-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
267 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
app/javascript/components/AeInlineMethod/NamespaceSelector.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import React, { useState, useEffect } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { | ||
TextInput, Select, SelectItem, Loading, | ||
} from 'carbon-components-react'; | ||
import MiqDataTable from '../miq-data-table'; | ||
import NotificationMessage from '../notification-message'; | ||
import './style.scss'; | ||
|
||
/** Component to search and select AeMethods. */ | ||
const NamespaceSelector = ({ onSelectMethod }) => { | ||
const aeMethodsUrl = '/miq_ae_class/ae_methods'; | ||
const aeDomainsUrl = '/miq_ae_class/ae_domains'; | ||
|
||
const [data, setData] = useState({ | ||
loading: true, | ||
domains: [], | ||
searchText: undefined, | ||
methods: [], | ||
selectedDomain: undefined, | ||
}); | ||
|
||
/** Function to format the method data needed for the data-table list. */ | ||
const formatMethods = (methods) => (methods.map((item) => ({ | ||
id: item.id.toString(), | ||
name: { text: item.name, icon: 'icon node-icon fa-ruby' }, | ||
path: item.relative_path, | ||
code: item.data, | ||
}))); | ||
|
||
/** Loads the 'domains' and 'methods' from its respective URL's during the component's onLoad event. */ | ||
useEffect(() => { | ||
Promise.all([ | ||
http.get(aeDomainsUrl), | ||
http.get(aeMethodsUrl)]) | ||
.then(([{ domains }, { methods }]) => { | ||
setData({ | ||
...data, | ||
loading: false, | ||
methods: formatMethods(methods), | ||
domains, | ||
}); | ||
}); | ||
}, []); | ||
|
||
/** Headers needed for the data-table list. */ | ||
const miqHeaders = [ | ||
{ | ||
key: 'name', | ||
header: 'Name', | ||
}, | ||
{ | ||
key: 'path', | ||
header: 'Relative path', | ||
}, | ||
]; | ||
|
||
/** Function to return a conditional URL based on the selected filters. */ | ||
const searchUrl = (selectedDomain, text) => { | ||
const queryParams = []; | ||
if (selectedDomain) { | ||
queryParams.push(`domain_id=${selectedDomain}`); | ||
} | ||
if (text) { | ||
queryParams.push(`search=${text}`); | ||
} | ||
const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : ''; | ||
return `${aeMethodsUrl}${queryString}`; | ||
}; | ||
|
||
/** Function to handle search text and drop-down item onchange events. */ | ||
const handleInputChange = (text, selectedDomain) => { | ||
const url = searchUrl(selectedDomain, text); | ||
http.get(url) | ||
.then(({ methods }) => { | ||
setData({ | ||
...data, | ||
methods: formatMethods(methods), | ||
searchText: text, | ||
selectedDomain, | ||
}); | ||
}); | ||
}; | ||
|
||
/** Function to render the search text. */ | ||
const renderSearchText = () => ( | ||
<TextInput | ||
id="search-method" | ||
labelText={__('Search')} | ||
placeholder={__('Search with Name or Relative path')} | ||
onChange={(event) => handleInputChange(event.target.value, data.selectedDomain)} | ||
/> | ||
); | ||
|
||
/** Function to render the domain items in a drop-down list. */ | ||
const renderDomainList = () => ( | ||
<Select | ||
id="select-3" | ||
labelText="Select an domain" | ||
defaultValue="option-3" | ||
onChange={(event) => handleInputChange(data.searchText, event.target.value)} | ||
> | ||
<SelectItem value="" text="None" /> | ||
{ | ||
data.domains.map((domain) => <SelectItem key={domain.id} value={domain.id} text={domain.name} />) | ||
} | ||
</Select> | ||
); | ||
|
||
/** Function to render the contents of the list. */ | ||
const renderContents = () => (data.methods && data.methods.length > 0 | ||
? ( | ||
<MiqDataTable | ||
headers={miqHeaders} | ||
rows={data.methods} | ||
mode="miq-inline-method-list" | ||
onCellClick={(selectedRow) => onSelectMethod(selectedRow)} | ||
/> | ||
) | ||
: <NotificationMessage type="error" message={__('No methods available.')} />); | ||
|
||
return ( | ||
<div className="inline-method-selector"> | ||
<div className="inline-filters"> | ||
{renderSearchText()} | ||
{data.domains && renderDomainList()} | ||
</div> | ||
<div className="inline-contents-wrapper"> | ||
{ | ||
data.loading | ||
? <Loading active small withOverlay={false} className="loading" /> | ||
: renderContents() | ||
} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default NamespaceSelector; | ||
|
||
NamespaceSelector.propTypes = { | ||
onSelectMethod: PropTypes.func.isRequired, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import React, { useState } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { Modal, Button, ModalBody } from 'carbon-components-react'; | ||
import NamespaceSelector from './NamespaceSelector'; | ||
|
||
/** Component to render a tree and to select an embedded method. */ | ||
const AeInlineMethod = ({ type }) => { | ||
const [data, setData] = useState({ | ||
isModalOpen: false, | ||
selectedNode: undefined, | ||
list: [], | ||
}); | ||
|
||
/** Function to show/hide the modal. */ | ||
const showModal = (status) => { | ||
setData({ | ||
...data, | ||
isModalOpen: status, | ||
}); | ||
}; | ||
|
||
/** Function to render the Add method button. */ | ||
const renderAddButton = () => ( | ||
<Button | ||
id="add-method" | ||
kind="primary" | ||
title={__('Add Method')} | ||
onClick={() => showModal(true)} | ||
size="sm" | ||
> | ||
{__('Add method')} | ||
</Button> | ||
); | ||
|
||
return ( | ||
<div> | ||
{renderAddButton()} | ||
<Modal | ||
primaryButtonDisabled={data.list.size > 0} | ||
size="lg" | ||
modalHeading={__('Select item')} | ||
open={data.isModalOpen} | ||
primaryButtonText={__('OK')} | ||
secondaryButtonText={__('Cancel')} | ||
onRequestClose={() => showModal(false)} | ||
onRequestSubmit={() => { | ||
console.log('on onRequestSubmit', data.list); | ||
showModal(false); | ||
}} | ||
onSecondarySubmit={() => { | ||
console.log('on onSecondarySubmit'); | ||
showModal(false); | ||
}} | ||
> | ||
<ModalBody> | ||
{ | ||
data.isModalOpen | ||
&& ( | ||
<NamespaceSelector | ||
onSelectMethod={(method) => { | ||
data.list.push(method); | ||
setData({ | ||
...data, | ||
list: [...data.list], | ||
}); | ||
}} | ||
/> | ||
) | ||
} | ||
</ModalBody> | ||
</Modal> | ||
|
||
</div> | ||
); | ||
}; | ||
|
||
export default AeInlineMethod; | ||
|
||
AeInlineMethod.propTypes = { | ||
type: PropTypes.string.isRequired, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
.inline-method-selector { | ||
display: flex; | ||
flex-direction: column; | ||
|
||
.inline-filters { | ||
display: flex; | ||
flex-direction: row; | ||
gap: 10px; | ||
} | ||
|
||
.inline-contents-wrapper { | ||
display: flex; | ||
flex-direction: column; | ||
margin-top: 20px; | ||
|
||
.miq-inline-method-list { | ||
background: #FFF; | ||
margin-top: 0; | ||
} | ||
|
||
.miq-notification-message-container { | ||
margin: 0; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1906,6 +1906,8 @@ | |
explorer | ||
method_form_fields | ||
namespace | ||
ae_domains | ||
ae_methods | ||
show | ||
], | ||
:post => %w[ | ||
|