From ae66fc944364ed23a1859ee067f991e18400aee7 Mon Sep 17 00:00:00 2001 From: Abdelsalem Date: Wed, 18 Sep 2024 16:02:03 +0200 Subject: [PATCH] use reducer Signed-off-by: Abdelsalem --- src/components/report-viewer/log-table.jsx | 31 ++++- .../report-viewer/report-viewer.jsx | 111 +++++++----------- src/redux/actions.ts | 19 +++ src/redux/reducer.ts | 22 ++++ 4 files changed, 113 insertions(+), 70 deletions(-) diff --git a/src/components/report-viewer/log-table.jsx b/src/components/report-viewer/log-table.jsx index 748fb8a399..82ea75f3a7 100644 --- a/src/components/report-viewer/log-table.jsx +++ b/src/components/report-viewer/log-table.jsx @@ -12,6 +12,9 @@ import { MuiVirtualizedTable } from '@gridsuite/commons-ui'; import { useTheme } from '@mui/material/styles'; import { FilterButton } from './filter-button'; import { TextFilterButton } from './text-filter-button.jsx'; +import { useDispatch, useSelector } from 'react-redux'; +import { useDebounce } from 'use-debounce'; +import { setReportFilters } from '../../redux/actions'; // WARNING this file has been copied from commons-ui, and updated here. Putting it back to commons-ui has to be discussed. @@ -36,13 +39,37 @@ const styles = { const VirtualizedTable = styled(MuiVirtualizedTable)(styles); -const LogTable = ({ logs, onRowClick, selectedSeverity, setSelectedSeverity, messageFilter, setMessageFilter }) => { +const LogTable = ({ logs, onRowClick }) => { const intl = useIntl(); const theme = useTheme(); + const dispatch = useDispatch(); + const [selectedRowIndex, setSelectedRowIndex] = useState(-1); + const severityFilter = useSelector((state) => state.reportSeverityFilter); + + const selectedReportId = useSelector((state) => state.reportSelectedReportId); + + //messageFilter is only used for display, debouncedMessageFilter is used for triggering fetch + const [messageFilter, setMessageFilter] = useState(''); + + const [debouncedMessageFilter] = useDebounce(messageFilter, 500); + + useEffect(() => { + dispatch(setReportFilters(undefined, debouncedMessageFilter, undefined)); + }, [debouncedMessageFilter, dispatch]); + + //We reset the displayed message filter when we switch reports + useEffect(() => { + setMessageFilter(''); + }, [selectedReportId]); + + const setSeverityFilter = (selectedSeverity) => { + dispatch(setReportFilters(undefined, undefined, selectedSeverity)); + }; + const severityCellRender = (cellData) => { return ( , + extra: , }, { label: intl.formatMessage({ id: 'report_viewer/message' }).toUpperCase(), diff --git a/src/components/report-viewer/report-viewer.jsx b/src/components/report-viewer/report-viewer.jsx index 94342d8b47..769b65d022 100644 --- a/src/components/report-viewer/report-viewer.jsx +++ b/src/components/report-viewer/report-viewer.jsx @@ -15,7 +15,8 @@ import { getDefaultSeverityFilter } from '../../utils/report-severity.utils'; import { useReportFetcher } from '../../hooks/use-report-fetcher'; import { mapReportLog, mapReportLogs } from '../../utils/report-log.mapper'; import { mapReportsTree } from '../../utils/report-tree.mapper'; -// import { useDebounce } from 'use-debounce'; +import { useDispatch, useSelector } from 'react-redux'; +import { setReportFilters } from '../../redux/actions'; // WARNING this file has been copied from commons-ui, and updated here. Putting it back to commons-ui has to be discussed. @@ -26,20 +27,17 @@ const styles = { }; export default function ReportViewer({ report, reportType }) { + const dispatch = useDispatch(); + const [expandedTreeReports, setExpandedTreeReports] = useState([]); const [logs, setLogs] = useState(null); const [highlightedReportId, setHighlightedReportId] = useState(); const [reportVerticalPositionFromTop, setReportVerticalPositionFromTop] = useState(undefined); const [isLogLoading, , fetchReportLogs] = useReportFetcher(reportType); - // const [selectedReportId, setSelectedReportId] = useState(null); - // const [severityFilter, setSeverityFilter] = useState(getDefaultSeverityFilter()); - // const [messageFilter, setMessageFilter] = useState(''); - // const [filterLogsTextDebounced] = useDebounce(messageFilter, 500); - - const selectedReportId = useRef(); - const severityFilter = useRef([]); - const messageFilter = useRef(''); + const selectedReportId = useSelector((state) => state.reportSelectedReportId); + const severityFilter = useSelector((state) => state.reportSeverityFilter); + const messageFilter = useSelector((state) => state.reportMessageFilter); const reportTreeData = useRef({}); const treeView = useRef(null); @@ -63,45 +61,46 @@ export default function ReportViewer({ report, reportType }) { ); }, []); - const refreshLogsOnSelectedReport = useCallback(() => { - let severityList = []; - for (const [severity, selected] of Object.entries(severityFilter.current)) { - if (selected) { - severityList.push(severity); + const refreshLogsOnSelectedReport = useCallback( + (selectedReportId, severityFilter, messageFilter) => { + let severityList = []; + for (const [severity, selected] of Object.entries(severityFilter)) { + if (selected) { + severityList.push(severity); + } + } + if (severityList.length === 0) { + setLogs([]); + setHighlightedReportId(null); + return; } - } - if (severityList.length === 0) { - setLogs([]); - setHighlightedReportId(null); - return; - } + fetchReportLogs( + selectedReportId, + severityList, + reportTreeData.current[selectedReportId].type, + messageFilter + ).then((reportLogs) => { + setLogs(mapReportLogs(reportLogs)); + }); + }, + [fetchReportLogs] + ); - fetchReportLogs( - selectedReportId.current, - severityList, - reportTreeData.current[selectedReportId.current].type, - messageFilter.current - ).then((reportLogs) => { - setLogs(mapReportLogs(reportLogs)); - }); - }, [fetchReportLogs]); + useEffect(() => { + //refresh the logs when we change the filters + if (selectedReportId != null) { + refreshLogsOnSelectedReport(selectedReportId, severityFilter, messageFilter); + } + }, [messageFilter, severityFilter, selectedReportId, refreshLogsOnSelectedReport]); useEffect(() => { const reportTree = mapReportsTree(report); treeView.current = initializeTreeDataAndComponent(reportTree); - selectedReportId.current = report.id; setExpandedTreeReports([report.id]); setLogs(mapReportLog(report, reportTree.severities)); - severityFilter.current = getDefaultSeverityFilter(reportTree.severities); - }, [report, initializeTreeDataAndComponent]); - - // //to reload the logs with the updated message filter without spamming the back - // useEffect(() => { - // if (selectedReportId != null) { - // refreshLogsOnSelectedReport(selectedReportId, severityFilter, filterLogsTextDebounced); - // } - // }, [refreshLogsOnSelectedReport, filterLogsTextDebounced, selectedReportId, severityFilter]); + dispatch(setReportFilters(report.id, '', getDefaultSeverityFilter(reportTree.severities))); + }, [report, initializeTreeDataAndComponent, dispatch]); const handleReportVerticalPositionFromTop = useCallback((node) => { setReportVerticalPositionFromTop(node?.getBoundingClientRect()?.top); @@ -109,29 +108,12 @@ export default function ReportViewer({ report, reportType }) { const handleSelectNode = (_, reportId) => { if (selectedReportId !== reportId) { - severityFilter.current = getDefaultSeverityFilter(reportTreeData.current[reportId].severities); - messageFilter.current = ''; - selectedReportId.current = reportId; - refreshLogsOnSelectedReport(); + dispatch( + setReportFilters(reportId, '', getDefaultSeverityFilter(reportTreeData.current[reportId].severities)) + ); } }; - const onSeverityChange = (newSeverityFilter) => { - severityFilter.current = newSeverityFilter; - refreshLogsOnSelectedReport(); - }; - - // useEffect(() => { - // const timeout = setTimeout(() => refreshLogsOnSelectedReport(), 500); - // - // return () => clearTimeout(timeout); - // }, [messageFilter.current]); - - const handleMessageFilterChange = (newMessageFilter) => { - messageFilter.current = newMessageFilter; - refreshLogsOnSelectedReport(); - }; - // The MUI TreeView/TreeItems use useMemo on our items, so it's important to avoid changing the context const isHighlighted = useMemo( () => ({ @@ -176,7 +158,7 @@ export default function ReportViewer({ report, reportType }) { {/*TODO do we need to useMemo/useCallback these props to avoid rerenders ?*/} - + diff --git a/src/redux/actions.ts b/src/redux/actions.ts index 3e867e2c16..ab19985996 100644 --- a/src/redux/actions.ts +++ b/src/redux/actions.ts @@ -64,6 +64,7 @@ import { } from '../utils/store-sort-filter-fields'; import { SortConfigType } from '../hooks/use-aggrid-sort'; import { StudyDisplayMode } from '../components/network-modification.type'; +import { SeverityFilter } from '../types/report.type'; type MutableUnknownArray = unknown[]; @@ -1124,3 +1125,21 @@ export function setTableSort(table: TableSortKeysType, tab: string, sort: SortCo sort, }; } +export const REPORT_FILTER = 'REPORT_FILTER'; +export type ReportFilterAction = Readonly> & { + reportId: string | null | undefined; + messageFilter: string | undefined; + severityFilter: SeverityFilter | undefined; +}; +export function setReportFilters( + reportId: string, + messageFilter: string, + severityFilter: SeverityFilter +): ReportFilterAction { + return { + type: REPORT_FILTER, + reportId, + messageFilter, + severityFilter, + }; +} diff --git a/src/redux/reducer.ts b/src/redux/reducer.ts index e8011b52b9..4ca736d37b 100644 --- a/src/redux/reducer.ts +++ b/src/redux/reducer.ts @@ -181,6 +181,7 @@ import { SUBSTATION_LAYOUT, SubstationLayoutAction, TABLE_SORT, + REPORT_FILTER, TableSortAction, TOGGLE_PIN_DIAGRAM, TogglePinDiagramAction, @@ -188,6 +189,7 @@ import { UpdateEquipmentsAction, USE_NAME, UseNameAction, + ReportFilterAction, } from './actions'; import { getLocalStorageComputedLanguage, @@ -271,6 +273,8 @@ import { Node } from 'react-flow-renderer'; import { BUILD_STATUS } from '../components/network/constants'; import { SortConfigType, SortWay } from '../hooks/use-aggrid-sort'; import { StudyDisplayMode } from '../components/network-modification.type'; +import { SeverityFilter } from '../types/report.type'; +import { getDefaultSeverityFilter } from '../utils/report-severity.utils'; export enum NotificationType { STUDY = 'study', @@ -411,6 +415,9 @@ export interface AppState extends CommonStoreState { studyDisplayMode: StudyDisplayMode; studyIndexationStatus: StudyIndexationStatus; tableSort: TableSort; + reportMessageFilter: string; + reportSeverityFilter: SeverityFilter; + reportSelectedReportId: string | null; limitReductionModified: boolean; selectionForCopy: SelectionForCopy; @@ -562,6 +569,9 @@ const initialState: AppState = { oneBusShortCircuitAnalysisDiagram: null, studyIndexationStatus: StudyIndexationStatus.NOT_INDEXED, limitReductionModified: false, + reportMessageFilter: '', + reportSeverityFilter: getDefaultSeverityFilter(), + reportSelectedReportId: null, // params [PARAM_THEME]: getLocalStorageTheme(), @@ -1543,6 +1553,18 @@ export const reducer = createReducer(initialState, (builder) => { builder.addCase(TABLE_SORT, (state, action: TableSortAction) => { state.tableSort[action.table][action.tab] = action.sort; }); + + builder.addCase(REPORT_FILTER, (state, action: ReportFilterAction) => { + if (action.messageFilter !== undefined) { + state.reportMessageFilter = action.messageFilter; + } + if (action.severityFilter !== undefined) { + state.reportSeverityFilter = action.severityFilter; + } + if (action.reportId !== undefined) { + state.reportSelectedReportId = action.reportId; + } + }); }); function updateSubstationAfterVLDeletion(currentSubstations: Substation[], VLToDeleteId: string): Substation[] {