Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LogTable : remove direct report dependency and include severity fetching logic #2480

Merged
Show file tree
Hide file tree
Changes from 4 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
12 changes: 10 additions & 2 deletions src/components/report-viewer-tab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { useReportFetcher } from '../hooks/use-report-fetcher';
import { COMPUTING_AND_NETWORK_MODIFICATION_TYPE } from '../utils/report/report.constant';
import { ROOT_NODE_LABEL } from '../constants/node.constant';
import { Box, Paper } from '@mui/material';
import { ReportType } from 'utils/report/report.type';
import { sortSeverityList } from 'utils/report/report-severity';

const styles = {
div: {
Expand All @@ -40,10 +42,11 @@ const styles = {
*/
export const ReportViewerTab = ({ visible, currentNode, disabled }) => {
const [report, setReport] = useState();
const [severities, setSeverities] = useState();
const [nodeOnlyReport, setNodeOnlyReport] = useState(true);
const treeModel = useSelector((state) => state.networkModificationTreeModel);
const intl = useIntl();
const [isReportLoading, fetchReport] = useReportFetcher(
const [isReportLoading, fetchReport, , fetchReportSeverities] = useReportFetcher(
COMPUTING_AND_NETWORK_MODIFICATION_TYPE.NETWORK_MODIFICATION
);

Expand All @@ -64,16 +67,20 @@ export const ReportViewerTab = ({ visible, currentNode, disabled }) => {
fetchReport(nodeOnlyReport).then((r) => {
if (r !== undefined) {
setReport(r);
fetchReportSeverities(r.id, r.parentId ? ReportType.NODE : ReportType.GLOBAL).then((severities) => {
setSeverities(sortSeverityList(severities));
});
}
});
} else {
// if the user unbuilds a node, the report needs to be reset.
// otherwise, the report will be kept in the state and useless report fetches with previous id will be made when the user rebuilds the node.
setReport();
setSeverities();
}
// It is important to keep the notifications in the useEffect's dependencies (even if it is not
// apparent that they are used) to trigger the update of reports when a notification happens.
}, [visible, currentNode, disabled, fetchReport, nodeOnlyReport]);
}, [visible, currentNode, disabled, fetchReport, nodeOnlyReport, fetchReportSeverities]);

return (
<WaitingLoader loading={isReportLoading} message={'loadingReport'}>
Expand Down Expand Up @@ -101,6 +108,7 @@ export const ReportViewerTab = ({ visible, currentNode, disabled }) => {
<ReportViewer
report={report}
reportType={COMPUTING_AND_NETWORK_MODIFICATION_TYPE.NETWORK_MODIFICATION}
severities={severities}
/>
)}
</Paper>
Expand Down
19 changes: 10 additions & 9 deletions src/components/report-viewer/log-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ import { getColumnFilterValue, useAggridRowFilter } from 'hooks/use-aggrid-row-f
import { LOGS_STORE_FIELD } from 'utils/store-sort-filter-fields';
import { useReportFetcher } from 'hooks/use-report-fetcher';
import { useDispatch } from 'react-redux';
import { getDefaultSeverityFilter, getReportSeverities, REPORT_SEVERITY } from '../../utils/report/report-severity';
import { getDefaultSeverityFilter, REPORT_SEVERITY } from '../../utils/report/report-severity';
import { QuickSearch } from './QuickSearch';
import { Box, Chip, Theme } from '@mui/material';
import { CellClickedEvent, GridApi, ICellRendererParams, IRowNode, RowClassParams, RowStyle } from 'ag-grid-community';
import { AgGridReact } from 'ag-grid-react';
import { Report, ReportLog, ReportType } from 'utils/report/report.type';
import { ReportLog, ReportType, SeverityLevel } from 'utils/report/report.type';
import { COMPUTING_AND_NETWORK_MODIFICATION_TYPE } from 'utils/report/report.constant';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
import VisibilityIcon from '@mui/icons-material/Visibility';
Expand Down Expand Up @@ -59,21 +59,23 @@ const styles = {
const SEVERITY_COLUMN_FIXED_WIDTH = 115;

type LogTableProps = {
report: Report;
selectedReportId: string;
reportType: string;
reportNature: ReportType;
severities: SeverityLevel[] | undefined;
onRowClick: (data: ReportLog) => void;
};

const LogTable = ({ report, selectedReportId, reportType, reportNature, onRowClick }: LogTableProps) => {
const LogTable = ({ selectedReportId, reportType, reportNature, severities, onRowClick }: LogTableProps) => {
const intl = useIntl();

const theme = useTheme<Theme>();

const dispatch = useDispatch();

const [, , fetchReportLogs] = useReportFetcher(reportType as keyof typeof COMPUTING_AND_NETWORK_MODIFICATION_TYPE);
const [, , fetchReportLogs, fetchNodeSeverities] = useReportFetcher(
reportType as keyof typeof COMPUTING_AND_NETWORK_MODIFICATION_TYPE
);
const { updateFilter, filterSelector } = useAggridRowFilter({
filterType: LOGS_STORE_FIELD,
filterTab: reportType,
Expand All @@ -89,7 +91,6 @@ const LogTable = ({ report, selectedReportId, reportType, reportNature, onRowCli

const severityFilter = useMemo(() => getColumnFilterValue(filterSelector, 'severity') ?? [], [filterSelector]);
const messageFilter = useMemo(() => getColumnFilterValue(filterSelector, 'message'), [filterSelector]);
const severities = useMemo(() => getReportSeverities(report), [report]);

const resetSearch = useCallback(() => {
setSearchResults([]);
Expand Down Expand Up @@ -120,7 +121,7 @@ const LogTable = ({ report, selectedReportId, reportType, reportNature, onRowCli
}, [severityFilter, fetchReportLogs, selectedReportId, reportNature, messageFilter, resetSearch]);

useEffect(() => {
if (filterSelector?.length === 0 && severities?.length > 0) {
if (filterSelector?.length === 0 && severities && severities.length > 0) {
dispatch(
setLogsFilter(reportType, [
{
Expand All @@ -132,7 +133,7 @@ const LogTable = ({ report, selectedReportId, reportType, reportNature, onRowCli
])
);
}
}, [severities, dispatch, reportType, filterSelector]);
}, [severities, dispatch, reportType, filterSelector, fetchNodeSeverities, selectedReportId, reportNature]);

useEffect(() => {
if (selectedReportId && reportNature) {
Expand Down Expand Up @@ -320,7 +321,7 @@ const LogTable = ({ report, selectedReportId, reportType, reportNature, onRowCli
/>
</Box>
<Box sx={styles.chipContainer}>
{severities.map((severity, index) => (
{severities?.map((severity, index) => (
<Chip
key={severity}
label={severity}
Expand Down
8 changes: 4 additions & 4 deletions src/components/report-viewer/report-viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import { mapReportsTree } from '../../utils/report/report-tree.mapper';
import { useDispatch } from 'react-redux';
import { VirtualizedTreeview } from './virtualized-treeview';
import { ReportItem } from './treeview-item';
import { Report, ReportLog, ReportTree, ReportType } from 'utils/report/report.type';
import { Report, ReportLog, ReportTree, ReportType, SeverityLevel } from 'utils/report/report.type';

type ReportViewerProps = { report: Report; reportType: string };
type ReportViewerProps = { report: Report; reportType: string; severities: SeverityLevel[] | undefined };

export default function ReportViewer({ report, reportType }: ReportViewerProps) {
export default function ReportViewer({ report, reportType, severities }: ReportViewerProps) {
const dispatch = useDispatch();

const [expandedTreeReports, setExpandedTreeReports] = useState<string[]>([]);
Expand Down Expand Up @@ -97,10 +97,10 @@ export default function ReportViewer({ report, reportType }: ReportViewerProps)
<Grid item xs={12} sm={9}>
{selectedReportId && selectedReportType && (
<LogTable
report={report}
selectedReportId={selectedReportId}
reportType={reportType}
reportNature={selectedReportType} // GlobalReport or NodeReport
severities={severities}
onRowClick={onLogRowClick}
/>
)}
Expand Down
18 changes: 14 additions & 4 deletions src/components/results/common/computation-report-viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@ import { AppState } from '../../../redux/reducer';
import { ComputingType } from '../../computing-status/computing-type';
import WaitingLoader from '../../utils/waiting-loader';
import { useReportFetcher } from '../../../hooks/use-report-fetcher';
import { Report } from '../../../utils/report/report.type';
import { Report, ReportType, SeverityLevel } from '../../../utils/report/report.type';
import { BUILD_STATUS } from 'components/network/constants';
import { Box } from '@mui/material';
import { sortSeverityList } from 'utils/report/report-severity';

interface ComputationReportViewerProps {
reportType: ComputingType;
}

export const ComputationReportViewer: FunctionComponent<ComputationReportViewerProps> = ({ reportType }) => {
const [report, setReport] = useState<Report>();
const [severities, setSeverities] = useState<SeverityLevel[]>();
const studyUuid = useSelector((state: AppState) => state.studyUuid);
const currentNode = useSelector((state: AppState) => state.currentTreeNode);
const [isReportLoading, fetchReport] = useReportFetcher(reportType);
const [isReportLoading, fetchReport, , fetchReportSeverities] = useReportFetcher(reportType);
const shouldFetchReport = useMemo(
() => studyUuid && currentNode?.id && currentNode?.data?.globalBuildStatus !== BUILD_STATUS.NOT_BUILT,
[studyUuid, currentNode]
Expand All @@ -35,19 +37,27 @@ export const ComputationReportViewer: FunctionComponent<ComputationReportViewerP
fetchReport().then((report) => {
if (report !== undefined) {
setReport(report);
fetchReportSeverities?.(report?.id, report?.parentId ? ReportType.NODE : ReportType.GLOBAL)?.then(
TheMaskedTurtle marked this conversation as resolved.
Show resolved Hide resolved
(severities) => {
setSeverities(sortSeverityList(severities));
}
);
}
});
} else {
// if the user unbuilds a node, the report needs to be reset.
// otherwise, the report will be kept in the state and useless report fetches with previous id will be made when the user rebuilds the node.
setReport(undefined);
setSeverities(undefined);
}
}, [reportType, fetchReport, shouldFetchReport]);
}, [reportType, fetchReport, shouldFetchReport, fetchReportSeverities]);

return (
<WaitingLoader loading={isReportLoading} message={'loadingReport'}>
<Box sx={{ marginTop: 1 }}>
{shouldFetchReport && report && <ReportViewer report={report} reportType={reportType} />}
{shouldFetchReport && report && (
<ReportViewer report={report} reportType={reportType} severities={severities} />
)}
</Box>
</WaitingLoader>
);
Expand Down
23 changes: 20 additions & 3 deletions src/hooks/use-report-fetcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { useSelector } from 'react-redux';
import { AppState } from '../redux/reducer';
import { useCallback, useMemo, useState } from 'react';
import { fetchNodeReportLogs, fetchParentNodesReport } from '../services/study';
import { fetchNodeReportLogs, fetchNodeSeverities, fetchParentNodesReport } from '../services/study';
import { useSnackMessage } from '@gridsuite/commons-ui';
import { Log, Report, ReportLog, ReportSeverity, ReportType, SeverityLevel } from '../utils/report/report.type';
import { getContainerDefaultSeverityList, REPORT_SEVERITY } from '../utils/report/report-severity';
Expand Down Expand Up @@ -75,7 +75,8 @@ export const useReportFetcher = (
severityList: string[],
reportType: ReportType,
filterMessage: string
) => Promise<Log[]> | undefined
) => Promise<Log[]> | undefined,
(reportId: string, reportType: ReportType) => Promise<SeverityLevel[]> | undefined
] => {
const [isLoading, setIsLoading] = useState(false);
const studyUuid = useSelector((state: AppState) => state.studyUuid);
Expand Down Expand Up @@ -151,5 +152,21 @@ export const useReportFetcher = (
[currentNode, studyUuid, nodesNames]
);

return [isLoading, fetchRawParentReport, fetchReportLogs];
const fetchReportSeverities = useCallback(
(reportId: string, reportType: ReportType) => {
if (!studyUuid) {
return;
}
let fetchPromise: (reportId: string) => Promise<SeverityLevel[]>;
if (reportType === ReportType.GLOBAL) {
fetchPromise = () => fetchNodeSeverities(studyUuid, currentNode!.id, null, true);
} else {
fetchPromise = (reportId: string) => fetchNodeSeverities(studyUuid, currentNode!.id, reportId, false);
}
return fetchPromise(reportId);
},
[currentNode, studyUuid]
);

return [isLoading, fetchRawParentReport, fetchReportLogs, fetchReportSeverities];
};
10 changes: 10 additions & 0 deletions src/services/study/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ export function fetchNodeReportLogs(
return backendFetchJson(url);
}

export function fetchNodeSeverities(studyUuid: UUID, nodeUuid: UUID, reportId: string | null, isGlobalLogs: boolean) {
let url;
if (isGlobalLogs) {
url = getStudyUrlWithNodeUuid(studyUuid, nodeUuid) + '/report/aggregated-severities';
} else {
url = getStudyUrlWithNodeUuid(studyUuid, nodeUuid) + '/report/' + reportId + '/aggregated-severities';
}
return backendFetchJson(url);
}

export function fetchSvg(svgUrl: string) {
console.debug(svgUrl);
return backendFetch(svgUrl).then((response) => (response.status === 204 ? null : response.json()));
Expand Down
18 changes: 4 additions & 14 deletions src/utils/report/report-severity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { ReportSeverity, SeverityLevel, Report } from './report.type';
import { ReportSeverity, SeverityLevel } from './report.type';

export const REPORT_SEVERITY: Record<SeverityLevel, ReportSeverity> = {
UNKNOWN: {
Expand Down Expand Up @@ -80,19 +80,9 @@ export const getDefaultSeverityFilter = (severityList: string[]): string[] => {
return severityFilter;
};

export const getReportSeverities = (report: Report): SeverityLevel[] => {
const severities: SeverityLevel[] = [];
if (report.severity) {
severities.push(report.severity);
}
if (report.subReports.length > 0) {
report.subReports.forEach((subreport) => {
severities.push(...getReportSeverities(subreport));
});
}
severities.sort((a, b) => REPORT_SEVERITY[b].level - REPORT_SEVERITY[a].level);
return [...new Set(severities)];
};
export function sortSeverityList(severityList: SeverityLevel[]): SeverityLevel[] {
return severityList.sort((a, b) => REPORT_SEVERITY[b].level - REPORT_SEVERITY[a].level);
}

export function getContainerDefaultSeverityList(): string[] {
// return name list like ['WARN', 'INFO']
Expand Down
Loading