Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
SecurityAnalysisResultNmkProps,
} from './security-analysis.type';
import {
flattenNmKPowerCutOff,
flattenNmKResultsConstraints,
flattenNmKResultsContingencies,
handlePostSortRows,
Expand All @@ -37,6 +38,7 @@ export const SecurityAnalysisResultNmk: FunctionComponent<SecurityAnalysisResult
columnDefs,
isLoadingResult,
isFromContingency,
isPowerCutOffView,
paginationProps,
computationSubType,
}) => {
Expand All @@ -45,23 +47,27 @@ export const SecurityAnalysisResultNmk: FunctionComponent<SecurityAnalysisResult
const theme = useTheme();
const intl: IntlShape = useIntl();

const rows = useMemo(
() =>
isFromContingency
? flattenNmKResultsContingencies(intl, content as ConstraintsFromContingencyItem[])
: flattenNmKResultsConstraints(intl, content as ContingenciesFromConstraintItem[]),
[content, intl, isFromContingency]
);
const rows = useMemo(() => {
if (isPowerCutOffView) {
return flattenNmKPowerCutOff(content as ConstraintsFromContingencyItem[]);
}
return isFromContingency
? flattenNmKResultsContingencies(intl, content as ConstraintsFromContingencyItem[])
: flattenNmKResultsConstraints(intl, content as ContingenciesFromConstraintItem[]);
}, [content, intl, isFromContingency, isPowerCutOffView]);

const getRowStyle = useCallback(
(params: RowClassParams) => {
if (isPowerCutOffView) {
return undefined;
}
if ((isFromContingency && params?.data?.contingencyId) || (!isFromContingency && params?.data?.subjectId)) {
return {
backgroundColor: theme.selectedRow.background,
};
}
},
[isFromContingency, theme.selectedRow.background]
[isFromContingency, isPowerCutOffView, theme.selectedRow.background]
);

const agGridProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { FunctionComponent, SyntheticEvent, useCallback, useEffect, useMemo, use
import { useSelector } from 'react-redux';
import { FormattedMessage, useIntl } from 'react-intl';
import { AppState } from '../../../redux/reducer.type';
import { Box, LinearProgress, MenuItem, Select, Tab, Tabs } from '@mui/material';
import { Badge, Box, LinearProgress, MenuItem, Select, SelectChangeEvent, Tab, Tabs } from '@mui/material';
import {
downloadSecurityAnalysisResultZippedCsv,
fetchSecurityAnalysisResult,
Expand All @@ -21,7 +21,13 @@ import { ComputingType, EquipmentType, GsLangUser, type MuiStyles, PARAM_DEVELOP
import { SecurityAnalysisResultN } from './security-analysis-result-n';
import { SecurityAnalysisResultNmk } from './security-analysis-result-nmk';
import { ComputationReportViewer } from '../common/computation-report-viewer';
import { RESULT_TYPE, SecurityAnalysisQueryParams, SecurityAnalysisTabProps } from './security-analysis.type';
import {
ConstraintsFromContingencyItem,
ContingenciesFromConstraintItem,
RESULT_TYPE,
SecurityAnalysisQueryParams,
SecurityAnalysisTabProps,
} from './security-analysis.type';
import {
convertFilterValues,
getStoreFields,
Expand Down Expand Up @@ -75,7 +81,8 @@ const styles = {
const N_RESULTS_TAB_INDEX = 0;
const NMK_RESULTS_TAB_INDEX = 1;
const LOGS_TAB_INDEX = 2;

const POWER_CUT_OFF_VIEW = 'constraints-from-power-cut-off' as const;
type NmkView = NMK_TYPE | typeof POWER_CUT_OFF_VIEW;
export const SecurityAnalysisResultTab: FunctionComponent<SecurityAnalysisTabProps> = ({
studyUuid,
nodeUuid,
Expand All @@ -86,9 +93,11 @@ export const SecurityAnalysisResultTab: FunctionComponent<SecurityAnalysisTabPro
const [tabIndex, setTabIndex] = useState(isDeveloperMode ? N_RESULTS_TAB_INDEX : NMK_RESULTS_TAB_INDEX);
const tabIndexRef = useRef<number>(null);
tabIndexRef.current = tabIndex;
const [nmkType, setNmkType] = useState(NMK_TYPE.CONSTRAINTS_FROM_CONTINGENCIES);
const [count, setCount] = useState<number>(0);
const [nmkView, setNmkView] = useState<NmkView>(NMK_TYPE.CONSTRAINTS_FROM_CONTINGENCIES);
const nmkType: NMK_TYPE = nmkView === POWER_CUT_OFF_VIEW ? NMK_TYPE.CONSTRAINTS_FROM_CONTINGENCIES : nmkView;

const isPowerCutOffView = nmkView === POWER_CUT_OFF_VIEW;
useEffect(() => {
if (!isDeveloperMode && tabIndexRef.current === N_RESULTS_TAB_INDEX) {
// handle tabIndex when dev mode is disabled
Expand Down Expand Up @@ -155,8 +164,11 @@ export const SecurityAnalysisResultTab: FunctionComponent<SecurityAnalysisTabPro
if (globalFilters) {
params['globalFilters'] = globalFilters;
}
if (isPowerCutOffView) {
params['isPowerCutOffView'] = true;
}
return params;
}, [resultType, tabIndex, sortConfig, filters, globalFiltersFromState, page, rowsPerPage, intl]);
}, [resultType, tabIndex, sortConfig, filters, globalFiltersFromState, isPowerCutOffView, page, rowsPerPage, intl]);

const fetchSecurityAnalysisResultWithQueryParams = useCallback(
(studyUuid: string, nodeUuid: string) => {
Expand Down Expand Up @@ -185,14 +197,10 @@ export const SecurityAnalysisResultTab: FunctionComponent<SecurityAnalysisTabPro
setCount(0);
}, [setResult]);

const handleChangeNmkType = () => {
const handleChangeNmkType = (event: SelectChangeEvent<NmkView>) => {
dispatchPagination({ page: 0, rowsPerPage });
resetResultStates();
setNmkType(
nmkType === NMK_TYPE.CONSTRAINTS_FROM_CONTINGENCIES
? NMK_TYPE.CONTINGENCIES_FROM_CONSTRAINTS
: NMK_TYPE.CONSTRAINTS_FROM_CONTINGENCIES
);
setNmkView(event.target.value as NmkView);
};

const handleTabChange = (event: SyntheticEvent, newTabIndex: number) => {
Expand Down Expand Up @@ -229,7 +237,7 @@ export const SecurityAnalysisResultTab: FunctionComponent<SecurityAnalysisTabPro
delay: RESULTS_LOADING_DELAY,
});

const columnDefs = useSecurityAnalysisColumnsDefs(filterEnums, resultType, tabIndex);
const columnDefs = useSecurityAnalysisColumnsDefs(filterEnums, resultType, tabIndex, isPowerCutOffView);

const csvHeaders = useMemo(() => columnDefs.map((cDef) => cDef.headerName ?? ''), [columnDefs]);
const downloadZipResult = useCallback(
Expand Down Expand Up @@ -279,6 +287,30 @@ export const SecurityAnalysisResultTab: FunctionComponent<SecurityAnalysisTabPro
return allFilterTypes;
}, [tabIndex]);

const hasPowerCutOffData = useMemo(() => {
const content = result?.content;
if (!content) {
return false;
}
const hasCutOff = (
cr?: {
disconnectedLoadActivePower?: number | null;
disconnectedGenerationActivePower?: number | null;
} | null
) => cr?.disconnectedLoadActivePower != null || cr?.disconnectedGenerationActivePower != null;

if (resultType === RESULT_TYPE.NMK_CONTINGENCIES) {
return (content as ConstraintsFromContingencyItem[]).some((item) =>
hasCutOff(item.contingency?.connectivityResult)
);
}
if (resultType === RESULT_TYPE.NMK_LIMIT_VIOLATIONS) {
return (content as ContingenciesFromConstraintItem[]).some((item) =>
item.contingencies?.some((c) => hasCutOff(c.contingency?.connectivityResult))
);
}
return false;
}, [result, resultType]);
return (
<>
<Box sx={styles.tabsAndToolboxContainer}>
Expand Down Expand Up @@ -307,20 +339,31 @@ export const SecurityAnalysisResultTab: FunctionComponent<SecurityAnalysisTabPro
)}
<Box sx={styles.toolboxContainer}>
{tabIndex === NMK_RESULTS_TAB_INDEX && (
<Select
labelId="nmk-type-label"
value={nmkType}
onChange={handleChangeNmkType}
autoWidth={true}
size="small"
<Badge
overlap="circular"
color="info"
variant="dot"
invisible={!hasPowerCutOffData || isPowerCutOffView}
sx={{ '& .MuiBadge-badge': { right: -4, top: 8 } }}
>
<MenuItem value={NMK_TYPE.CONSTRAINTS_FROM_CONTINGENCIES}>
<FormattedMessage id="ConstraintsFromContingencies" />
</MenuItem>
<MenuItem value={NMK_TYPE.CONTINGENCIES_FROM_CONSTRAINTS}>
<FormattedMessage id="ContingenciesFromConstraints" />
</MenuItem>
</Select>
<Select
labelId="nmk-type-label"
value={nmkView}
onChange={handleChangeNmkType}
autoWidth={true}
size="small"
>
<MenuItem value={NMK_TYPE.CONSTRAINTS_FROM_CONTINGENCIES}>
<FormattedMessage id="ConstraintsFromContingencies" />
</MenuItem>
<MenuItem value={NMK_TYPE.CONTINGENCIES_FROM_CONSTRAINTS}>
<FormattedMessage id="ContingenciesFromConstraints" />
</MenuItem>
<MenuItem value={POWER_CUT_OFF_VIEW}>
<FormattedMessage id="ConstraintsFromPowerCutOff" />
</MenuItem>
</Select>
</Badge>
)}
{(tabIndex === NMK_RESULTS_TAB_INDEX || (tabIndex === N_RESULTS_TAB_INDEX && isDeveloperMode)) && (
<SecurityAnalysisExportButton
Expand Down Expand Up @@ -349,6 +392,7 @@ export const SecurityAnalysisResultTab: FunctionComponent<SecurityAnalysisTabPro
result={result}
isLoadingResult={isLoadingResult || filterEnumsLoading}
isFromContingency={nmkType === NMK_TYPE.CONSTRAINTS_FROM_CONTINGENCIES}
isPowerCutOffView={isPowerCutOffView}
paginationProps={{
count,
rowsPerPage: rowsPerPage as number,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,10 @@ export enum NMK_TYPE {
CONTINGENCIES_FROM_CONSTRAINTS = 'contingencies-from-constraints',
}

export const mappingColumnToField = (resultType: RESULT_TYPE) => {
export const mappingColumnToField = (resultType: RESULT_TYPE, isPowerCutOffView = false) => {
if (resultType === RESULT_TYPE.NMK_CONTINGENCIES && isPowerCutOffView) {
return FROM_COLUMN_TO_FIELD_NMK_POWER_CUT_OFF;
}
switch (resultType) {
case RESULT_TYPE.N:
return FROM_COLUMN_TO_FIELD_N;
Expand Down Expand Up @@ -785,3 +788,70 @@ export const getStoreFields = (index: number): string => {
return '';
}
};

export const flattenNmKPowerCutOff = (result: ConstraintsFromContingencyItem[] | null) => {
if (!result) {
return undefined;
}
return result.map(({ contingency }) => {
const { contingencyId, status, elements = [], connectivityResult } = contingency || {};
return {
contingencyId,
contingencyEquipmentsIds: elements.map((e) => e.id),
status,
disconnectedLoadActivePower: connectivityResult?.disconnectedLoadActivePower,
disconnectedGenerationActivePower: connectivityResult?.disconnectedGenerationActivePower,
};
});
};

export const FROM_COLUMN_TO_FIELD_NMK_POWER_CUT_OFF: Record<string, string> = {
contingencyId: 'contingencyId',
status: 'status',
disconnectedLoadActivePower: 'connectivityResult.disconnectedLoadActivePower',
disconnectedGenerationActivePower: 'connectivityResult.disconnectedGenerationActivePower',
};

export const securityAnalysisTableNmKPowerCutOffColumnsDefinition = (
intl: IntlShape,
filterEnums: FilterEnumsType,
getEnumLabel: (value: string) => string,
tabIndex: number
): ColDef[] => {
const { sortParams, filterParams } = createTableParams(tabIndex);

return [
makeAgGridCustomHeaderColumn({
...makeAgGridStringColumn('Contingency', 'contingencyId', intl, filterParams, sortParams),
valueGetter: contingencyGetterValues,
cellRenderer: ContingencyCellRenderer,
}),
createEnumColumn(
'status',
'ComputationStatus',
filterEnums['status'] ?? [],
getEnumLabel,
intl,
sortParams,
filterParams
),
makeAgGridCustomHeaderColumn(
makeAgGridFloatColumn(
'disconnectedLoadActivePower',
'disconnectedLoadActivePower',
intl,
filterParams,
sortParams
)
),
makeAgGridCustomHeaderColumn(
makeAgGridFloatColumn(
'disconnectedGenerationActivePower',
'disconnectedGenerationActivePower',
intl,
filterParams,
sortParams
)
),
Comment thread
coderabbitai[bot] marked this conversation as resolved.
];
};
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,19 @@ export interface ContingencyItem {
status?: string;
contingencyId?: string;
elements?: Element[];
connectivityResult?: ConnectivityResult;
}

export interface Contingency {
contingency?: ContingencyItem;
limitViolation?: LimitViolation;
}

export interface ConnectivityResult {
disconnectedLoadActivePower: number;
disconnectedGenerationActivePower: number;
}

export interface SecurityAnalysisNmkTableRow {
subjectId?: string;
locationId?: string;
Expand Down Expand Up @@ -102,6 +108,7 @@ export type SecurityAnalysisQueryParams = {
sort?: SortConfig[];
page?: number;
size?: number;
isPowerCutOffView?: boolean;
};

export type SubjectIdRendererType = (cellData: ICellRendererParams) => React.JSX.Element | undefined;
Expand Down Expand Up @@ -129,6 +136,7 @@ export interface SecurityAnalysisResultNmkProps {
columnDefs: ColDef<any>[];
isLoadingResult: boolean;
isFromContingency: boolean;
isPowerCutOffView: boolean;
paginationProps: TablePaginationProps;
computationSubType: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
securityAnalysisTableNColumnsDefinition,
securityAnalysisTableNmKConstraintsColumnsDefinition,
securityAnalysisTableNmKContingenciesColumnsDefinition,
securityAnalysisTableNmKPowerCutOffColumnsDefinition,
} from './security-analysis-result-utils';
import { useSelector } from 'react-redux';
import { AppState } from 'redux/reducer.type';
Expand All @@ -33,13 +34,15 @@ export interface SecurityAnalysisFilterEnumsType {
type UseSecurityAnalysisColumnsDefsProps = (
filterEnums: SecurityAnalysisFilterEnumsType,
resultType: RESULT_TYPE,
tabIndex: number
tabIndex: number,
isPowerCutOffView: boolean
) => ColDef[];

export const useSecurityAnalysisColumnsDefs: UseSecurityAnalysisColumnsDefsProps = (
filterEnums,
resultType,
tabIndex
tabIndex,
isPowerCutOffView
) => {
const intl = useIntl();
const { snackError } = useSnackMessage();
Expand Down Expand Up @@ -132,6 +135,9 @@ export const useSecurityAnalysisColumnsDefs: UseSecurityAnalysisColumnsDefsProps
);

const columnDefs = useMemo(() => {
if (isPowerCutOffView && resultType === RESULT_TYPE.NMK_CONTINGENCIES) {
return securityAnalysisTableNmKPowerCutOffColumnsDefinition(intl, filterEnums.nmk, getEnumLabel, tabIndex);
}
switch (resultType) {
case RESULT_TYPE.NMK_CONTINGENCIES:
return securityAnalysisTableNmKContingenciesColumnsDefinition(
Expand All @@ -152,7 +158,16 @@ export const useSecurityAnalysisColumnsDefs: UseSecurityAnalysisColumnsDefsProps
case RESULT_TYPE.N:
return securityAnalysisTableNColumnsDefinition(intl, filterEnums.n, getEnumLabel, tabIndex);
}
}, [resultType, intl, SubjectIdRenderer, filterEnums.nmk, filterEnums.n, getEnumLabel, tabIndex]);
}, [
isPowerCutOffView,
resultType,
intl,
filterEnums.nmk,
filterEnums.n,
getEnumLabel,
tabIndex,
SubjectIdRenderer,
]);

return columnDefs;
};
Loading
Loading