diff --git a/src/components/authentication/utils/userManagerMock.ts b/src/components/authentication/utils/userManagerMock.ts index 3ff604af..47531a41 100644 --- a/src/components/authentication/utils/userManagerMock.ts +++ b/src/components/authentication/utils/userManagerMock.ts @@ -20,14 +20,13 @@ import { } from 'oidc-client'; class Events implements UserManagerEvents { - userLoadedCallbacks: ((data: any) => void)[] = []; + userLoadedCallbacks: ((data: User) => void)[] = []; - addUserLoaded(callback: (data: any) => void) { + addUserLoaded(callback: (data: User) => void) { this.userLoadedCallbacks.push(callback); } - // eslint-disable-next-line - addSilentRenewError(callback: (data: any) => void) { + addSilentRenewError() { // Nothing to do } diff --git a/src/components/directoryItemSelector/DirectoryItemSelector.tsx b/src/components/directoryItemSelector/DirectoryItemSelector.tsx index 0b55d74f..a9f50045 100644 --- a/src/components/directoryItemSelector/DirectoryItemSelector.tsx +++ b/src/components/directoryItemSelector/DirectoryItemSelector.tsx @@ -65,7 +65,7 @@ function refreshedUpNodes( const parent = nodeMap[newElement.parentUuid]; const nextChildren = parent.children.map((c) => (c.elementUuid === newElement.elementUuid ? newElement : c)); const nextParent = { ...parent, children: nextChildren }; - return [newElement, ...refreshedUpNodes(nodeMap, nextParent)]; + return [newElement, ...refreshedUpNodes(nodeMap, nextParent as ElementAttributesBase)]; } /** @@ -148,19 +148,9 @@ function updatedTree( } export interface DirectoryItemSelectorProps extends TreeViewFinderProps { - open: boolean; types: string[]; equipmentTypes?: string[]; - itemFilter?: any; - classes?: any; - contentText?: string; - defaultExpanded?: string[]; - defaultSelected?: string[]; - validationButtonText?: string; - className?: string; - cancelButtonProps?: any; - onlyLeaves?: boolean; - multiselect?: boolean; + itemFilter?: (val: ElementAttributes) => boolean; expanded?: UUID[]; selected?: UUID[]; } @@ -196,7 +186,7 @@ export function DirectoryItemSelector({ const { snackError } = useSnackMessage(); const contentFilter = useCallback(() => new Set([ElementType.DIRECTORY, ...types]), [types]); - const convertChildren = useCallback((children: any[]): any[] => { + const convertChildren = useCallback((children: ElementAttributes[]): TreeViewFinderNodeProps[] => { return children.map((e) => { return { id: e.elementUuid, @@ -210,7 +200,7 @@ export function DirectoryItemSelector({ }, []); const convertRoots = useCallback( - (newRoots: ElementAttributes[]) => { + (newRoots: ElementAttributes[]): TreeViewFinderNodeProps[] => { return newRoots.map((e) => { return { id: e.elementUuid, @@ -258,16 +248,18 @@ export function DirectoryItemSelector({ const typeList = types.includes(ElementType.DIRECTORY) ? [] : types; fetchDirectoryContent(nodeId, typeList) .then((children) => { - const childrenMatchedTypes = children.filter((item: any) => contentFilter().has(item.type)); + const childrenMatchedTypes = children.filter((item: ElementAttributes) => + contentFilter().has(item.type) + ); if (childrenMatchedTypes.length > 0 && equipmentTypes && equipmentTypes.length > 0) { fetchElementsInfos( - childrenMatchedTypes.map((e: any) => e.elementUuid), + childrenMatchedTypes.map((e: ElementAttributes) => e.elementUuid), types, equipmentTypes - ).then((childrenWithMetadata) => { + ).then((childrenWithMetadata: ElementAttributes[]) => { const filtredChildren = itemFilter - ? childrenWithMetadata.filter((val: any) => { + ? childrenWithMetadata.filter((val: ElementAttributes) => { // Accept every directory if (val.type === ElementType.DIRECTORY) { return true; diff --git a/src/components/filter/FilterCreationDialog.tsx b/src/components/filter/FilterCreationDialog.tsx index 8207860b..ba417dd5 100644 --- a/src/components/filter/FilterCreationDialog.tsx +++ b/src/components/filter/FilterCreationDialog.tsx @@ -14,16 +14,17 @@ import { useSnackMessage } from '../../hooks/useSnackMessage'; import { CustomMuiDialog } from '../dialogs/customMuiDialog/CustomMuiDialog'; import { explicitNamingFilterSchema, - FILTER_EQUIPMENTS_ATTRIBUTES, getExplicitNamingFilterEmptyFormData, } from './explicitNaming/ExplicitNamingFilterForm'; import { FieldConstants } from '../../utils/constants/fieldConstants'; import yup from '../../utils/yupConfig'; import { FilterForm } from './FilterForm'; -import { EXPERT_FILTER_QUERY, expertFilterSchema, getExpertFilterEmptyFormData } from './expert/ExpertFilterForm'; +import { expertFilterSchema, getExpertFilterEmptyFormData } from './expert/ExpertFilterForm'; import { FilterType } from './constants/FilterConstants'; import { ElementExistsType } from '../../utils/types/elementType'; import { MAX_CHAR_DESCRIPTION } from '../../utils/constants/uiConstants'; +import { EXPERT_FILTER_QUERY } from './expert/expertFilterConstants'; +import { FILTER_EQUIPMENTS_ATTRIBUTES } from './explicitNaming/ExplicitNamingFilterConstants'; const emptyFormData = { [FieldConstants.NAME]: '', diff --git a/src/components/filter/expert/ExpertFilterEditionDialog.tsx b/src/components/filter/expert/ExpertFilterEditionDialog.tsx index 42ec88a5..6cec8456 100644 --- a/src/components/filter/expert/ExpertFilterEditionDialog.tsx +++ b/src/components/filter/expert/ExpertFilterEditionDialog.tsx @@ -17,9 +17,11 @@ import { FilterType, NO_ITEM_SELECTION_FOR_COPY } from '../constants/FilterConst import { FilterEditionProps } from '../filter.type'; import { FilterForm } from '../FilterForm'; import { saveExpertFilter } from '../utils/filterApi'; -import { EXPERT_FILTER_QUERY, expertFilterSchema } from './ExpertFilterForm'; +import { expertFilterSchema } from './ExpertFilterForm'; import { importExpertRules } from './expertFilterUtils'; import { HeaderFilterSchema } from '../HeaderFilterForm'; +import { catchErrorHandler } from '../../../services'; +import { EXPERT_FILTER_QUERY } from './expertFilterConstants'; const formSchema = yup .object() @@ -65,21 +67,23 @@ export function ExpertFilterEditionDialog({ if (id && open) { setDataFetchStatus(FetchStatus.FETCHING); getFilterById(id) - .then((response: { [prop: string]: any }) => { + .then((response) => { setDataFetchStatus(FetchStatus.FETCH_SUCCESS); reset({ [FieldConstants.NAME]: name, [FieldConstants.DESCRIPTION]: description, [FieldConstants.FILTER_TYPE]: FilterType.EXPERT.id, [FieldConstants.EQUIPMENT_TYPE]: response[FieldConstants.EQUIPMENT_TYPE], - [EXPERT_FILTER_QUERY]: importExpertRules(response[EXPERT_FILTER_QUERY]), + [EXPERT_FILTER_QUERY]: importExpertRules(response[EXPERT_FILTER_QUERY]!), }); }) - .catch((error: { message: any }) => { - setDataFetchStatus(FetchStatus.FETCH_ERROR); - snackError({ - messageTxt: error.message, - headerId: 'cannotRetrieveFilter', + .catch((error: unknown) => { + catchErrorHandler(error, (message: string) => { + setDataFetchStatus(FetchStatus.FETCH_ERROR); + snackError({ + messageTxt: message, + headerId: 'cannotRetrieveFilter', + }); }); }); } diff --git a/src/components/filter/expert/ExpertFilterForm.tsx b/src/components/filter/expert/ExpertFilterForm.tsx index 325354a7..9d6dcc08 100644 --- a/src/components/filter/expert/ExpertFilterForm.tsx +++ b/src/components/filter/expert/ExpertFilterForm.tsx @@ -19,6 +19,7 @@ import { COMBINATOR_OPTIONS, EXPERT_FILTER_EQUIPMENTS, EXPERT_FILTER_FIELDS, + EXPERT_FILTER_QUERY, OPERATOR_OPTIONS, RULES, } from './expertFilterConstants'; @@ -44,8 +45,6 @@ yup.setLocale({ }, }); -export const EXPERT_FILTER_QUERY = 'rules'; - function isSupportedEquipmentType(equipmentType: string): boolean { return Object.values(EXPERT_FILTER_EQUIPMENTS) .map((equipments) => equipments.id) diff --git a/src/components/filter/expert/expertFilterConstants.ts b/src/components/filter/expert/expertFilterConstants.ts index 8452eeaa..22f449e0 100644 --- a/src/components/filter/expert/expertFilterConstants.ts +++ b/src/components/filter/expert/expertFilterConstants.ts @@ -26,6 +26,8 @@ export enum RULES { BETWEEN_RULE = 'betweenRule', } +export const EXPERT_FILTER_QUERY = 'rules'; + export const EXPERT_FILTER_EQUIPMENTS = { SUBSTATION: { id: 'SUBSTATION', diff --git a/src/components/filter/explicitNaming/ExplicitNamingFilterConstants.ts b/src/components/filter/explicitNaming/ExplicitNamingFilterConstants.ts new file mode 100644 index 00000000..ea9ca22c --- /dev/null +++ b/src/components/filter/explicitNaming/ExplicitNamingFilterConstants.ts @@ -0,0 +1,8 @@ +/** + * Copyright (c) 2024, 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/. + */ + +export const FILTER_EQUIPMENTS_ATTRIBUTES = 'filterEquipmentsAttributes'; diff --git a/src/components/filter/explicitNaming/ExplicitNamingFilterEditionDialog.tsx b/src/components/filter/explicitNaming/ExplicitNamingFilterEditionDialog.tsx index 5c0399be..e536fc8f 100644 --- a/src/components/filter/explicitNaming/ExplicitNamingFilterEditionDialog.tsx +++ b/src/components/filter/explicitNaming/ExplicitNamingFilterEditionDialog.tsx @@ -15,13 +15,14 @@ import { FieldConstants } from '../../../utils/constants/fieldConstants'; import yup from '../../../utils/yupConfig'; import { CustomMuiDialog } from '../../dialogs/customMuiDialog/CustomMuiDialog'; import { saveExplicitNamingFilter } from '../utils/filterApi'; -import { explicitNamingFilterSchema, FILTER_EQUIPMENTS_ATTRIBUTES } from './ExplicitNamingFilterForm'; +import { explicitNamingFilterSchema } from './ExplicitNamingFilterForm'; import { FetchStatus } from '../../../utils/constants/fetchStatus'; import { FilterForm } from '../FilterForm'; import { FilterType, NO_ITEM_SELECTION_FOR_COPY } from '../constants/FilterConstants'; import { FilterEditionProps } from '../filter.type'; import { HeaderFilterSchema } from '../HeaderFilterForm'; +import { FILTER_EQUIPMENTS_ATTRIBUTES } from './ExplicitNamingFilterConstants'; const formSchema = yup .object() @@ -75,7 +76,7 @@ export function ExplicitNamingFilterEditionDialog({ [FieldConstants.DESCRIPTION]: description, [FieldConstants.FILTER_TYPE]: FilterType.EXPLICIT_NAMING.id, [FieldConstants.EQUIPMENT_TYPE]: response[FieldConstants.EQUIPMENT_TYPE], - [FILTER_EQUIPMENTS_ATTRIBUTES]: response[FILTER_EQUIPMENTS_ATTRIBUTES].map((row: any) => ({ + [FILTER_EQUIPMENTS_ATTRIBUTES]: response[FILTER_EQUIPMENTS_ATTRIBUTES]?.map((row: any) => ({ [FieldConstants.AG_GRID_ROW_UUID]: uuid4(), ...row, })), diff --git a/src/components/filter/explicitNaming/ExplicitNamingFilterForm.tsx b/src/components/filter/explicitNaming/ExplicitNamingFilterForm.tsx index f129e0b5..47b65175 100644 --- a/src/components/filter/explicitNaming/ExplicitNamingFilterForm.tsx +++ b/src/components/filter/explicitNaming/ExplicitNamingFilterForm.tsx @@ -27,8 +27,7 @@ import { ModifyElementSelection } from '../../dialogs/modifyElementSelection/Mod import { exportFilter } from '../../../services/study'; import { EquipmentType } from '../../../utils/types/equipmentType'; import { unscrollableDialogStyles } from '../../dialogs'; - -export const FILTER_EQUIPMENTS_ATTRIBUTES = 'filterEquipmentsAttributes'; +import { FILTER_EQUIPMENTS_ATTRIBUTES } from './ExplicitNamingFilterConstants'; function isGeneratorOrLoad(equipmentType: string): boolean { return equipmentType === Generator.type || equipmentType === Load.type; diff --git a/src/components/filter/explicitNaming/index.ts b/src/components/filter/explicitNaming/index.ts index 75eedca3..c7843b8b 100644 --- a/src/components/filter/explicitNaming/index.ts +++ b/src/components/filter/explicitNaming/index.ts @@ -6,3 +6,4 @@ */ export * from './ExplicitNamingFilterEditionDialog'; export * from './ExplicitNamingFilterForm'; +export * from './ExplicitNamingFilterConstants'; diff --git a/src/components/filter/filter.type.ts b/src/components/filter/filter.type.ts index 3ba8e434..f8ce5905 100644 --- a/src/components/filter/filter.type.ts +++ b/src/components/filter/filter.type.ts @@ -6,7 +6,10 @@ */ import { UUID } from 'crypto'; -import { ElementExistsType } from '../../utils'; +import { ElementExistsType, FieldConstants } from '../../utils'; +import { RuleGroupTypeExport } from './expert/expertFilter.type'; +import { EXPERT_FILTER_QUERY } from './expert/expertFilterConstants'; +import { FILTER_EQUIPMENTS_ATTRIBUTES } from './explicitNaming/ExplicitNamingFilterConstants'; /** * Represent an item/object in directories. @@ -20,6 +23,11 @@ export type ItemSelectionForCopy = { specificTypeItem: string | null; }; +type EquipmentsFilter = { + equipmentID: string; + distributionKey?: number; +}; + export interface FilterEditionProps { id: string; name: string; @@ -29,9 +37,21 @@ export interface FilterEditionProps { broadcastChannel: BroadcastChannel; itemSelectionForCopy: ItemSelectionForCopy; setItemSelectionForCopy: (selection: ItemSelectionForCopy) => void; - getFilterById: (id: string) => Promise<{ [prop: string]: any }>; + getFilterById: (id: string) => Promise<{ + [FieldConstants.EQUIPMENT_TYPE]: string; + [EXPERT_FILTER_QUERY]?: RuleGroupTypeExport; + [FILTER_EQUIPMENTS_ATTRIBUTES]?: EquipmentsFilter[]; + }>; activeDirectory?: UUID; elementExists?: ElementExistsType; language?: string; description?: string; } + +export interface NewFilterType { + id: string | null; + type: string; + equipmentType: string; + rules?: RuleGroupTypeExport; + filterEquipmentsAttributes?: EquipmentsFilter[]; +} diff --git a/src/components/filter/utils/filterApi.ts b/src/components/filter/utils/filterApi.ts index 960fb208..9ba2e9e8 100644 --- a/src/components/filter/utils/filterApi.ts +++ b/src/components/filter/utils/filterApi.ts @@ -11,6 +11,7 @@ import { Generator, Load } from '../../../utils/types/equipmentTypes'; import { exportExpertRules } from '../expert/expertFilterUtils'; import { DISTRIBUTION_KEY, FilterType } from '../constants/FilterConstants'; import { createFilter, saveFilter } from '../../../services/explore'; +import { catchErrorHandler } from '../../../services'; export const saveExplicitNamingFilter = ( tableValues: any[], @@ -40,6 +41,7 @@ export const saveExplicitNamingFilter = ( if (isFilterCreation) { createFilter( { + id: null, type: FilterType.EXPLICIT_NAMING.id, equipmentType, filterEquipmentsAttributes: cleanedTableValues, @@ -82,7 +84,7 @@ export const saveExpertFilter = ( name: string, description: string, isFilterCreation: boolean, - activeDirectory: any, + activeDirectory: UUID | undefined | null, onClose: () => void, onError: (message: string) => void, token?: string @@ -90,6 +92,7 @@ export const saveExpertFilter = ( if (isFilterCreation) { createFilter( { + id: null, type: FilterType.EXPERT.id, equipmentType, rules: exportExpertRules(query), @@ -102,8 +105,10 @@ export const saveExpertFilter = ( .then(() => { onClose(); }) - .catch((error: any) => { - onError(error.message); + .catch((error: unknown) => { + catchErrorHandler(error, (message: string) => { + onError(message); + }); }); } else { saveFilter( @@ -120,8 +125,10 @@ export const saveExpertFilter = ( .then(() => { onClose(); }) - .catch((error: any) => { - onError(error.message); + .catch((error: unknown) => { + catchErrorHandler(error, (message: string) => { + onError(message); + }); }); } }; diff --git a/src/components/flatParameters/FlatParameters.tsx b/src/components/flatParameters/FlatParameters.tsx index d7762760..9a3b84af 100644 --- a/src/components/flatParameters/FlatParameters.tsx +++ b/src/components/flatParameters/FlatParameters.tsx @@ -50,7 +50,7 @@ const IntegerRE = /^-?\d*$/; const ListRE = /^\[(.*)]$/; const sepRE = /[, ]/; -export function extractDefault(paramDescription: any) { +export function extractDefault(paramDescription: Parameter) { const d = paramDescription.defaultValue; if (paramDescription.type === 'BOOLEAN') { return !!d; @@ -95,7 +95,7 @@ export type Parameter = { type: 'BOOLEAN' | 'DOUBLE' | 'INTEGER' | 'STRING_LIST' | 'STRING'; description?: string; name: string; - possibleValues: any; + possibleValues: string[]; defaultValue: any; }; diff --git a/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx b/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx index 129c6212..8054678f 100644 --- a/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx +++ b/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx @@ -8,7 +8,7 @@ import { Chip, FormControl, Grid, IconButton, Theme, Tooltip } from '@mui/material'; import FolderIcon from '@mui/icons-material/Folder'; import { useCallback, useMemo, useState } from 'react'; -import { useController, useFieldArray } from 'react-hook-form'; +import { FieldValues, useController, useFieldArray } from 'react-hook-form'; import { useIntl } from 'react-intl'; import { UUID } from 'crypto'; import { RawReadOnlyInput } from './RawReadOnlyInput'; @@ -23,6 +23,7 @@ import { OverflowableText } from '../../overflowableText'; import { MidFormError } from './errorManagement/MidFormError'; import { DirectoryItemSelector } from '../../directoryItemSelector/DirectoryItemSelector'; import { fetchDirectoryElementPath } from '../../../services'; +import { ElementAttributes } from '../../../utils'; export const NAME = 'name'; @@ -59,7 +60,7 @@ export interface DirectoryItemsInputProps { name: string; elementType: string; equipmentTypes?: string[]; - itemFilter?: any; + itemFilter?: (val: ElementAttributes) => boolean; titleId?: string; hideErrorMessage?: boolean; onRowChanged?: (a: boolean) => void; @@ -113,14 +114,14 @@ export function DirectoryItemsInput({ // if we select a chip and return a new values, we remove it to be replaced if (selected?.length > 0 && values?.length > 0) { selected.forEach((chip) => { - remove(getValues(name).findIndex((item: any) => item.id === chip)); + remove(getValues(name).findIndex((item: FieldValues) => item.id === chip)); }); } values.forEach((value) => { const { icon, children, ...otherElementAttributes } = value; // Check if the element is already present - if (getValues(name).find((v: any) => v?.id === otherElementAttributes.id) !== undefined) { + if (getValues(name).find((v: FieldValues) => v?.id === otherElementAttributes.id) !== undefined) { snackError({ messageTxt: '', headerId: 'directory_items_input/ElementAlreadyUsed', @@ -148,10 +149,10 @@ export function DirectoryItemsInput({ const handleChipClick = useCallback( (index: number) => { - const chips = getValues(name) as any[]; + const chips = getValues(name); const chip = chips.at(index)?.id; if (chip) { - fetchDirectoryElementPath(chip).then((response: any[]) => { + fetchDirectoryElementPath(chip).then((response: ElementAttributes[]) => { const path = response.filter((e) => e.elementUuid !== chip).map((e) => e.elementUuid); setExpanded(path); diff --git a/src/components/inputs/reactHookForm/agGridTable/cellEditors/numericEditor.ts b/src/components/inputs/reactHookForm/agGridTable/cellEditors/numericEditor.ts index e4d8cb9a..37f284cd 100644 --- a/src/components/inputs/reactHookForm/agGridTable/cellEditors/numericEditor.ts +++ b/src/components/inputs/reactHookForm/agGridTable/cellEditors/numericEditor.ts @@ -56,11 +56,11 @@ export class NumericEditor implements ICellEditorComp { this.cancelBeforeStart = !!isNotANumber; } - static isBackspace(event: any) { + static isBackspace(event: KeyboardEvent) { return event.key === KEY_BACKSPACE; } - static isNavigationKey(event: any) { + static isNavigationKey(event: KeyboardEvent) { return event.key === 'ArrowLeft' || event.key === 'ArrowRight'; } @@ -92,7 +92,7 @@ export class NumericEditor implements ICellEditorComp { return charStr && !!/\d|,|\./.test(charStr); } - static isNumericKey(event: any) { + static isNumericKey(event: KeyboardEvent) { const charStr = event.key; return NumericEditor.isCharNumeric(charStr); } diff --git a/src/components/inputs/reactHookForm/agGridTable/csvUploader/CsvUploader.tsx b/src/components/inputs/reactHookForm/agGridTable/csvUploader/CsvUploader.tsx index 69cba501..75cc1b4f 100644 --- a/src/components/inputs/reactHookForm/agGridTable/csvUploader/CsvUploader.tsx +++ b/src/components/inputs/reactHookForm/agGridTable/csvUploader/CsvUploader.tsx @@ -25,7 +25,7 @@ import { CancelButton } from '../../utils/CancelButton'; export interface CsvUploaderProps { name: string; onClose: () => void; - open: true; + open: boolean; title: string[]; fileHeaders: string[]; fileName: string; diff --git a/src/components/inputs/reactHookForm/booleans/BooleanInput.tsx b/src/components/inputs/reactHookForm/booleans/BooleanInput.tsx index 552ef68a..f749a7e5 100644 --- a/src/components/inputs/reactHookForm/booleans/BooleanInput.tsx +++ b/src/components/inputs/reactHookForm/booleans/BooleanInput.tsx @@ -7,13 +7,13 @@ import { ChangeEvent, useCallback } from 'react'; import { useIntl } from 'react-intl'; -import { Checkbox, FormControlLabel, Switch } from '@mui/material'; +import { Checkbox, CheckboxProps, FormControlLabel, Switch, SwitchProps } from '@mui/material'; import { useController } from 'react-hook-form'; export interface BooleanInputProps { name: string; label?: string; - formProps?: any; + formProps?: SwitchProps | CheckboxProps; Input: typeof Switch | typeof Checkbox; } diff --git a/src/components/inputs/reactHookForm/numbers/RangeInput.tsx b/src/components/inputs/reactHookForm/numbers/RangeInput.tsx index 9c380f6d..248d4678 100644 --- a/src/components/inputs/reactHookForm/numbers/RangeInput.tsx +++ b/src/components/inputs/reactHookForm/numbers/RangeInput.tsx @@ -9,13 +9,14 @@ import { FormattedMessage } from 'react-intl'; import { useMemo } from 'react'; import { type ObjectSchema } from 'yup'; import { FormControl, Grid, InputLabel } from '@mui/material'; +import { Theme } from '@mui/system'; import { FloatInput } from './FloatInput'; import yup from '../../../../utils/yupConfig'; import { MuiSelectInput } from '../selectInputs/MuiSelectInput'; import { FieldConstants } from '../../../../utils/constants/fieldConstants'; const style = { - inputLegend: (theme: any) => ({ + inputLegend: (theme: Theme) => ({ backgroundImage: 'linear-gradient(rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.16))', backgroundColor: theme.palette.background.paper, padding: '0 8px 0 8px', diff --git a/src/components/inputs/reactHookForm/numbers/SliderInput.tsx b/src/components/inputs/reactHookForm/numbers/SliderInput.tsx index bd0ee17c..79055f07 100644 --- a/src/components/inputs/reactHookForm/numbers/SliderInput.tsx +++ b/src/components/inputs/reactHookForm/numbers/SliderInput.tsx @@ -11,7 +11,7 @@ import { identity } from '../utils/functions'; export interface SliderInputProps extends SliderProps { name: string; - onValueChanged: (value: any) => void; + onValueChanged: (value: number | number[]) => void; } export function SliderInput({ name, min, max, step, size = 'small', onValueChanged = identity }: SliderInputProps) { diff --git a/src/components/inputs/reactHookForm/text/TextInput.tsx b/src/components/inputs/reactHookForm/text/TextInput.tsx index 61ccb5a6..a654b505 100644 --- a/src/components/inputs/reactHookForm/text/TextInput.tsx +++ b/src/components/inputs/reactHookForm/text/TextInput.tsx @@ -67,7 +67,7 @@ export function TextInput({ onChange(outputTransform('')); }; - const handleValueChanged = (e: any) => { + const handleValueChanged = (e: React.ChangeEvent) => { if (acceptValue(e.target.value)) { onChange(outputTransform(e.target.value)); } diff --git a/src/components/inputs/reactQueryBuilder/CountryValueEditor.tsx b/src/components/inputs/reactQueryBuilder/CountryValueEditor.tsx index 8f8da5ae..2a94ca9c 100644 --- a/src/components/inputs/reactQueryBuilder/CountryValueEditor.tsx +++ b/src/components/inputs/reactQueryBuilder/CountryValueEditor.tsx @@ -48,7 +48,7 @@ export function CountryValueEditor(props: ValueEditorProps) { getOptionLabel={(code: string) => (code ? translate(code) : '')} valid={valid} title={title} - onChange={(event: SyntheticEvent, newValue: any) => { + onChange={(event: SyntheticEvent, newValue) => { handleOnChange(newValue); }} fullWidth diff --git a/src/components/inputs/reactQueryBuilder/ElementValueEditor.tsx b/src/components/inputs/reactQueryBuilder/ElementValueEditor.tsx index 586336de..91b1ac17 100644 --- a/src/components/inputs/reactQueryBuilder/ElementValueEditor.tsx +++ b/src/components/inputs/reactQueryBuilder/ElementValueEditor.tsx @@ -10,6 +10,7 @@ import { useEffect } from 'react'; import { useCustomFormContext } from '../reactHookForm/provider/useCustomFormContext'; import { fetchElementsInfos } from '../../../services'; import { DirectoryItemsInput } from '../reactHookForm/DirectoryItemsInput'; +import { ElementAttributes } from '../../../utils'; interface ElementValueEditorProps { name: string; @@ -18,7 +19,7 @@ interface ElementValueEditorProps { titleId: string; hideErrorMessage: boolean; onChange?: (e: any) => void; - itemFilter?: any; + itemFilter?: (val: ElementAttributes) => boolean; defaultValue?: any; } @@ -37,7 +38,7 @@ export function ElementValueEditor(props: ElementValueEditorProps) { fetchElementsInfos(defaultValue).then((childrenWithMetadata) => { setValue( name, - childrenWithMetadata.map((v: any) => { + childrenWithMetadata.map((v: ElementAttributes) => { return { id: v.elementUuid, name: v.elementName, diff --git a/src/components/inputs/reactQueryBuilder/PropertyValueEditor.tsx b/src/components/inputs/reactQueryBuilder/PropertyValueEditor.tsx index eddf6cf3..70eb3f50 100644 --- a/src/components/inputs/reactQueryBuilder/PropertyValueEditor.tsx +++ b/src/components/inputs/reactQueryBuilder/PropertyValueEditor.tsx @@ -80,7 +80,7 @@ export function PropertyValueEditor(props: ExpertFilterPropertyProps) { autoSelect forcePopupIcon renderInput={(params) => } - onChange={(event, value: any) => { + onChange={(event, value) => { onChange(FieldConstants.PROPERTY_NAME, value); }} size="small" @@ -92,7 +92,7 @@ export function PropertyValueEditor(props: ExpertFilterPropertyProps) { size="small" title={valueEditorProps?.title} error={!valid} - onChange={(event, value: any) => { + onChange={(event, value) => { onChange(FieldConstants.PROPERTY_OPERATOR, value); }} > @@ -112,7 +112,7 @@ export function PropertyValueEditor(props: ExpertFilterPropertyProps) { renderInput={(params) => } freeSolo autoSelect - onChange={(event, value: any) => { + onChange={(event, value) => { onChange(FieldConstants.PROPERTY_VALUES, value); }} size="small" diff --git a/src/components/inputs/reactQueryBuilder/TranslatedValueEditor.tsx b/src/components/inputs/reactQueryBuilder/TranslatedValueEditor.tsx index c9b255c5..05883e26 100644 --- a/src/components/inputs/reactQueryBuilder/TranslatedValueEditor.tsx +++ b/src/components/inputs/reactQueryBuilder/TranslatedValueEditor.tsx @@ -47,7 +47,7 @@ export function TranslatedValueEditor(props: ValueEditorProps) { options={Object.keys(translatedValuesAutocomplete)} title={title} getOptionLabel={(code: string) => translatedValuesAutocomplete[code]} - onChange={(event, newValue: any) => handleOnChange(newValue)} + onChange={(event, newValue) => handleOnChange(newValue)} multiple fullWidth renderInput={(params) => } diff --git a/src/components/inputs/reactQueryBuilder/ValueEditor.tsx b/src/components/inputs/reactQueryBuilder/ValueEditor.tsx index a3a45a0e..fbc09d93 100644 --- a/src/components/inputs/reactQueryBuilder/ValueEditor.tsx +++ b/src/components/inputs/reactQueryBuilder/ValueEditor.tsx @@ -24,6 +24,7 @@ import { FilterType } from '../../filter/constants/FilterConstants'; import { GroupValueEditor } from './compositeRuleEditor/GroupValueEditor'; import { OPERATOR_OPTIONS } from '../../filter/expert/expertFilterConstants'; import { FieldType } from '../../../utils/types/fieldType'; +import { ElementAttributes } from '../../../utils'; const styles = { noArrows: { @@ -41,7 +42,7 @@ export function ValueEditor(props: ValueEditorProps) { const formContext = useFormContext(); const { getValues } = formContext; const itemFilter = useCallback( - (filterValue: any) => { + (filterValue: ElementAttributes) => { if (filterValue?.type === ElementType.FILTER) { return ( // we do not authorize to use an expert filter in the rules of diff --git a/src/components/notifications/hooks/useNotificationsListener.ts b/src/components/notifications/hooks/useNotificationsListener.ts index 4b80f448..f0279bc0 100644 --- a/src/components/notifications/hooks/useNotificationsListener.ts +++ b/src/components/notifications/hooks/useNotificationsListener.ts @@ -17,7 +17,7 @@ export const useNotificationsListener = ( listenerCallbackOnReopen, propsId, }: { - listenerCallbackMessage?: (event: MessageEvent) => void; + listenerCallbackMessage?: (event: MessageEvent) => void; listenerCallbackOnReopen?: () => void; propsId?: string; } diff --git a/src/components/treeViewFinder/TreeViewFinder.tsx b/src/components/treeViewFinder/TreeViewFinder.tsx index e3160048..7117d188 100644 --- a/src/components/treeViewFinder/TreeViewFinder.tsx +++ b/src/components/treeViewFinder/TreeViewFinder.tsx @@ -160,7 +160,7 @@ function TreeViewFinderComponant(props: TreeViewFinderProps) { // Controlled selected for TreeView const [selected, setSelected] = useState(defaultSelected ?? []); - const scrollRef = useRef([]); + const scrollRef = useRef<(HTMLLIElement | null)[]>([]); const [autoScrollAllowed, setAutoScrollAllowed] = useState(true); /* Utilities */ diff --git a/src/hooks/useSnackMessage.ts b/src/hooks/useSnackMessage.ts index 11ffb364..e71166d0 100644 --- a/src/hooks/useSnackMessage.ts +++ b/src/hooks/useSnackMessage.ts @@ -13,7 +13,7 @@ import { useIntlRef } from './useIntlRef'; interface SnackInputs extends Omit { messageTxt?: string; messageId?: string; - messageValues?: { [key: string]: string }; + messageValues?: Record; headerTxt?: string; headerId?: string; headerValues?: Record; @@ -26,13 +26,18 @@ export interface UseSnackMessageReturn { closeSnackbar: typeof closeSnackbarFromNotistack; } -function checkInputs(txt?: string, id?: string, values?: any) { +function checkInputs(txt?: string, id?: string, values?: SnackInputs['messageValues']) { if (txt && (id || values)) { console.warn('Snack inputs should be [*Txt] OR [*Id, *Values]'); } } -function checkAndTranslateIfNecessary(intlRef: MutableRefObject, txt?: string, id?: string, values?: any) { +function checkAndTranslateIfNecessary( + intlRef: MutableRefObject, + txt?: string, + id?: string, + values?: SnackInputs['messageValues'] +) { checkInputs(txt, id, values); return ( txt ?? diff --git a/src/module-mui.d.ts b/src/module-mui.d.ts index eb2d1037..b3063960 100644 --- a/src/module-mui.d.ts +++ b/src/module-mui.d.ts @@ -4,6 +4,7 @@ * 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 '@mui/material/Switch'; // used to customize mui theme // https://mui.com/material-ui/customization/theming/#typescript @@ -19,3 +20,9 @@ declare module '@mui/material/styles/createTheme' { }; } } + +declare module '@mui/material/Switch' { + interface SwitchPropsSizeOverrides { + large: true; + } +} diff --git a/src/services/explore.ts b/src/services/explore.ts index 0e0fc8e5..d25268e4 100644 --- a/src/services/explore.ts +++ b/src/services/explore.ts @@ -8,14 +8,15 @@ import { UUID } from 'crypto'; import { backendFetch, backendFetchJson, getRequestParamFromList } from './utils'; import { ElementAttributes } from '../utils/types/types'; +import { NewFilterType } from '../components/filter/filter.type'; const PREFIX_EXPLORE_SERVER_QUERIES = `${import.meta.env.VITE_API_GATEWAY}/explore`; export function createFilter( - newFilter: any, + newFilter: NewFilterType, name: string, description: string, - parentDirectoryUuid?: UUID, + parentDirectoryUuid: UUID | undefined | null, token?: string ) { const urlSearchParams = new URLSearchParams(); @@ -35,7 +36,7 @@ export function createFilter( ); } -export function saveFilter(filter: any, name: string, description: string, token?: string) { +export function saveFilter(filter: NewFilterType, name: string, description: string, token?: string) { const urlSearchParams = new URLSearchParams(); urlSearchParams.append('name', name); urlSearchParams.append('description', description); diff --git a/src/services/utils.ts b/src/services/utils.ts index be4fd8df..2709af49 100644 --- a/src/services/utils.ts +++ b/src/services/utils.ts @@ -7,6 +7,13 @@ import { getUserToken } from '../redux/commonStore'; +export interface BackendFetchInit { + method: string; + headers?: HeadersInit; + body?: string | FormData; + signal?: AbortSignal; +} + const parseError = (text: string) => { try { return JSON.parse(text); @@ -15,7 +22,7 @@ const parseError = (text: string) => { } }; -const prepareRequest = (init: any, token?: string) => { +const prepareRequest = (init: BackendFetchInit, token?: string) => { if (!(typeof init === 'undefined' || typeof init === 'object')) { throw new TypeError(`First argument of prepareRequest is not an object : ${typeof init}`); } @@ -26,7 +33,7 @@ const prepareRequest = (init: any, token?: string) => { return initCopy; }; -const handleError = (response: any) => { +const handleError = (response: Response) => { return response.text().then((text: string) => { const errorName = 'HttpResponseError : '; const errorJson = parseError(text); @@ -38,22 +45,22 @@ const handleError = (response: any) => { customError.status = errorJson.status; } else { customError = new Error(`${errorName + response.status} ${response.statusText}, message : ${text}`); - customError.status = response.status; + customError.status = response.statusText; } throw customError; }); }; -const safeFetch = (url: string, initCopy: any) => { +const safeFetch = (url: string, initCopy: BackendFetchInit) => { return fetch(url, initCopy).then((response) => (response.ok ? response : handleError(response))); }; -export const backendFetch = (url: string, init: any, token?: string) => { +export const backendFetch = (url: string, init: BackendFetchInit, token?: string) => { const initCopy = prepareRequest(init, token); return safeFetch(url, initCopy); }; -export const backendFetchJson = (url: string, init: any, token?: string) => { +export const backendFetchJson = (url: string, init: BackendFetchInit, token?: string) => { const initCopy = prepareRequest(init, token); return safeFetch(url, initCopy).then((safeResponse) => (safeResponse.status === 204 ? null : safeResponse.json())); }; diff --git a/src/utils/algos.ts b/src/utils/algos.ts index 0d00e7d6..d1f04344 100644 --- a/src/utils/algos.ts +++ b/src/utils/algos.ts @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -export function equalsArray(a: Array, b: Array) { +export function equalsArray(a: T[] | null, b: T[]) { if (b === a) { return true; } @@ -17,11 +17,14 @@ export function equalsArray(a: Array, b: Array) { } for (let i = 0, l = a.length; i < l; i++) { - if (a[i] instanceof Array && b[i] instanceof Array) { - if (!equalsArray(a[i], b[i])) { + const newA = a[i]; + const newB = b[i]; + + if (newA instanceof Array && newB instanceof Array) { + if (!equalsArray(newA, newB)) { return false; } - } else if (a[i] !== b[i]) { + } else if (newA !== newB) { // Warning - two different object instances will never be equal: {x:20} != {x:20} return false; } diff --git a/src/utils/types/types.ts b/src/utils/types/types.ts index 367d2cd6..477782d5 100644 --- a/src/utils/types/types.ts +++ b/src/utils/types/types.ts @@ -24,9 +24,14 @@ export type ElementAttributes = { lastModificationDate: string; lastModifiedBy: string; // id lastModifiedByLabel?: string; // enrich with user identity server - children: any[]; + children: ElementAttributes[]; parentUuid: null | UUID; - specificMetadata: Record; + specificMetadata: { + type: string; + equipmentType: string; + sheetType?: string; + format?: string; + }; uploading?: boolean; hasMetadata?: boolean; subtype?: string;