-
Notifications
You must be signed in to change notification settings - Fork 1
Add new contingency list by filter #711
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 28 commits
b1afd69
4212a0a
1cac0c5
4e0d846
2ab313d
6d55a16
6c3af4f
8e2eeb8
9b3f7f8
21775b2
6de6d80
999734f
ecc5f99
9af1cd9
5bd6b63
5e53494
de82257
b5af04f
c54de55
cf5011b
bc151d9
a346a79
3ae3628
47ed523
5eff019
a250861
dfedcca
b63f5f7
c4339dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
/** | ||
* 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 { | ||
CustomMuiDialog, | ||
FieldConstants, | ||
MAX_CHAR_DESCRIPTION, | ||
TreeViewFinderNodeProps, | ||
useSnackMessage, | ||
yupConfig as yup, | ||
} from '@gridsuite/commons-ui'; | ||
import { useForm } from 'react-hook-form'; | ||
import { yupResolver } from '@hookform/resolvers/yup'; | ||
import { useSelector } from 'react-redux'; | ||
import { useCallback, useEffect, useState } from 'react'; | ||
import { UUID } from 'crypto'; | ||
import { ObjectSchema } from 'yup'; | ||
import ContingencyListFilterBasedForm from './contingency-list-filter-based-form'; | ||
import { AppState } from '../../../../redux/types'; | ||
import { | ||
createFilterBasedContingency, | ||
getContingencyList, | ||
saveFilterBasedContingencyList, | ||
} from '../../../../utils/rest-api'; | ||
import { handleNotAllowedError } from '../../../utils/rest-errors'; | ||
import { ContingencyListType } from '../../../../utils/elementType'; | ||
import { getFilterBasedFormDataFromFetchedElement } from '../contingency-list-utils'; | ||
import { FilterBasedContingencyList } from '../../../../utils/contingency-list.type'; | ||
|
||
const schema: ObjectSchema<ContingencyListFilterBasedFormData> = yup.object().shape({ | ||
[FieldConstants.NAME]: yup.string().required(), | ||
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION), | ||
[FieldConstants.FILTERS]: yup.array().required(), | ||
}); | ||
|
||
export interface ContingencyListFilterBasedFormData { | ||
[FieldConstants.NAME]: string; | ||
[FieldConstants.DESCRIPTION]?: string; | ||
[FieldConstants.FILTERS]: TreeViewFinderNodeProps[]; | ||
Check failure on line 43 in src/components/dialogs/contingency-list/filter-based/contingency-list-filter-based-dialog.tsx
|
||
} | ||
|
||
const getContingencyListEmptyFormData = (name = '') => ({ | ||
[FieldConstants.NAME]: name, | ||
[FieldConstants.DESCRIPTION]: '', | ||
[FieldConstants.FILTERS]: [], | ||
}); | ||
|
||
const emptyFormData = (name?: string) => getContingencyListEmptyFormData(name); | ||
|
||
export interface FilterBasedContingencyListProps { | ||
titleId: string; | ||
open: boolean; | ||
onClose: () => void; | ||
name?: string; | ||
description?: string; | ||
id?: UUID; | ||
} | ||
|
||
export default function FilterBasedContingencyListDialog({ | ||
titleId, | ||
open, | ||
onClose, | ||
name, | ||
description, | ||
id, | ||
}: Readonly<FilterBasedContingencyListProps>) { | ||
const activeDirectory = useSelector((state: AppState) => state.activeDirectory); | ||
const { snackError } = useSnackMessage(); | ||
const [isFetching, setIsFetching] = useState(!!id); | ||
|
||
const methods = useForm<ContingencyListFilterBasedFormData>({ | ||
defaultValues: emptyFormData(), | ||
resolver: yupResolver(schema), | ||
}); | ||
const { | ||
reset, | ||
formState: { errors }, | ||
} = methods; | ||
|
||
useEffect(() => { | ||
if (id) { | ||
setIsFetching(true); | ||
getContingencyList(ContingencyListType.FILTERS.id, id?.toString()) | ||
.then((response) => { | ||
const formData: ContingencyListFilterBasedFormData = getFilterBasedFormDataFromFetchedElement( | ||
response, | ||
name ?? '', | ||
description ?? '' | ||
); | ||
reset({ ...formData }); | ||
}) | ||
.catch((error) => { | ||
snackError({ | ||
messageTxt: error.message, | ||
headerId: 'cannotRetrieveContingencyList', | ||
}); | ||
}) | ||
.finally(() => setIsFetching(false)); | ||
} | ||
}, [id, name, reset, snackError, description]); | ||
|
||
const closeAndClear = useCallback(() => { | ||
reset(emptyFormData()); | ||
onClose(); | ||
}, [onClose, reset]); | ||
|
||
const onSubmit = useCallback( | ||
(data: ContingencyListFilterBasedFormData) => { | ||
const filterBaseContingencyList: FilterBasedContingencyList = { | ||
filters: data[FieldConstants.FILTERS]?.map((item: TreeViewFinderNodeProps) => { | ||
Check failure on line 114 in src/components/dialogs/contingency-list/filter-based/contingency-list-filter-based-dialog.tsx
|
||
return { | ||
id: item.id, | ||
}; | ||
}), | ||
}; | ||
|
||
if (id) { | ||
saveFilterBasedContingencyList( | ||
id, | ||
data[FieldConstants.NAME], | ||
data[FieldConstants.DESCRIPTION] ?? '', | ||
filterBaseContingencyList | ||
) | ||
.then(() => closeAndClear()) | ||
.catch((error) => { | ||
if (handleNotAllowedError(error, snackError)) { | ||
return; | ||
} | ||
snackError({ | ||
messageTxt: error.message, | ||
headerId: 'contingencyListEditingError', | ||
headerValues: { name: data[FieldConstants.NAME] }, | ||
}); | ||
}); | ||
} else { | ||
createFilterBasedContingency( | ||
data[FieldConstants.NAME], | ||
data[FieldConstants.DESCRIPTION] ?? '', | ||
filterBaseContingencyList, | ||
activeDirectory | ||
) | ||
.then(() => closeAndClear()) | ||
.catch((error) => { | ||
if (handleNotAllowedError(error, snackError)) { | ||
return; | ||
} | ||
snackError({ | ||
messageTxt: error.message, | ||
headerId: 'contingencyListCreationError', | ||
headerValues: { name: data[FieldConstants.NAME] }, | ||
}); | ||
}); | ||
} | ||
}, | ||
[activeDirectory, closeAndClear, id, snackError] | ||
); | ||
|
||
const nameError = errors[FieldConstants.NAME]; | ||
const isValidating = errors.root?.isValidating; | ||
|
||
return ( | ||
<CustomMuiDialog | ||
titleId={titleId} | ||
open={open} | ||
onClose={closeAndClear} | ||
onSave={onSubmit} | ||
formSchema={schema} | ||
formMethods={methods} | ||
unscrollableFullHeight | ||
disabledSave={Boolean(!!nameError || isValidating)} | ||
isDataFetching={isFetching} | ||
> | ||
<ContingencyListFilterBasedForm /> | ||
</CustomMuiDialog> | ||
); | ||
} |
Uh oh!
There was an error while loading. Please reload this page.