Skip to content

Commit

Permalink
Merge pull request #149 from mercedes-benz/develop
Browse files Browse the repository at this point in the history
VULCAN-947/Checkbox disable feature production deployment
  • Loading branch information
m-o-n-i-s-h authored Nov 21, 2024
2 parents c9e2899 + f20b60f commit ed625d0
Show file tree
Hide file tree
Showing 5 changed files with 316 additions and 37 deletions.
1 change: 1 addition & 0 deletions src/card/settings/CardSettingsFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ const NeoCardSettingsFooter = ({
settingValue={reportSettings[actionsToCustomize]}
type={type}
fields={fields}
preConditionsSetting={reportSettings?.preConditions}
customReportActionsModalOpen={customReportActionsModalOpen}
setCustomReportActionsModalOpen={setCustomReportActionsModalOpen}
onReportSettingUpdate={onReportSettingUpdate}
Expand Down
49 changes: 49 additions & 0 deletions src/chart/table/TableActionsHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,55 @@ export const hasCheckboxes = (actionsRules) => {
return rules.length > 0;
};

export const hasPreCondition = (preConditions) => {
return preConditions.length > 0;
};

const groupConditionsByField = (conditions) => {
return conditions.reduce((acc, condition) => {
if (!acc[condition.field]) {
acc[condition.field] = [];
}
acc[condition.field].push(condition);
return acc;
}, {});
};

const evaluateGroupedConditions = (groupedConditions, row) => {
return Object.keys(groupedConditions).every((field) => {
// Logical OR between conditions for the same field
return groupedConditions[field].some((condition) => evaluateCondition(condition, row));
});
};

export const convertConditionsToExpression = (conditions, row) => {
const groupedConditions = groupConditionsByField(conditions);
return !evaluateGroupedConditions(groupedConditions, row);
};

const evaluateCondition = (condition, row) => {
let fieldValue = row[condition.field];

// Handle Neo4j integer format
if (fieldValue && typeof fieldValue === 'object' && 'low' in fieldValue && 'high' in fieldValue) {
// Assuming we only care about the 'low' value for comparisons
fieldValue = String(fieldValue.low);
}

switch (condition.condition) {
case '=':
return fieldValue === condition.value;
case '!=':
return fieldValue !== condition.value;
case 'contains':
return typeof fieldValue === 'string' && fieldValue.includes(condition.value);
case 'not_contains':
return typeof fieldValue === 'string' && !fieldValue.includes(condition.value);
default:
return false;
}
};

export const getCheckboxes = (actionsRules, rows, getGlobalParameter) => {
let rules = actionsRules.filter((rule) => rule.condition && rule.condition == 'rowCheck');
const params = rules.map((rule) => `neodash_${rule.customizationValue}`);
Expand Down
124 changes: 88 additions & 36 deletions src/chart/table/TableChart.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
import { DataGrid, GridColumnVisibilityModel } from '@mui/x-data-grid';
import { DataGrid, GridColumnVisibilityModel, GridRowId } from '@mui/x-data-grid';
import { ChartProps } from '../Chart';
import {
evaluateRulesOnDict,
Expand All @@ -17,14 +17,21 @@ import {
performActionOnElement,
} from '../../extensions/advancedcharts/Utils';
import { IconButton } from '@neo4j-ndl/react';
import { CloudArrowDownIconOutline, XMarkIconOutline } from '@neo4j-ndl/react/icons';
import { CloudArrowDownIconOutline, ArrowPathIconOutline, XMarkIconOutline } from '@neo4j-ndl/react/icons';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import Button from '@mui/material/Button';
import { extensionEnabled } from '../../utils/ReportUtils';
import { renderCellExpand } from '../../component/misc/DataGridExpandRenderer';
import { getCheckboxes, hasCheckboxes, updateCheckBoxes } from './TableActionsHelper';
import {
convertConditionsToExpression,
getCheckboxes,
hasCheckboxes,
hasPreCondition,
updateCheckBoxes,
} from './TableActionsHelper';
import ApiService from '../../utils/apiService';
import { AxiosResponse } from 'axios';
import Notification from '../../component/custom/Notification';

const TABLE_HEADER_HEIGHT = 32;
const TABLE_FOOTER_HEIGHT = 62;
Expand Down Expand Up @@ -96,6 +103,10 @@ export const NeoTableChart = (props: ChartProps) => {
extensionEnabled(props.extensions, 'actions') && props.settings && props.settings.actionsRules
? props.settings.actionsRules
: [];
const preConditions =
extensionEnabled(props.extensions, 'actions') && props.settings && props.settings.preConditions
? props.settings.preConditions
: [];
const compact = props.settings && props.settings.compact !== undefined ? props.settings.compact : false;
const styleRules = useStyleRules(
extensionEnabled(props.extensions, 'styling'),
Expand Down Expand Up @@ -129,6 +140,7 @@ export const NeoTableChart = (props: ChartProps) => {
}

const { records } = props;
const isApiSpecEnabled = props.settings?.apiSpec && props.settings?.apiSpec.apiEnabled;

const generateSafeColumnKey = (key) => {
return key != 'id' ? key : `${key} `;
Expand All @@ -142,6 +154,13 @@ export const NeoTableChart = (props: ChartProps) => {
setAnchorEl(null);
};

const [alertOpen, setAlertOpen] = React.useState(false);
const [notificationMessage, setNotificationMessage] = React.useState('');
const [notificationSeverity, setNotificationSeverity] = React.useState<'success' | 'warning' | 'error'>('success');

const handleNotificationClose = () => {
setAlertOpen(false);
};
const lineBreakColumns: string[] = props.settings?.lineBreaksAfterListEntry;

const actionableFields = actionsRules.filter((r) => r.condition !== 'rowCheck').map((r) => r.field);
Expand Down Expand Up @@ -333,60 +352,92 @@ export const NeoTableChart = (props: ChartProps) => {
throw new Error(`Unsupported method: ${method}`);
}

props.updateReportSetting('apiSpec', { ...props.settings.apiSpec, response });
props.updateReportSetting('apiSpec', { ...props.settings?.apiSpec, response });
setNotificationMessage('RUPS package created. Please find the link above');
setNotificationSeverity('success');
setAlertOpen(true);
} catch (error) {
// Handle errors here
console.error('API call error:', error);
setNotificationMessage('RUPS package creation is currently not working. Please try again later.');
setNotificationSeverity('error');
setAlertOpen(true);
} finally {
setApiLoading(false);
}
};

const handleResetApiResponse = () => {
props.updateReportSetting('apiSpec', { ...props.settings?.apiSpec, response: null });
};

useEffect(() => {
if (isApiSpecEnabled) {
handleResetApiResponse();
}
}, [records]);

const apiCallButton = () => (
<Stack direction='row' spacing={2} justifyContent='flex-end' marginRight={2}>
<ButtonGroup color='primary' variant='outlined' aria-label='button group'>
<Button size='small' onClick={handleApiCall} disabled={isApiLoading}>
{isApiLoading ? 'Loading...' : props.settings?.sendRequestButtonName || 'send'}
</Button>
<Button size='small' onClick={handlePopHoverClick} disabled={!props.settings.apiSpec.response}>
<Button variant='outlined' size='small' onClick={handleApiCall} disabled={isApiLoading}>
{isApiLoading ? 'Loading...' : props.settings?.sendRequestButtonName || 'send'}
</Button>
{props.settings?.apiSpec.response && (
<Button
size='small'
variant='outlined'
onClick={handlePopHoverClick}
disabled={!props.settings?.apiSpec.response}
>
{isApiLoading ? 'Loading...' : props.settings?.viewResponseButtonName || 'view response'}
</Button>
{props.settings.apiSpec.response ? (
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handlePopHoverClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
<Typography sx={{ p: 2 }}>
<a href={props.settings?.apiSpec.response.data} target='_blank'>
{props.settings?.apiSpec.response.data}
</a>
</Typography>
</Popover>
) : (
<></>
)}
</ButtonGroup>
)}
{props.settings?.apiSpec.response ? (
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handlePopHoverClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
<Typography sx={{ p: 2 }}>
<a href={props.settings?.apiSpec.response.data} target='_blank'>
{props.settings?.apiSpec.response.data}
</a>
</Typography>
</Popover>
) : (
<></>
)}
</Stack>
);

const isApiSpecEnabled = props.settings?.apiSpec && props.settings?.apiSpec.apiEnabled;

const tableStyle: any = isApiSpecEnabled
? { marginTop: 10, height: '90%', width: '100%', position: 'relative' }
: { height: '100%', width: '100%', position: 'relative' };

const isRowSelectable = (params: { id: GridRowId; row: any }) => {
if (hasPreCondition(preConditions)) {
return convertConditionsToExpression(preConditions, params.row);
}
return true;
};

return (
<ThemeProvider theme={theme}>
<Notification
open={alertOpen}
message={notificationMessage}
severity={notificationSeverity}
onClose={handleNotificationClose}
/>
{isApiSpecEnabled ? apiCallButton() : <></>}
<div className={classes.root} style={tableStyle}>
<Snackbar
Expand Down Expand Up @@ -455,6 +506,7 @@ export const NeoTableChart = (props: ChartProps) => {
onSelectionModelChange={(selection) =>
updateCheckBoxes(actionsRules, rows, selection, props.setGlobalParameter)
}
isRowSelectable={isRowSelectable}
autoPageSize
pagination
disableSelectionOnClick
Expand Down
26 changes: 26 additions & 0 deletions src/component/custom/Notification.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import Snackbar from '@mui/material/Snackbar';
import MuiAlert, { AlertProps } from '@mui/material/Alert';

interface NotificationProps {
open: boolean;
message: string;
severity: 'success' | 'warning' | 'error';
onClose: () => void;
}

const Alert = React.forwardRef<HTMLDivElement, AlertProps>((props, ref) => {
return <MuiAlert elevation={6} ref={ref} variant='filled' {...props} />;
});

const Notification: React.FC<NotificationProps> = ({ open, message, severity, onClose }) => {
return (
<Snackbar open={open} autoHideDuration={6000} onClose={onClose}>
<Alert onClose={onClose} severity={severity}>
{message}
</Alert>
</Snackbar>
);
};

export default Notification;
Loading

0 comments on commit ed625d0

Please sign in to comment.