diff --git a/app/javascript/components/AeInlineMethod/NamespaceSelector.jsx b/app/javascript/components/AeInlineMethod/NamespaceSelector.jsx
index 1e47c7f7001..f58f3ffc560 100644
--- a/app/javascript/components/AeInlineMethod/NamespaceSelector.jsx
+++ b/app/javascript/components/AeInlineMethod/NamespaceSelector.jsx
@@ -1,20 +1,26 @@
import React, { useState, useEffect } from 'react';
+import PropTypes from 'prop-types';
import {
- TextInput, Select, SelectItem,
+ TextInput, Select, SelectItem, Loading,
} from 'carbon-components-react';
import MiqDataTable from '../miq-data-table';
+import NotificationMessage from '../notification-message';
+import './style.scss';
-const NamespaceSelector = () => {
+/** 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' },
@@ -22,21 +28,22 @@ const NamespaceSelector = () => {
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)])
- // eslint-disable-next-line camelcase
.then(([{ domains }, { methods }]) => {
setData({
...data,
+ loading: false,
methods: formatMethods(methods),
domains,
});
});
}, []);
- console.log(data);
+ /** Headers needed for the data-table list. */
const miqHeaders = [
{
key: 'name',
@@ -48,74 +55,89 @@ const NamespaceSelector = () => {
},
];
- return (
-
-
{
- const text = event.target.value;
- let url = `${aeMethodsUrl}?search=${text}`;
- if (data.selectedDomain) {
- url = `${url}&domain_id=${data.selectedDomain}`;
- }
- http.get(url)
- .then(({ methods }) => {
- setData({
- ...data,
- methods: formatMethods(methods),
- searchText: text,
- });
- });
- }}
- />
- {
- data.domains && (
-
- )
- }
+ /** 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 = () => (
+ handleInputChange(event.target.value, data.selectedDomain)}
+ />
+ );
+ /** Function to render the domain items in a drop-down list. */
+ const renderDomainList = () => (
+
+ );
+
+ /** Function to render the contents of the list. */
+ const renderContents = () => (data.methods && data.methods.length > 0
+ ? (
+ onSelectMethod(selectedRow)}
+ />
+ )
+ : );
+
+ return (
+
+
+ {renderSearchText()}
+ {data.domains && renderDomainList()}
+
+
+ {
+ data.loading
+ ?
+ : renderContents()
+ }
+
);
};
export default NamespaceSelector;
-// NamespaceSelector.propTypes = {
-// type: PropTypes.string.isRequired,
-// };
+NamespaceSelector.propTypes = {
+ onSelectMethod: PropTypes.func.isRequired,
+};
diff --git a/app/javascript/components/AeInlineMethod/index.jsx b/app/javascript/components/AeInlineMethod/index.jsx
index f1cd9b9d09a..0ef4ad55c86 100644
--- a/app/javascript/components/AeInlineMethod/index.jsx
+++ b/app/javascript/components/AeInlineMethod/index.jsx
@@ -36,7 +36,7 @@ const AeInlineMethod = ({ type }) => {
{renderAddButton()}
0}
size="lg"
modalHeading={__('Select item')}
open={data.isModalOpen}
@@ -44,11 +44,7 @@ const AeInlineMethod = ({ type }) => {
secondaryButtonText={__('Cancel')}
onRequestClose={() => showModal(false)}
onRequestSubmit={() => {
- console.log('on onRequestSubmit');
- setData({
- ...data,
- list: data.list.push(data.selectedNode),
- });
+ console.log('on onRequestSubmit', data.list);
showModal(false);
}}
onSecondarySubmit={() => {
@@ -60,7 +56,15 @@ const AeInlineMethod = ({ type }) => {
{
data.isModalOpen
&& (
-
+ {
+ data.list.push(method);
+ setData({
+ ...data,
+ list: [...data.list],
+ });
+ }}
+ />
)
}
diff --git a/app/javascript/components/AeInlineMethod/style.scss b/app/javascript/components/AeInlineMethod/style.scss
new file mode 100644
index 00000000000..0e63cf75c3d
--- /dev/null
+++ b/app/javascript/components/AeInlineMethod/style.scss
@@ -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;
+ }
+ }
+}