Skip to content

Commit

Permalink
ADDON-70909: added condition to render custom row compoonent
Browse files Browse the repository at this point in the history
  • Loading branch information
rohanm-crest committed Jun 11, 2024
1 parent 21730b2 commit 08c3757
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 35 deletions.
162 changes: 128 additions & 34 deletions ui/src/components/table/CustomTableControl.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import DL from '@splunk/react-ui/DefinitionList';
import { _ } from '@splunk/ui-utils/i18n';

import ExclamationTriangle from '@splunk/react-icons/ExclamationTriangle';
import { getUnifiedConfigs } from '../../util/util';
import { getBuildDirPath } from '../../util/script';
// eslint-disable-next-line import/no-cycle
import { getExpansionRowData } from './TableExpansionRow';

function onCustomControlError(params) {
// eslint-disable-next-line no-console
Expand All @@ -17,23 +21,64 @@ class CustomTableControl extends Component {
super(props);
this.state = {
loading: true,
row: { ...props.row },
checkMethodIsPresent: false,
methodNotPresentError: '',
};
this.shouldRender = true;
}

componentDidMount() {
const globalConfig = getUnifiedConfigs();
this.setState({ loading: true });
this.loadCustomControl().then((Control) => {
this.customControl = new Control(
globalConfig,
this.props.serviceName,
this.el,
this.props.row,
this.props.field
this.loadCustomControl()
.then((Control) => {
if (typeof Control === 'function') {
this.customControl = new Control(
globalConfig,
this.props.serviceName,
this.el,
this.state.row,
this.props.field
);

this.callCustomMethod('getDLRows')
.then((result) => {
// check if getDLRow is exist in the custom input row file
if (result && typeof result === 'object' && !Array.isArray(result)) {
this.setState({
row: { ...result },
checkMethodIsPresent: true,
loading: false,
});
} else if (result !== null) {
// check if getDLRow return invalid object
this.setState({
loading: false,
methodNotPresentError:
'getDLRows method did not return a valid object',
});
} else {
// if getDLRow is not present then check render method is present or not
this.handleNoGetDLRows();
}
})
.catch((error) => {
onCustomControlError({ methodName: 'getDLRows', error });
this.handleNoGetDLRows();
});
} else {
this.setState({
loading: false,
methodNotPresentError: 'Loaded module is not a constructor function',
});
}
})
.catch(() =>
this.setState({
loading: false,
methodNotPresentError: 'Error loading custom control',
})
);
this.setState({ loading: false });
});
}

shouldComponentUpdate(nextProps, nextState) {
Expand All @@ -48,45 +93,93 @@ class CustomTableControl extends Component {
}

loadCustomControl = () =>
new Promise((resolve) => {
if (this.props.type === 'external') {
import(
/* webpackIgnore: true */ `${getBuildDirPath()}/custom/${
this.props.fileName
}.js`
).then((external) => {
const Control = external.default;
resolve(Control);
});
new Promise((resolve, reject) => {
const { type, fileName } = this.props;
const globalConfig = getUnifiedConfigs();

if (type === 'external') {
import(/* webpackIgnore: true */ `${getBuildDirPath()}/custom/${fileName}.js`)
.then((external) => resolve(external.default))
.catch((error) => reject(error));
} else {
const globalConfig = getUnifiedConfigs();
const appName = globalConfig.meta.name;
__non_webpack_require__(
[`app/${appName}/js/build/custom/${this.props.fileName}`],
(Control) => resolve(Control)
[`app/${appName}/js/build/custom/${fileName}`],
(Control) => resolve(Control),
(error) => reject(error)
);
}
});

callCustomMethod = async (methodName, ...args) => {
try {
if (typeof this.customControl[methodName] === 'function') {
return this.customControl[methodName](...args);
}
return null;
} catch (error) {
onCustomControlError({ methodName, error });
return null;
}
};

handleNoGetDLRows = () => {
if (!this.customControl || typeof this.customControl.render !== 'function') {
this.setState((prevState) => ({
...prevState,
methodNotPresentError:
'At least "render" either "getDLRows" method should be present.',
}));
}
this.setState((prevState) => ({
...prevState,
loading: false,
}));
};

render() {
if (!this.state.loading) {
const { row, loading, checkMethodIsPresent, methodNotPresentError } = this.state;
const { moreInfo } = this.props;

if (
!loading &&
!checkMethodIsPresent &&
this.customControl &&
typeof this.customControl.render === 'function'
) {
try {
this.customControl.render(this.props.row, this.props.field);
this.customControl.render(row, moreInfo);
} catch (error) {
onCustomControlError({ methodName: 'render', error });
}
}

let content;

if (methodNotPresentError) {
content = (
<span style={{ display: 'flex', alignItems: 'center' }}>
<ExclamationTriangle style={{ color: 'red', marginRight: '4px' }} />
{methodNotPresentError}
</span>
);
} else if (checkMethodIsPresent) {
content = <DL termWidth={250}>{getExpansionRowData(row, moreInfo)}</DL>;
} else {
content = (
<span
ref={(el) => {
this.el = el;
}}
style={{ visibility: loading ? 'hidden' : 'visible' }}
/>
);
}

return (
<>
{this.state.loading && _('Loading...')}
{
<span // nosemgrep: typescript.react.security.audit.react-no-refs.react-no-refs
ref={(el) => {
this.el = el;
}}
style={{ visibility: this.state.loading ? 'hidden' : 'visible' }}
/>
}
{loading && _('Loading...')}
{content}
</>
);
}
Expand All @@ -98,6 +191,7 @@ CustomTableControl.propTypes = {
field: PropTypes.string,
fileName: PropTypes.string.isRequired,
type: PropTypes.string,
moreInfo: PropTypes.array.isRequired,
};

export default CustomTableControl;
4 changes: 3 additions & 1 deletion ui/src/components/table/TableExpansionRow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import Table from '@splunk/react-ui/Table';
import styled from 'styled-components';
import { _ } from '@splunk/ui-utils/i18n';

// eslint-disable-next-line import/no-cycle
import CustomTableControl from './CustomTableControl';
import { getUnifiedConfigs } from '../../util/util';

const TableCellWrapper = styled(Table.Cell)`
border-top: none;
`;

function getExpansionRowData(row, moreInfo) {
export function getExpansionRowData(row, moreInfo) {
const DefinitionLists = [];

if (moreInfo?.length) {
Expand Down Expand Up @@ -50,6 +51,7 @@ export function getExpansionRow(colSpan, row, moreInfo) {
row,
fileName: customRow.src,
type: customRow.type,
moreInfo,
})}
</>
) : (
Expand Down

0 comments on commit 08c3757

Please sign in to comment.