diff --git a/src/components/app-wrapper.jsx b/src/components/app-wrapper.jsx index 7a4c31b376..06c3264b8b 100644 --- a/src/components/app-wrapper.jsx +++ b/src/components/app-wrapper.jsx @@ -219,6 +219,9 @@ const lightTheme = createTheme({ }, highlightColor: '#1976D214', }, + agGridBackground: { + color: 'white', + }, networkModificationPanel: { backgroundColor: 'white', border: 'solid 1px #babfc7', @@ -335,6 +338,9 @@ const darkTheme = createTheme({ }, highlightColor: '#90CAF929', }, + agGridBackground: { + color: '#383838', + }, networkModificationPanel: { backgroundColor: '#252525', border: 'solid 1px #68686e', diff --git a/src/components/dialogs/network-modifications/tabular/tabular-dialog.tsx b/src/components/dialogs/network-modifications/tabular/tabular-dialog.tsx index 4088377b03..645fee318c 100644 --- a/src/components/dialogs/network-modifications/tabular/tabular-dialog.tsx +++ b/src/components/dialogs/network-modifications/tabular/tabular-dialog.tsx @@ -6,12 +6,19 @@ */ import { yupResolver } from '@hookform/resolvers/yup'; -import { CustomFormProvider, ModificationType, snackWithFallback, useSnackMessage } from '@gridsuite/commons-ui'; +import { + CustomFormProvider, + FieldConstants, + ModificationType, + snackWithFallback, + useSnackMessage, +} from '@gridsuite/commons-ui'; +import { v4 as uuid4 } from 'uuid'; import { useForm } from 'react-hook-form'; import { useCallback, useEffect, useMemo } from 'react'; import { useOpenShortWaitFetching } from 'components/dialogs/commons/handle-modification-form.js'; import { FORM_LOADING_DELAY } from 'components/network/constants.js'; -import { TABULAR_PROPERTIES, MODIFICATIONS_TABLE, CSV_FILENAME, TYPE } from 'components/utils/field-constants.js'; +import { CSV_FILENAME, MODIFICATIONS_TABLE, TABULAR_PROPERTIES, TYPE } from 'components/utils/field-constants.js'; import { ModificationDialog } from 'components/dialogs/commons/modificationDialog.js'; import { createTabularModification } from 'services/study/network-modifications.js'; import { FetchStatus } from 'services/utils.type'; @@ -111,6 +118,7 @@ export function TabularDialog({ } } modification = addPropertiesFromBack(modification, modif?.[TABULAR_PROPERTIES]); + modification[FieldConstants.AG_GRID_ROW_UUID] = uuid4(); return modification; }); reset({ @@ -126,7 +134,10 @@ export function TabularDialog({ const initTabularCreationData = useCallback( (editData: TabularModificationEditDataType) => { const equipmentType = getEquipmentTypeFromCreationType(editData?.modificationType); - const creations = convertCreations(editData?.modifications); + const creations = convertCreations(editData?.modifications).map((creation) => ({ + ...creation, + [FieldConstants.AG_GRID_ROW_UUID]: uuid4(), + })); reset({ [TYPE]: equipmentType, [MODIFICATIONS_TABLE]: creations, @@ -241,6 +252,7 @@ export function TabularDialog({ titleId={dialogMode === TabularModificationType.CREATION ? 'TabularCreation' : 'TabularModification'} open={open} isDataFetching={dataFetching} + slotProps={{ paper: { sx: { height: '83vh' } } }} {...dialogProps} > diff --git a/src/components/dialogs/network-modifications/tabular/tabular-form.tsx b/src/components/dialogs/network-modifications/tabular/tabular-form.tsx index b8b12ac627..f9ef19ed47 100644 --- a/src/components/dialogs/network-modifications/tabular/tabular-form.tsx +++ b/src/components/dialogs/network-modifications/tabular/tabular-form.tsx @@ -5,27 +5,27 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; -import { useFormContext, useWatch } from 'react-hook-form'; +import { type FieldValues, type UseFieldArrayReturn, useFormContext, useWatch } from 'react-hook-form'; import { AutocompleteInput, - BooleanNullableCellRenderer, - CustomAGGrid, + CustomAgGridTable, DefaultCellRenderer, DirectoryItemSelector, ElementType, EquipmentType, - ErrorInput, fetchStudyMetadata, - FieldErrorAlert, + FieldConstants, getObjectId, LANG_FRENCH, type MuiStyles, + NumericEditor, type TreeViewFinderNodeProps, useSnackMessage, useStateBoolean, } from '@gridsuite/commons-ui'; +import { v4 as uuid4 } from 'uuid'; import { CSV_FILENAME, EQUIPMENT_ID, @@ -53,7 +53,7 @@ import { transformIfFrenchNumber, } from './tabular-common'; import { ColDef } from 'ag-grid-community'; -import { BOOLEAN } from '../../../network/constants'; +import { ENUM, NUMBER } from '../../../network/constants'; import { TABULAR_CREATION_FIELDS } from './tabular-creation-utils'; import { TABULAR_MODIFICATION_FIELDS } from './tabular-modification-utils'; import { useFilterCsvGenerator } from './use-filter-csv-generator'; @@ -75,6 +75,7 @@ export function TabularForm({ dataFetching, dialogMode }: Readonly(dataFetching); const { setValue, clearErrors, setError } = useFormContext(); + const tableRef = useRef>(null); const propertiesDialogOpen = useStateBoolean(false); const generateFromFilterOpen = useStateBoolean(false); const prefilledModelDialogOpen = useStateBoolean(false); @@ -91,9 +92,6 @@ export function TabularForm({ dataFetching, dialogMode }: Readonly ({ + ...row, + [FieldConstants.AG_GRID_ROW_UUID]: uuid4(), + })); + tableRef.current?.replace(rowsWithUuid); setValue(CSV_FILENAME, selectedFile?.name); } else { // If the file is undefined we don't update the values because it's outdated - setValue(MODIFICATIONS_TABLE, []); + tableRef.current?.replace([]); setValue(CSV_FILENAME, undefined); } setIsFetching(false); @@ -336,7 +338,7 @@ export function TabularForm({ dataFetching, dialogMode }: Readonly { if (selectedFileError) { - setValue(MODIFICATIONS_TABLE, []); + tableRef.current?.replace([]); setValue(CSV_FILENAME, undefined); clearErrors(MODIFICATIONS_TABLE); setIsFetching(false); @@ -373,7 +375,7 @@ export function TabularForm({ dataFetching, dialogMode }: Readonly { setTypeChangedTrigger(!typeChangedTrigger); clearErrors(MODIFICATIONS_TABLE); - setValue(MODIFICATIONS_TABLE, []); + tableRef.current?.replace([]); setValue(CSV_FILENAME, undefined); setValue(TABULAR_PROPERTIES, []); resetFile(); @@ -406,26 +408,50 @@ export function TabularForm({ dataFetching, dialogMode }: Readonly { return csvFields .map((field) => { - const columnDef: ColDef = {}; + const columnDef: ColDef = { + field: field.id, + headerName: intl.formatMessage({ id: field.id }) + (field.required ? ' (*)' : ''), + editable: true, + singleClickEdit: true, + }; if (field.id === EQUIPMENT_ID) { columnDef.pinned = true; + columnDef.rowDrag = true; + } + switch (field.type) { + case NUMBER: + columnDef.cellEditor = NumericEditor; + break; + case ENUM: + columnDef.cellEditor = 'agSelectCellEditor'; + columnDef.cellEditorParams = { values: [null, ...(field.options ?? [])] }; + break; + default: + break; } - columnDef.field = field.id; - columnDef.headerName = intl.formatMessage({ id: field.id }) + (field.required ? ' (*)' : ''); - columnDef.cellRenderer = field.type === BOOLEAN ? BooleanNullableCellRenderer : DefaultCellRenderer; return columnDef; }) .concat( - selectedProperties.map((propertyName: string) => { - const columnDef: ColDef = {}; - columnDef.field = PROPERTY_CSV_COLUMN_PREFIX + propertyName; - columnDef.headerName = propertyName; - columnDef.cellRenderer = DefaultCellRenderer; - return columnDef; - }) + selectedProperties.map((propertyName: string) => ({ + field: PROPERTY_CSV_COLUMN_PREFIX + propertyName, + headerName: propertyName, + editable: true, + singleClickEdit: true, + })) ); }, [csvFields, selectedProperties, intl]); + const makeDefaultRowData = useCallback(() => { + const row: Record = { [FieldConstants.AG_GRID_ROW_UUID]: uuid4() }; + csvFields.forEach((field) => { + row[field.id] = null; + }); + selectedProperties.forEach((propertyName) => { + row[PROPERTY_CSV_COLUMN_PREFIX + propertyName] = ''; + }); + return row; + }, [csvFields, selectedProperties]); + const onPropertiesChange = (formData: PropertiesFormType) => { const newSelectedProperties = formData[TABULAR_PROPERTIES]?.filter((property: TabularProperty) => property.selected)?.map( @@ -434,7 +460,7 @@ export function TabularForm({ dataFetching, dialogMode }: Readonly reset table clearErrors(MODIFICATIONS_TABLE); - setValue(MODIFICATIONS_TABLE, []); + tableRef.current?.replace([]); setValue(CSV_FILENAME, undefined); } setValue(TABULAR_PROPERTIES, formData[TABULAR_PROPERTIES], { shouldDirty: true }); @@ -509,21 +535,27 @@ export function TabularForm({ dataFetching, dialogMode }: Readonly )} - - - {selectedFileError && {selectedFileError}} - + {selectedFileError && ( + + {selectedFileError} + + )} -