diff --git a/src/components/customAGGrid/index.ts b/src/components/customAGGrid/index.ts index cbcb26ef..b2a25f9a 100644 --- a/src/components/customAGGrid/index.ts +++ b/src/components/customAGGrid/index.ts @@ -7,3 +7,4 @@ export * from './customAggrid.style'; export * from './customAggrid'; +export * from './separatorCellRenderer'; diff --git a/src/components/customAGGrid/separatorCellRenderer.tsx b/src/components/customAGGrid/separatorCellRenderer.tsx new file mode 100644 index 00000000..f38d9f2b --- /dev/null +++ b/src/components/customAGGrid/separatorCellRenderer.tsx @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2025, 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 { Theme, Typography } from '@mui/material'; + +const styles = { + separator: (theme: Theme) => ({ + fontWeight: 'bold', + fontSize: '1rem', + width: '100%', + marginTop: theme.spacing(1), + }), +}; + +type SeparatorCellRendererProps = { + value: string; +}; + +export function SeparatorCellRenderer({ value }: Readonly) { + return ( + + {value} + + ); +} diff --git a/src/components/filter/expert/expertFilterUtils.ts b/src/components/filter/expert/expertFilterUtils.ts index 70b1f1a3..5f4ea7de 100644 --- a/src/components/filter/expert/expertFilterUtils.ts +++ b/src/components/filter/expert/expertFilterUtils.ts @@ -29,7 +29,7 @@ import { RuleGroupTypeExport, RuleTypeExport, } from './expertFilter.type'; -import { FIELDS_OPTIONS, OPERATOR_OPTIONS, RULES } from './expertFilterConstants'; +import { EXPERT_FILTER_EQUIPMENTS, FIELDS_OPTIONS, OPERATOR_OPTIONS, RULES } from './expertFilterConstants'; import { convertInputValue, convertOutputValue, isBlankOrEmpty } from '../../../utils/conversionUtils'; import { FieldType } from '../../../utils/types/fieldType'; @@ -524,3 +524,10 @@ export function recursiveRemove(query: RuleGroupTypeAny, path: number[]): RuleGr return remove(query, path); } + +export function getFilterEquipmentTypeLabel(equipmentType: string | undefined): string { + if (!equipmentType) { + return ''; + } + return EXPERT_FILTER_EQUIPMENTS[equipmentType as keyof typeof EXPERT_FILTER_EQUIPMENTS]?.label ?? ''; +} diff --git a/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx b/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx index d7bddddf..99b3b140 100644 --- a/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx +++ b/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx @@ -5,26 +5,25 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { Chip, FormControl, Grid, IconButton, Tooltip } from '@mui/material'; +import { Box, Chip, FormControl, FormHelperText, Grid, IconButton, Tooltip } from '@mui/material'; import { Folder as FolderIcon } from '@mui/icons-material'; import { useCallback, useMemo, useState } from 'react'; import { FieldValues, useController, useFieldArray } from 'react-hook-form'; -import { useIntl } from 'react-intl'; +import { FormattedMessage, useIntl } from 'react-intl'; import { UUID } from 'crypto'; import { RawReadOnlyInput } from './RawReadOnlyInput'; -import { FieldLabel } from './utils/FieldLabel'; -import { useCustomFormContext } from './provider/useCustomFormContext'; -import { isFieldRequired } from './utils/functions'; -import { ErrorInput } from './errorManagement/ErrorInput'; -import { useSnackMessage } from '../../../hooks/useSnackMessage'; +import { FieldLabel, isFieldRequired } from './utils'; +import { useCustomFormContext } from './provider'; +import { ErrorInput, MidFormError } from './errorManagement'; +import { useSnackMessage } from '../../../hooks'; import { TreeViewFinderNodeProps } from '../../treeViewFinder'; -import { mergeSx, type MuiStyles } from '../../../utils/styles'; +import { type MuiStyles } from '../../../utils/styles'; import { OverflowableText } from '../../overflowableText'; -import { MidFormError } from './errorManagement/MidFormError'; -import { DirectoryItemSelector } from '../../directoryItemSelector/DirectoryItemSelector'; +import { DirectoryItemSelector } from '../../directoryItemSelector'; import { fetchDirectoryElementPath } from '../../../services'; -import { ElementAttributes } from '../../../utils'; +import { ElementAttributes, mergeSx } from '../../../utils'; import { NAME } from './constants'; +import { getFilterEquipmentTypeLabel } from '../../filter/expert/expertFilterUtils'; const styles = { formDirectoryElements1: { @@ -67,6 +66,7 @@ export interface DirectoryItemsInputProps { disable?: boolean; allowMultiSelect?: boolean; labelRequiredFromContext?: boolean; + equipmentColorsMap?: Map; } export function DirectoryItemsInput({ @@ -82,6 +82,7 @@ export function DirectoryItemsInput({ disable = false, allowMultiSelect = true, labelRequiredFromContext = true, + equipmentColorsMap, }: Readonly) { const { snackError } = useSnackMessage(); const intl = useIntl(); @@ -94,7 +95,7 @@ export function DirectoryItemsInput({ fields: elements, append, remove, - } = useFieldArray({ + } = useFieldArray<{ [key: string]: TreeViewFinderNodeProps[] }>({ name, }); @@ -189,18 +190,44 @@ export function DirectoryItemsInput({ {elements?.length > 0 && ( {elements.map((item, index) => ( - removeElements(index)} - onClick={() => handleChipClick(index)} - label={ - } - sx={{ width: '100%' }} - /> - } - /> + sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column', gap: 1 }} + > + removeElements(index)} + onClick={() => handleChipClick(index)} + label={ + + ) : ( + intl.formatMessage({ id: 'elementNotFound' }) + ) + } + sx={{ width: '100%' }} + /> + } + /> + {equipmentColorsMap && ( + + {item?.specificMetadata?.equipmentType ? ( + + ) : ( + '' + )} + + )} + ))} )} diff --git a/src/components/treeViewFinder/TreeViewFinder.tsx b/src/components/treeViewFinder/TreeViewFinder.tsx index 0ebbc7c4..d66e3050 100644 --- a/src/components/treeViewFinder/TreeViewFinder.tsx +++ b/src/components/treeViewFinder/TreeViewFinder.tsx @@ -82,6 +82,9 @@ export interface TreeViewFinderNodeProps { childrenCount?: number; children?: TreeViewFinderNodeProps[]; parents?: TreeViewFinderNodeProps[]; + specificMetadata?: { + equipmentType: string; + }; } interface TreeViewFinderNodeMapProps { diff --git a/src/translations/en/filterEn.ts b/src/translations/en/filterEn.ts index 0bad46aa..92454495 100644 --- a/src/translations/en/filterEn.ts +++ b/src/translations/en/filterEn.ts @@ -57,4 +57,5 @@ export const filterEn = { nameAlreadyUsed: 'This name is already used', nameValidityCheckErrorMsg: 'Error while checking name validity', cantSubmitWhileValidating: 'Impossible to submit the form while validating a field', + elementNotFound: 'element not found', }; diff --git a/src/translations/fr/filterFr.ts b/src/translations/fr/filterFr.ts index b0845cc6..acad7ea0 100644 --- a/src/translations/fr/filterFr.ts +++ b/src/translations/fr/filterFr.ts @@ -57,4 +57,5 @@ export const filterFr = { nameAlreadyUsed: 'Ce nom est déjà utilisé', nameValidityCheckErrorMsg: 'Erreur lors de la vérification de la validité du nom', cantSubmitWhileValidating: "Impossible de soumettre le formulaire durant la validation d'un champ", + elementNotFound: 'Élément inexistant', }; diff --git a/src/utils/constants/fieldConstants.ts b/src/utils/constants/fieldConstants.ts index b79e2418..5adf9266 100644 --- a/src/utils/constants/fieldConstants.ts +++ b/src/utils/constants/fieldConstants.ts @@ -27,6 +27,7 @@ export enum FieldConstants { EQUIPMENT_TABLE = 'equipmentTable', EQUIPMENT_TYPE = 'equipmentType', FILTER_TYPE = 'filterType', + FILTERS = 'filters', FOLDER_ID = 'folderId', FOLDER_NAME = 'folderName', FORMATTED_CASE_PARAMETERS = 'formattedCaseParameters', @@ -37,6 +38,7 @@ export enum FieldConstants { NOMINAL_VOLTAGE_3 = 'nominalVoltage3', NOMINAL_VOLTAGE = 'nominalVoltage', OPERATION_TYPE = 'type', + TYPE = 'type', PROPERTY_NAME = 'propertyName', PROPERTY_OPERATOR = 'propertyOperator', PROPERTY = 'PROPERTY',