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
4 changes: 2 additions & 2 deletions src/components/dnd-table/dnd-table-bottom-right-buttons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export function DndTableBottomRightButtons({
});

const noRowsSelected = currentRows ? !currentRows.some((row) => row[SELECTED]) : true;
const firstRowSelected = currentRows[0]?.[SELECTED];
const lastRowSelected = currentRows[currentRows.length - 1]?.[SELECTED];
const firstRowSelected = noRowsSelected ? undefined : currentRows[0]?.[SELECTED];
const lastRowSelected = noRowsSelected ? undefined : currentRows[currentRows.length - 1]?.[SELECTED];

return (
<Grid container item xs spacing={1} sx={{ justifyContent: 'flex-end' }}>
Expand Down
6 changes: 5 additions & 1 deletion src/components/dnd-table/dnd-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
ErrorInput,
FieldErrorAlert,
RawReadOnlyInput,
SwitchInput,
TableNumericalInput,
TableTextInput,
} from '../inputs';
Expand Down Expand Up @@ -168,12 +169,15 @@ function EditableTableCell({
{column.type === DndColumnType.CHIP_ITEMS && (
<ChipItemsInput name={`${arrayFormName}[${rowIndex}].${column.dataKey}`} hideErrorMessage />
)}
{column.type === DndColumnType.SWITCH && (
<SwitchInput name={`${arrayFormName}[${rowIndex}].${column.dataKey}`} />
)}
{column.type === DndColumnType.CUSTOM && column.component(rowIndex)}
</TableCell>
);
}

interface DndTableProps {
export interface DndTableProps {
arrayFormName: string;
useFieldArrayOutput: UseFieldArrayReturn;
columnsDefinition: DndColumn[];
Expand Down
7 changes: 7 additions & 0 deletions src/components/dnd-table/dnd-table.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export enum DndColumnType {
AUTOCOMPLETE = 'AUTOCOMPLETE',
CHIP_ITEMS = 'CHIP_ITEMS',
DIRECTORY_ITEMS = 'DIRECTORY_ITEMS',
SWITCH = 'SWITCH',
CUSTOM = 'CUSTOM',
}

Expand All @@ -28,6 +29,7 @@ export interface ColumnBase {
extra?: JSX.Element;
editable?: boolean;
type: DndColumnType;
initialValue?: any; // should conform to the type field
}

export interface ColumnText extends ColumnBase {
Expand Down Expand Up @@ -58,6 +60,10 @@ export interface ColumnChipsItem extends ColumnBase {
type: DndColumnType.CHIP_ITEMS;
}

export interface ColumnSwitchItem extends ColumnBase {
type: DndColumnType.SWITCH;
}

export interface ColumnCustom extends ColumnBase {
type: DndColumnType.CUSTOM;
component: (rowIndex: number) => ReactNode;
Expand All @@ -69,4 +75,5 @@ export type DndColumn =
| ColumnText
| ColumnDirectoryItem
| ColumnChipsItem
| ColumnSwitchItem
| ColumnCustom;
4 changes: 2 additions & 2 deletions src/components/parameters/common/ProviderParam.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ const styles = {
export function ProviderParam({ options }: Readonly<ProviderParamProps>) {
return (
<>
<Grid xl={8} container sx={styles.providerParam} paddingRight={1}>
<Grid container sx={styles.providerParam} paddingRight={1}>
<Grid item xs sx={parametersStyles.parameterName}>
<FormattedMessage id="Provider" />
</Grid>
<Grid item container xs={2} sx={parametersStyles.controlItem}>
<MuiSelectInput name={PROVIDER} size="small" fullWidth options={options} />
</Grid>
</Grid>
<Grid container paddingTop={1} paddingRight={1} xl={8}>
<Grid container paddingTop={1} paddingRight={1}>
<LineSeparator />
</Grid>
</>
Expand Down
72 changes: 72 additions & 0 deletions src/components/parameters/common/parameter-dnd-table-field.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Copyright (c) 2026, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { Grid, SxProps, Tooltip, TooltipProps, Typography } from '@mui/material';
import { FormattedMessage } from 'react-intl';
import { useFieldArray } from 'react-hook-form';
import { Info as InfoIcon } from '@mui/icons-material';
import { useCallback, useMemo } from 'react';
import { DndTable, DndTableProps } from '../../dnd-table';

export type ParameterDndTableFieldProps = {
name: string;
label: string;
tooltipProps?: Omit<TooltipProps, 'children'>;
sxContainerProps?: SxProps;
} & Omit<DndTableProps, 'arrayFormName' | 'useFieldArrayOutput'>;

export default function ParameterDndTableField({
name,
label,
columnsDefinition,
tooltipProps,
sxContainerProps,
...otherProps
}: Readonly<ParameterDndTableFieldProps>) {
const useFieldArrayOutput = useFieldArray({
name,
});

const newDefaultRowData = useMemo(() => {
const newRowData: Record<string, any> = {};
columnsDefinition.forEach((columnDefinition) => {
newRowData[columnDefinition.dataKey] = columnDefinition.initialValue || null;
});
return newRowData;
}, [columnsDefinition]);

const createRows = useCallback(() => [newDefaultRowData], [newDefaultRowData]);

const { title, ...otherTooltipProps } = tooltipProps || {};
return (
<Grid container sx={sxContainerProps}>
<Grid container alignItems="center" paddingBottom={2} paddingTop={2}>
<Typography component="span" variant="h6">
<FormattedMessage id={label} />
</Typography>
{tooltipProps && (
<Tooltip
title={typeof title === 'string' ? <FormattedMessage id={title} /> : title}
placement="right-start"
sx={{ marginLeft: 1 }}
{...otherTooltipProps}
>
<InfoIcon />
</Tooltip>
)}
</Grid>
<DndTable
arrayFormName={name}
useFieldArrayOutput={useFieldArrayOutput}
columnsDefinition={columnsDefinition}
createRows={createRows}
withAddRowsDialog={false}
{...otherProps}
/>
</Grid>
);
}
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 { Grid, Tooltip, Chip, Typography } from '@mui/material';
import { Chip, Grid, SxProps, Tooltip, Typography } from '@mui/material';
import { FormattedMessage } from 'react-intl';
import { parametersStyles } from '../parameters-style';
import { ParameterType } from '../../../utils/types/parameters.type';
Expand All @@ -19,30 +19,24 @@ import {
SwitchInput,
TextInput,
} from '../../inputs';
import { LineSeparator } from '../common';
import { LineSeparator } from './index';

interface LoadFlowParameterFieldProps {
interface ParameterFieldProps {
id: string;
name: string;
type: string;
label?: string;
description?: string;
possibleValues?: { id: string; label: string }[] | string[];
sx?: SxProps;
}

function LoadFlowParameterField({
id,
name,
type,
label,
description,
possibleValues,
}: Readonly<LoadFlowParameterFieldProps>) {
function ParameterField({ id, name, type, label, description, possibleValues, sx }: Readonly<ParameterFieldProps>) {
const renderField = () => {
switch (type) {
case ParameterType.STRING:
return possibleValues ? (
<MuiSelectInput name={`${id}.${name}`} options={possibleValues} size="small" />
<MuiSelectInput name={`${id}.${name}`} options={possibleValues} size="small" sx={sx} />
) : (
<TextInput name={`${id}.${name}`} />
);
Expand Down Expand Up @@ -94,4 +88,4 @@ function LoadFlowParameterField({
);
}

export default LoadFlowParameterField;
export default ParameterField;
21 changes: 21 additions & 0 deletions src/components/parameters/dynamic-margin-calculation/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright (c) 2026, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

// tab TAB_TIME_DELAY
export const START_TIME = 'startTime';
export const STOP_TIME = 'stopTime';
// tab TAB_LOADS_VARIATIONS
export const MARGIN_CALCULATION_START_TIME = 'marginCalculationStartTime';
export const LOAD_INCREASE_START_TIME = 'loadIncreaseStartTime';
export const LOAD_INCREASE_STOP_TIME = 'loadIncreaseStopTime';
export const CALCULATION_TYPE = 'calculationType';
export const ACCURACY = 'accuracy';
export const LOAD_MODELS_RULE = 'loadModelsRule';
export const LOADS_VARIATIONS = 'loadsVariations';
export const LOAD_FILTERS = 'loadFilters';
export const VARIATION = 'variation';
export const ACTIVE = 'active';
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Copyright (c) 2026, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* Copyright (c) 2026, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { ReactNode } from 'react';
import { Grid, LinearProgress, Tab, Tabs } from '@mui/material';
import { FormattedMessage } from 'react-intl';
import { UseDynamicMarginCalculationParametersFormReturn } from './use-dynamic-margin-calculation-parameters-form';
import { mergeSx } from '../../../utils';
import { CustomFormProvider } from '../../inputs';
import { ProviderParam } from '../common';
import { getTabStyle, parametersStyles } from '../parameters-style';
import { TabPanel } from '../common/parameters';
import TimeDelayParameters from './time-delay-parameters';
import LoadsVariationsParameters from './loads-variations-parameters';

import { TabValues } from './dynamic-margin-calculation.type';

type DynamicMarginCalculationFormProps = {
dynamicMarginCalculationMethods: UseDynamicMarginCalculationParametersFormReturn;
renderTitleFields?: () => ReactNode;
renderActions?: () => ReactNode;
};

export function DynamicMarginCalculationForm({
dynamicMarginCalculationMethods,
renderTitleFields,
renderActions,
}: Readonly<DynamicMarginCalculationFormProps>) {
const { formMethods, formSchema, paramsLoaded, formattedProviders, selectedTab, onTabChange, tabsWithError } =
dynamicMarginCalculationMethods;
return (
<CustomFormProvider validationSchema={formSchema} {...formMethods}>
{renderTitleFields?.()}
{paramsLoaded ? (
<Grid container sx={{ height: '100%' }} direction="column">
<Grid container>
<ProviderParam options={formattedProviders} />
</Grid>
<Grid>
<Tabs value={selectedTab} variant="scrollable" onChange={onTabChange} aria-label="parameters">
<Tab
label={<FormattedMessage id="DynamicMarginCalculationTimeDelayTab" />}
value={TabValues.TAB_TIME_DELAY}
sx={getTabStyle(tabsWithError, TabValues.TAB_TIME_DELAY)}
/>
<Tab
label={<FormattedMessage id="DynamicMarginCalculationLoadsVariationsTab" />}
value={TabValues.TAB_LOADS_VARIATIONS}
sx={getTabStyle(tabsWithError, TabValues.TAB_LOADS_VARIATIONS)}
/>
</Tabs>
</Grid>
<Grid
container
xs
key="dmcParameters"
sx={mergeSx(parametersStyles.scrollableGrid, {
paddingTop: 0,
width: '100%',
})}
>
<TabPanel value={selectedTab} index={TabValues.TAB_TIME_DELAY}>
<TimeDelayParameters path={TabValues.TAB_TIME_DELAY} />
</TabPanel>
<TabPanel value={selectedTab} index={TabValues.TAB_LOADS_VARIATIONS}>
<LoadsVariationsParameters path={TabValues.TAB_LOADS_VARIATIONS} />
</TabPanel>
</Grid>
{renderActions?.()}
</Grid>
) : (
<LinearProgress />
)}
</CustomFormProvider>
);
}
Loading
Loading