Skip to content

Commit

Permalink
refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffibm committed Feb 28, 2024
1 parent bcdb82c commit b0a7cdf
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 73 deletions.
154 changes: 88 additions & 66 deletions app/javascript/components/AeInlineMethod/NamespaceSelector.jsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,49 @@
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' },
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)])
// 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',
Expand All @@ -48,74 +55,89 @@ const NamespaceSelector = () => {
},
];

return (
<div>
<TextInput
id="search-method"
labelText={__('Search')}
placeholder={__('Search with Name or Relative path')}
onChange={(event) => {
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 && (
<Select
id="select-3"
labelText="Select an domain"
defaultValue="option-3"
onChange={(event) => {
const selectedDomain = event.target.value;
let url = `${aeMethodsUrl}?domain_id=${selectedDomain}`;
if (data.searchText) {
url = `${url}&search=${data.searchText}`;
}
http.get(url)
.then(({ methods }) => {
setData({
...data,
methods: formatMethods(methods),
selectedDomain,
});
});
}}
>
{
data.domains.map((domain) => (
<SelectItem key={domain.id} value={domain.id} text={domain.name} />
))
}
</Select>
)
}
/** 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.methods && data.methods.length > 0 && (
<MiqDataTable
headers={miqHeaders}
rows={data.methods}
mode="list"
/>
)
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 = {
// type: PropTypes.string.isRequired,
// };
NamespaceSelector.propTypes = {
onSelectMethod: PropTypes.func.isRequired,
};
18 changes: 11 additions & 7 deletions app/javascript/components/AeInlineMethod/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,15 @@ const AeInlineMethod = ({ type }) => {
<div>
{renderAddButton()}
<Modal
primaryButtonDisabled={data.selectedNode === undefined}
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');
setData({
...data,
list: data.list.push(data.selectedNode),
});
console.log('on onRequestSubmit', data.list);
showModal(false);
}}
onSecondarySubmit={() => {
Expand All @@ -60,7 +56,15 @@ const AeInlineMethod = ({ type }) => {
{
data.isModalOpen
&& (
<NamespaceSelector />
<NamespaceSelector
onSelectMethod={(method) => {
data.list.push(method);
setData({
...data,
list: [...data.list],
});
}}
/>
)
}
</ModalBody>
Expand Down
25 changes: 25 additions & 0 deletions app/javascript/components/AeInlineMethod/style.scss
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;
}
}
}

0 comments on commit b0a7cdf

Please sign in to comment.