Skip to content

Commit

Permalink
Allow editing description from filter edition dialogs (#660)
Browse files Browse the repository at this point in the history
* Allow editing description from filter edition dialogs

Signed-off-by: basseche <[email protected]>
  • Loading branch information
basseche authored Jan 9, 2025
1 parent 26cd310 commit db1cdc3
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { FieldConstants } from '../../../utils/constants/fieldConstants';
import { useSnackMessage } from '../../../hooks/useSnackMessage';
import { CustomMuiDialog } from '../customMuiDialog/CustomMuiDialog';
import { ExpandingTextField } from '../../inputs/reactHookForm/text/ExpandingTextField';
import { MAX_CHAR_DESCRIPTION } from '../../../utils/constants/uiConstants';

export interface DescriptionModificationDialogProps {
elementUuid: string;
Expand All @@ -24,7 +25,7 @@ export interface DescriptionModificationDialogProps {
}

const schema = yup.object().shape({
[FieldConstants.DESCRIPTION]: yup.string().max(500, 'descriptionLimitError'),
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION, 'descriptionLimitError'),
});
type SchemaType = yup.InferType<typeof schema>;

Expand Down
3 changes: 2 additions & 1 deletion src/components/filter/FilterCreationDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { FilterForm } from './FilterForm';
import { EXPERT_FILTER_QUERY, expertFilterSchema, getExpertFilterEmptyFormData } from './expert/ExpertFilterForm';
import { FilterType } from './constants/FilterConstants';
import { ElementExistsType } from '../../utils/types/elementType';
import { MAX_CHAR_DESCRIPTION } from '../../utils/constants/uiConstants';

const emptyFormData = {
[FieldConstants.NAME]: '',
Expand All @@ -38,7 +39,7 @@ const formSchema = yup
.object()
.shape({
[FieldConstants.NAME]: yup.string().trim().required('nameEmpty'),
[FieldConstants.DESCRIPTION]: yup.string().max(500, 'descriptionLimitError'),
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION, 'descriptionLimitError'),
[FieldConstants.FILTER_TYPE]: yup.string().required(),
[FieldConstants.EQUIPMENT_TYPE]: yup.string().required(),
...explicitNamingFilterSchema,
Expand Down
37 changes: 22 additions & 15 deletions src/components/filter/HeaderFilterForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { UniqueNameInput } from '../inputs/reactHookForm/text/UniqueNameInput';
import { ElementExistsType, ElementType } from '../../utils/types/elementType';
import { DescriptionField } from '../inputs/reactHookForm/text/DescriptionField';
import { RadioInput } from '../inputs/reactHookForm/booleans/RadioInput';
import yup from '../../utils/yupConfig';
import { MAX_CHAR_DESCRIPTION } from '../../utils/constants/uiConstants';

export interface FilterFormProps {
creation?: boolean;
Expand All @@ -25,6 +27,13 @@ export interface FilterFormProps {
handleFilterTypeChange?: (event: React.ChangeEvent<HTMLInputElement>, value: string) => void;
}

export const HeaderFilterSchema = {
[FieldConstants.NAME]: yup.string().trim().required('nameEmpty'),
[FieldConstants.FILTER_TYPE]: yup.string().required(),
[FieldConstants.EQUIPMENT_TYPE]: yup.string().required(),
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION, 'descriptionLimitError'),
};

export function HeaderFilterForm({
sourceFilterForExplicitNamingConversion,
creation,
Expand All @@ -46,22 +55,20 @@ export function HeaderFilterForm({
elementExists={elementExists}
/>
</Grid>
{creation && (
<>
<Grid item xs={12}>
<DescriptionField />
<>
<Grid item xs={12}>
<DescriptionField />
</Grid>
{creation && !sourceFilterForExplicitNamingConversion && (
<Grid item>
<RadioInput
name={FieldConstants.FILTER_TYPE}
options={filterTypes}
formProps={{ onChange: handleFilterTypeChange }} // need to override this in order to do not activate the validate button when changing the filter type
/>
</Grid>
{!sourceFilterForExplicitNamingConversion && (
<Grid item>
<RadioInput
name={FieldConstants.FILTER_TYPE}
options={filterTypes}
formProps={{ onChange: handleFilterTypeChange }} // need to override this in order to do not activate the validate button when changing the filter type
/>
</Grid>
)}
</>
)}
)}
</>
</Grid>
);
}
32 changes: 8 additions & 24 deletions src/components/filter/expert/ExpertFilterEditionDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,29 @@
*/

import { yupResolver } from '@hookform/resolvers/yup';
import { UUID } from 'crypto';
import { useCallback, useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { useSnackMessage } from '../../../hooks/useSnackMessage';
import { FetchStatus } from '../../../utils/constants/fetchStatus';
import { FieldConstants } from '../../../utils/constants/fieldConstants';
import { ElementExistsType } from '../../../utils/types/elementType';
import yup from '../../../utils/yupConfig';
import { CustomMuiDialog } from '../../dialogs/customMuiDialog/CustomMuiDialog';
import { FilterType, NO_ITEM_SELECTION_FOR_COPY } from '../constants/FilterConstants';
import { ItemSelectionForCopy } from '../filter.type';
import { FilterEditionProps } from '../filter.type';
import { FilterForm } from '../FilterForm';
import { saveExpertFilter } from '../utils/filterApi';
import { EXPERT_FILTER_QUERY, expertFilterSchema } from './ExpertFilterForm';
import { importExpertRules } from './expertFilterUtils';
import { HeaderFilterSchema } from '../HeaderFilterForm';

const formSchema = yup
.object()
.shape({
[FieldConstants.NAME]: yup.string().trim().required('nameEmpty'),
[FieldConstants.FILTER_TYPE]: yup.string().required(),
[FieldConstants.EQUIPMENT_TYPE]: yup.string().required(),
...HeaderFilterSchema,
...expertFilterSchema,
})
.required();

export interface ExpertFilterEditionDialogProps {
id: string;
name: string;
titleId: string;
open: boolean;
onClose: () => void;
broadcastChannel: BroadcastChannel;
itemSelectionForCopy: ItemSelectionForCopy;
setItemSelectionForCopy: (selection: ItemSelectionForCopy) => void;
getFilterById: (id: string) => Promise<{ [prop: string]: any }>;
activeDirectory?: UUID;
elementExists?: ElementExistsType;
language?: string;
}

export function ExpertFilterEditionDialog({
id,
name,
Expand All @@ -60,7 +42,8 @@ export function ExpertFilterEditionDialog({
activeDirectory,
elementExists,
language,
}: Readonly<ExpertFilterEditionDialogProps>) {
description,
}: Readonly<FilterEditionProps>) {
const { snackError } = useSnackMessage();
const [dataFetchStatus, setDataFetchStatus] = useState(FetchStatus.IDLE);

Expand All @@ -86,6 +69,7 @@ export function ExpertFilterEditionDialog({
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]),
Expand All @@ -99,7 +83,7 @@ export function ExpertFilterEditionDialog({
});
});
}
}, [id, name, open, reset, snackError, getFilterById]);
}, [id, name, open, reset, snackError, getFilterById, description]);

const onSubmit = useCallback(
(filterForm: { [prop: string]: any }) => {
Expand All @@ -108,7 +92,7 @@ export function ExpertFilterEditionDialog({
filterForm[EXPERT_FILTER_QUERY],
filterForm[FieldConstants.EQUIPMENT_TYPE],
filterForm[FieldConstants.NAME],
'', // The description can not be edited from this dialog
filterForm[FieldConstants.DESCRIPTION] ?? '',
false,
null,
onClose,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

import { yupResolver } from '@hookform/resolvers/yup';
import { UUID } from 'crypto';
import PropTypes from 'prop-types';
import { useCallback, useEffect, useState } from 'react';
import { SubmitHandler, useForm, UseFormReturn } from 'react-hook-form';
Expand All @@ -19,36 +18,20 @@ import { saveExplicitNamingFilter } from '../utils/filterApi';
import { explicitNamingFilterSchema, FILTER_EQUIPMENTS_ATTRIBUTES } from './ExplicitNamingFilterForm';

import { FetchStatus } from '../../../utils/constants/fetchStatus';
import { ElementExistsType } from '../../../utils/types/elementType';
import { FilterForm } from '../FilterForm';
import { FilterType, NO_ITEM_SELECTION_FOR_COPY } from '../constants/FilterConstants';
import { ItemSelectionForCopy } from '../filter.type';
import { FilterEditionProps } from '../filter.type';
import { HeaderFilterSchema } from '../HeaderFilterForm';

const formSchema = yup
.object()
.shape({
[FieldConstants.NAME]: yup.string().trim().required('nameEmpty'),
[FieldConstants.FILTER_TYPE]: yup.string().required(),
[FieldConstants.EQUIPMENT_TYPE]: yup.string().required(),
...HeaderFilterSchema,
...explicitNamingFilterSchema,
})
.required();

type FormSchemaType = yup.InferType<typeof formSchema>;
export interface ExplicitNamingFilterEditionDialogProps {
id: string;
name: string;
titleId: string;
open: boolean;
onClose: () => void;
broadcastChannel: BroadcastChannel;
itemSelectionForCopy: ItemSelectionForCopy;
setItemSelectionForCopy: (selection: ItemSelectionForCopy) => void;
getFilterById: (id: string) => Promise<any>;
activeDirectory?: UUID;
elementExists?: ElementExistsType;
language?: string;
}

export function ExplicitNamingFilterEditionDialog({
id,
Expand All @@ -63,7 +46,8 @@ export function ExplicitNamingFilterEditionDialog({
activeDirectory,
elementExists,
language,
}: Readonly<ExplicitNamingFilterEditionDialogProps>) {
description,
}: Readonly<FilterEditionProps>) {
const { snackError } = useSnackMessage();
const [dataFetchStatus, setDataFetchStatus] = useState(FetchStatus.IDLE);

Expand All @@ -88,6 +72,7 @@ export function ExplicitNamingFilterEditionDialog({
setDataFetchStatus(FetchStatus.FETCH_SUCCESS);
reset({
[FieldConstants.NAME]: name,
[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) => ({
Expand All @@ -104,7 +89,7 @@ export function ExplicitNamingFilterEditionDialog({
});
});
}
}, [id, name, open, reset, snackError, getFilterById]);
}, [id, name, open, reset, snackError, getFilterById, description]);

const onSubmit = useCallback<SubmitHandler<FormSchemaType>>(
(filterForm) => {
Expand All @@ -113,7 +98,7 @@ export function ExplicitNamingFilterEditionDialog({
false,
filterForm[FieldConstants.EQUIPMENT_TYPE],
filterForm[FieldConstants.NAME],
'', // The description can not be edited from this dialog
filterForm[FieldConstants.DESCRIPTION] ?? '',
id,
(error) => {
snackError({
Expand Down
17 changes: 17 additions & 0 deletions src/components/filter/filter.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { UUID } from 'crypto';
import { ElementExistsType } from '../../utils';

/**
* Represent an item/object in directories.
Expand All @@ -18,3 +19,19 @@ export type ItemSelectionForCopy = {
parentDirectoryUuid: UUID | null;
specificTypeItem: string | null;
};

export interface FilterEditionProps {
id: string;
name: string;
titleId: string;
open: boolean;
onClose: () => void;
broadcastChannel: BroadcastChannel;
itemSelectionForCopy: ItemSelectionForCopy;
setItemSelectionForCopy: (selection: ItemSelectionForCopy) => void;
getFilterById: (id: string) => Promise<{ [prop: string]: any }>;
activeDirectory?: UUID;
elementExists?: ElementExistsType;
language?: string;
description?: string;
}
2 changes: 2 additions & 0 deletions src/components/filter/utils/filterApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const saveExplicitNamingFilter = (
filterEquipmentsAttributes: cleanedTableValues,
},
name,
description,
token
)
.then(() => {
Expand Down Expand Up @@ -113,6 +114,7 @@ export const saveExpertFilter = (
rules: exportExpertRules(query),
},
name,
description,
token
)
.then(() => {
Expand Down
7 changes: 4 additions & 3 deletions src/components/inputs/reactHookForm/text/DescriptionField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@ import { FieldConstants } from '../../../../utils/constants/fieldConstants';
import { ExpandingTextField } from './ExpandingTextField';

export function DescriptionField() {
const [isDescriptionFieldVisible, setIsDescriptionFieldVisible] = useState(false);
const { setValue } = useFormContext();
const { setValue, getValues } = useFormContext();
const description = getValues(FieldConstants.DESCRIPTION);
const [isDescriptionFieldVisible, setIsDescriptionFieldVisible] = useState(!!description);

const handleOpenDescription = () => {
setIsDescriptionFieldVisible(true);
};

const handleCloseDescription = () => {
setIsDescriptionFieldVisible(false);
setValue(FieldConstants.DESCRIPTION, '');
setValue(FieldConstants.DESCRIPTION, '', { shouldDirty: true });
};

return (
Expand Down
3 changes: 2 additions & 1 deletion src/services/explore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ export function createFilter(
);
}

export function saveFilter(filter: any, name: string, token?: string) {
export function saveFilter(filter: any, name: string, description: string, token?: string) {
const urlSearchParams = new URLSearchParams();
urlSearchParams.append('name', name);
urlSearchParams.append('description', description);
return backendFetch(
`${PREFIX_EXPLORE_SERVER_QUERIES}/v1/explore/filters/${filter.id}?${urlSearchParams.toString()}`,
{
Expand Down
1 change: 1 addition & 0 deletions src/utils/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
export * from './browserConstants';
export * from './fetchStatus';
export * from './fieldConstants';
export * from './uiConstants';
8 changes: 8 additions & 0 deletions src/utils/constants/uiConstants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright © 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/.
*/

export const MAX_CHAR_DESCRIPTION = 500;

0 comments on commit db1cdc3

Please sign in to comment.