Skip to content
This repository has been archived by the owner on Oct 5, 2023. It is now read-only.

feat(CODE): ADDON-58505 Added support of style to page in the global config file #201

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 79 additions & 29 deletions src/main/webapp/components/ConfigurationTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,103 @@ import PropTypes from 'prop-types';
import { TableContextProvider } from '../context/TableContext';
import TableWrapper from './table/TableWrapper';
import EntityModal from './EntityModal';
import { MODE_CREATE } from '../constants/modes';
import EntityPage from './EntityPage';
import { MODE_CREATE, MODE_CLONE } from '../constants/modes';
import { PAGE_CONF } from '../constants/pages';
import { STYLE_PAGE } from '../constants/dialogStyles';

function ConfigurationTable({ serviceName, serviceTitle }) {
const [open, setOpen] = useState(false);
const serviceLabel = `Add ${serviceTitle}`;
function ConfigurationTable({ selectedTab, updateIsPageOpen }) {

const [entity, setEntity] = useState({ open: false });

const isConfigurationPageStyle = selectedTab.style === STYLE_PAGE;

const handleRequestOpen = () => {
setOpen(true);
setEntity({
...entity,
open: true,
mode: MODE_CREATE,
formLabel: `Add ${selectedTab.title}`,
});
};

const handleRequestClose = () => {
setOpen(false);
// handle close request for modal style dialog
const handleModalDialogClose = () => {
setEntity({ ...entity, open: false });
};

// generate modal style dialog
const generateModalDialog = () => {
if (open) {
return (
<EntityModal
page={PAGE_CONF}
open={open}
handleRequestClose={handleRequestClose}
handleSaveData={() => {}}
serviceName={serviceName}
mode={MODE_CREATE}
formLabel={serviceLabel}
/>
);
}
return null;
return (
<EntityModal
page={PAGE_CONF}
open={entity.open}
handleRequestClose={handleModalDialogClose}
serviceName={selectedTab.name}
mode={MODE_CREATE}
formLabel={entity.formLabel}
/>
);
};

// handle clone/edit request per row from table for page style dialog
const handleOpenPageStyleDialog = (row, mode) => {
setEntity({
...entity,
open: true,
stanzaName: row.name,
formLabel: mode === MODE_CLONE ? `Clone ${selectedTab.title}` : `Update ${selectedTab.title}`,
mode,
});
};

// handle close request for page style dialog
const handlePageDialogClose = () => {
setEntity({ ...entity, open: false });
updateIsPageOpen(false);
};

// generate page style dialog
const generatePageDialog = () => {
updateIsPageOpen(true);
return (
<EntityPage
open={entity.open}
handleRequestClose={handlePageDialogClose}
serviceName={selectedTab.name}
stanzaName={entity.stanzaName}
mode={entity.mode}
formLabel={entity.formLabel}
page={PAGE_CONF}
/>
);
};

const getTableWrapper = () => {
return (
<TableWrapper
page={PAGE_CONF}
serviceName={selectedTab.name}
handleRequestModalOpen={() => handleRequestOpen()}
handleOpenPageStyleDialog={handleOpenPageStyleDialog}
/>
);
};

return (
<>
<TableContextProvider value={null}>
<TableWrapper
page={PAGE_CONF}
serviceName={serviceName}
handleRequestModalOpen={() => handleRequestOpen()}
/>
{generateModalDialog()}
{isConfigurationPageStyle && entity.open ? generatePageDialog() : null}
{!(isConfigurationPageStyle && entity.open) ? getTableWrapper() : null}
{!isConfigurationPageStyle && entity.open ? generateModalDialog() : null}
</TableContextProvider>
</>
);
}

ConfigurationTable.propTypes = {
serviceName: PropTypes.string.isRequired,
serviceTitle: PropTypes.string.isRequired,
selectedTab: PropTypes.object,
updateIsPageOpen: PropTypes.func
};

export default memo(ConfigurationTable);
11 changes: 7 additions & 4 deletions src/main/webapp/components/EntityPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import { _ } from '@splunk/ui-utils/i18n';
import { useSplunkTheme } from '@splunk/themes';

import { MODE_CLONE, MODE_CREATE, MODE_EDIT } from '../constants/modes';
import { PAGE_INPUT } from '../constants/pages';
import BaseFormView from './BaseFormView';
import { SubTitleComponent } from '../pages/Input/InputPageStyle';
import { PAGE_INPUT } from '../constants/pages';

function EntityPage({ handleRequestClose, serviceName, mode, stanzaName, formLabel }) {
function EntityPage({ handleRequestClose, serviceName, mode, stanzaName, formLabel, page }) {
// Ref is used here to call submit method of form only
const form = useRef(); // nosemgrep: typescript.react.security.audit.react-no-refs.react-no-refs
const [isSubmitting, setIsSubmitting] = useState(false);
Expand Down Expand Up @@ -52,7 +52,7 @@ function EntityPage({ handleRequestClose, serviceName, mode, stanzaName, formLab
<ColumnLayout.Row style={{ padding: '5px 0px' }}>
<ColumnLayout.Column>
<SubTitleComponent>
<Link onClick={handleRequestClose}>{_('Inputs')}</Link>
<Link onClick={handleRequestClose}>{page === PAGE_INPUT ? _('Inputs') : _('Configuration')}</Link>
{' > '}
{_(formLabel)}
</SubTitleComponent>
Expand All @@ -63,7 +63,7 @@ function EntityPage({ handleRequestClose, serviceName, mode, stanzaName, formLab
<ColumnLayout.Column span={8} style={colStyle}>
<BaseFormView // nosemgrep: typescript.react.security.audit.react-no-refs.react-no-refs
ref={form}
page={PAGE_INPUT}
page={page}
serviceName={serviceName}
mode={mode}
stanzaName={stanzaName}
Expand All @@ -80,12 +80,14 @@ function EntityPage({ handleRequestClose, serviceName, mode, stanzaName, formLab
onClick={handleRequestClose}
label={_('Cancel')}
disabled={isSubmitting}
style={{"width": "80px"}}
/>
<Button
appearance="primary"
label={isSubmitting ? <WaitSpinner /> : buttonText}
onClick={handleSubmit}
disabled={isSubmitting}
style={{"width": "80px"}}
/>
</ColumnLayout.Column>
<ColumnLayout.Column span={2} />
Expand All @@ -100,6 +102,7 @@ EntityPage.propTypes = {
mode: PropTypes.string,
stanzaName: PropTypes.string,
formLabel: PropTypes.string,
page: PropTypes.string,
};

export default memo(EntityPage);
8 changes: 6 additions & 2 deletions src/main/webapp/components/table/CustomTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ function CustomTable({
unifiedConfigs.pages.inputs.services.forEach((x) => {
serviceToStyleMap[x.name] = x.style === STYLE_PAGE ? STYLE_PAGE : STYLE_MODAL;
});
} else {
unifiedConfigs.pages.configuration.tabs.forEach((x) => {
serviceToStyleMap[x.name] = x.style === STYLE_PAGE ? STYLE_PAGE : STYLE_MODAL;
});
}

const query = useQuery();
Expand Down Expand Up @@ -86,7 +90,7 @@ function CustomTable({

const handleEditActionClick = useCallback(
(selectedRow) => {
if (serviceToStyleMap[selectedRow.serviceName] === 'page') {
if (serviceToStyleMap[selectedRow.serviceName] === STYLE_PAGE) {
handleOpenPageStyleDialog(selectedRow, MODE_EDIT);
} else {
setEntityModal({
Expand All @@ -108,7 +112,7 @@ function CustomTable({

const handleCloneActionClick = useCallback(
(selectedRow) => {
if (serviceToStyleMap[selectedRow.serviceName] === 'page') {
if (serviceToStyleMap[selectedRow.serviceName] === STYLE_PAGE) {
handleOpenPageStyleDialog(selectedRow, MODE_CLONE);
} else {
setEntityModal({
Expand Down
38 changes: 23 additions & 15 deletions src/main/webapp/pages/Configuration/ConfigurationPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function ConfigurationPage() {
});

const [activeTabId, setActiveTabId] = useState(tabs[0].name);
const [isPageOpen, setIsPageOpen] = useState(false);

const query = useQuery();

Expand All @@ -55,26 +56,33 @@ function ConfigurationPage() {
const handleChange = useCallback(
(e, { selectedTabId }) => {
setActiveTabId(selectedTabId);
setIsPageOpen(false);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[activeTabId]
);

const updateIsPageOpen = (data) => {
setIsPageOpen(data);
};

return (
<ErrorBoundary>
<ColumnLayout gutter={8}>
<Row>
<ColumnLayout.Column span={9}>
<TitleComponent>{_(title)}</TitleComponent>
<SubTitleComponent>{_(description || '')}</SubTitleComponent>
</ColumnLayout.Column>
</Row>
</ColumnLayout>
<TabBar activeTabId={activeTabId} onChange={handleChange}>
{tabs.map((tab) => (
<TabBar.Tab key={tab.name} label={_(tab.title)} tabId={tab.name} />
))}
</TabBar>
<div style={isPageOpen ? { display: 'none' } : { display: 'block' }}>
<ColumnLayout gutter={8}>
<Row>
<ColumnLayout.Column span={9}>
<TitleComponent>{_(title)}</TitleComponent>
<SubTitleComponent>{_(description || '')}</SubTitleComponent>
</ColumnLayout.Column>
</Row>
</ColumnLayout>
<TabBar activeTabId={activeTabId} onChange={handleChange}>
{tabs.map((tab) => (
<TabBar.Tab key={tab.name} label={_(tab.title)} tabId={tab.name} />
))}
</TabBar>
</div>
{tabs.map((tab) => {
return tab.table ? (
<div
Expand All @@ -86,8 +94,8 @@ function ConfigurationPage() {
>
<ConfigurationTable
key={tab.name}
serviceName={tab.name}
serviceTitle={tab.title}
selectedTab={tab}
updateIsPageOpen={updateIsPageOpen}
/>
</div>
) : (
Expand Down
3 changes: 2 additions & 1 deletion src/main/webapp/pages/Input/InputPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function InputPage() {
return service.name;
});

let navigate = useNavigate();
const navigate = useNavigate();
const query = useQuery();

useEffect(() => {
Expand Down Expand Up @@ -187,6 +187,7 @@ function InputPage() {
stanzaName={entity.stanzaName}
mode={entity.mode}
formLabel={entity.formLabel}
page={PAGE_INPUT}
/>
);
};
Expand Down
4 changes: 4 additions & 0 deletions src/main/webapp/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,10 @@
"table": {
"$ref": "#/definitions/ConfigurationTable"
},
"style": {
"type": "string",
"enum": ["page", "dialog"]
},
"conf": {
"type": "string",
"maxLength": 100
Expand Down