@gridsuite/commons-ui 0.117.0 → 0.118.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/directoryItemSelector/DirectoryItemSelector.js +22 -20
- package/dist/components/directoryItemSelector/utils.d.ts +8 -5
- package/dist/components/directoryItemSelector/utils.js +20 -14
- package/dist/components/dnd-table/dnd-table.d.ts +1 -0
- package/dist/components/dnd-table/dnd-table.js +6 -6
- package/dist/components/inputs/reactHookForm/text/UniqueNameInput.d.ts +1 -1
- package/dist/components/inputs/reactHookForm/text/UniqueNameInput.js +8 -77
- package/dist/components/parameters/common/limitreductions/columns-definitions.js +1 -5
- package/dist/hooks/use-unique-name-validation.d.ts +16 -0
- package/dist/hooks/use-unique-name-validation.js +92 -0
- package/dist/hooks/useModificationLabelComputer.js +1 -0
- package/package.json +1 -1
|
@@ -180,27 +180,27 @@ function DirectoryItemSelector({
|
|
|
180
180
|
const fetchDirectoryChildren = useCallback(
|
|
181
181
|
(nodeId) => {
|
|
182
182
|
const typeList = types.includes(ElementType.DIRECTORY) ? [] : types;
|
|
183
|
-
fetchDirectoryContent(nodeId, typeList).then((children) => {
|
|
183
|
+
return fetchDirectoryContent(nodeId, typeList).then((children) => {
|
|
184
184
|
const childrenMatchedTypes = children.filter(
|
|
185
185
|
(item) => contentFilter().has(item.type)
|
|
186
186
|
);
|
|
187
187
|
if (childrenMatchedTypes.length > 0 && equipmentTypes && equipmentTypes.length > 0) {
|
|
188
|
-
fetchElementsInfos(
|
|
188
|
+
return fetchElementsInfos(
|
|
189
189
|
childrenMatchedTypes.map((e) => e.elementUuid),
|
|
190
190
|
types,
|
|
191
191
|
equipmentTypes
|
|
192
192
|
).then((childrenWithMetadata) => {
|
|
193
|
-
const
|
|
193
|
+
const filteredChildren = itemFilter ? childrenWithMetadata.filter((val) => {
|
|
194
194
|
if (val.type === ElementType.DIRECTORY) {
|
|
195
195
|
return true;
|
|
196
196
|
}
|
|
197
197
|
return itemFilter(val);
|
|
198
198
|
}) : childrenWithMetadata;
|
|
199
|
-
addToDirectory(nodeId,
|
|
199
|
+
addToDirectory(nodeId, filteredChildren);
|
|
200
200
|
});
|
|
201
|
-
} else {
|
|
202
|
-
addToDirectory(nodeId, childrenMatchedTypes);
|
|
203
201
|
}
|
|
202
|
+
addToDirectory(nodeId, childrenMatchedTypes);
|
|
203
|
+
return Promise.resolve();
|
|
204
204
|
}).catch((error) => {
|
|
205
205
|
console.warn(`Could not update subs (and content) of '${nodeId}' : ${error.message}`);
|
|
206
206
|
});
|
|
@@ -208,13 +208,11 @@ function DirectoryItemSelector({
|
|
|
208
208
|
[types, equipmentTypes, itemFilter, contentFilter, addToDirectory]
|
|
209
209
|
);
|
|
210
210
|
const fetchNodeChildrenIfNeeded = useCallback(
|
|
211
|
-
(nodeId
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
}, delay);
|
|
211
|
+
async (nodeId) => {
|
|
212
|
+
const node = nodeMap.current[nodeId];
|
|
213
|
+
if (node && (!node.children || node.children.length === 0) && node.type === ElementType.DIRECTORY) {
|
|
214
|
+
await fetchDirectoryChildren(nodeId);
|
|
215
|
+
}
|
|
218
216
|
},
|
|
219
217
|
[fetchDirectoryChildren]
|
|
220
218
|
);
|
|
@@ -224,15 +222,15 @@ function DirectoryItemSelector({
|
|
|
224
222
|
}
|
|
225
223
|
const expandedArray = await getExpansionPathsForSelected(selected, expanded);
|
|
226
224
|
setAutoExpandedNodes(expandedArray);
|
|
227
|
-
fetchChildrenForExpandedNodes(expandedArray, fetchNodeChildrenIfNeeded);
|
|
225
|
+
await fetchChildrenForExpandedNodes(expandedArray, fetchNodeChildrenIfNeeded);
|
|
228
226
|
return true;
|
|
229
227
|
}, [selected, expanded, fetchNodeChildrenIfNeeded]);
|
|
230
|
-
const handleProvidedExpansion = useCallback(() => {
|
|
228
|
+
const handleProvidedExpansion = useCallback(async () => {
|
|
231
229
|
if (!expanded || expanded.length === 0) {
|
|
232
230
|
return false;
|
|
233
231
|
}
|
|
234
232
|
setAutoExpandedNodes(expanded);
|
|
235
|
-
fetchChildrenForExpandedNodes(expanded, fetchNodeChildrenIfNeeded);
|
|
233
|
+
await fetchChildrenForExpandedNodes(expanded, fetchNodeChildrenIfNeeded);
|
|
236
234
|
return true;
|
|
237
235
|
}, [expanded, fetchNodeChildrenIfNeeded]);
|
|
238
236
|
const handleLastSelectedExpansion = useCallback(async () => {
|
|
@@ -241,14 +239,18 @@ function DirectoryItemSelector({
|
|
|
241
239
|
return false;
|
|
242
240
|
}
|
|
243
241
|
setAutoExpandedNodes(expandPath);
|
|
244
|
-
fetchChildrenForExpandedNodes(expandPath, fetchNodeChildrenIfNeeded);
|
|
242
|
+
await fetchChildrenForExpandedNodes(expandPath, fetchNodeChildrenIfNeeded);
|
|
245
243
|
return true;
|
|
246
244
|
}, [fetchNodeChildrenIfNeeded]);
|
|
247
245
|
const initializeExpansion = useCallback(async () => {
|
|
248
246
|
const selectedSuccess = await handleSelectedExpansion();
|
|
249
|
-
if (selectedSuccess)
|
|
250
|
-
|
|
251
|
-
|
|
247
|
+
if (selectedSuccess) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const expandedSuccess = await handleProvidedExpansion();
|
|
251
|
+
if (expandedSuccess) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
252
254
|
await handleLastSelectedExpansion();
|
|
253
255
|
}, [handleSelectedExpansion, handleProvidedExpansion, handleLastSelectedExpansion]);
|
|
254
256
|
useEffect(() => {
|
|
@@ -26,10 +26,14 @@ export declare function fetchDirectoryPathSafe(directoryId: UUID): Promise<Eleme
|
|
|
26
26
|
*/
|
|
27
27
|
export declare function initializeFromLastSelected(): Promise<UUID[] | null>;
|
|
28
28
|
/**
|
|
29
|
-
* Fetches expansion paths for multiple selected items
|
|
29
|
+
* Fetches expansion paths for multiple selected items, collecting unique parent directories
|
|
30
|
+
* (excluding the selected items themselves) and sorting them by their minimum depth across
|
|
31
|
+
* all paths. This ensures parents appear before their descendants in the returned array,
|
|
32
|
+
* which is crucial for sequential fetching to avoid loading children before parents are
|
|
33
|
+
* fully populated in the node map.
|
|
30
34
|
* @param selectedIds Array of selected item UUIDs
|
|
31
35
|
* @param expanded Optional existing expanded nodes
|
|
32
|
-
* @returns Promise resolving to combined expansion array
|
|
36
|
+
* @returns Promise resolving to combined expansion array sorted by depth
|
|
33
37
|
*/
|
|
34
38
|
export declare function getExpansionPathsForSelected(selectedIds: UUID[], expanded?: UUID[]): Promise<UUID[]>;
|
|
35
39
|
/**
|
|
@@ -44,9 +48,8 @@ export declare function saveLastSelectedDirectoryFromNode(node: {
|
|
|
44
48
|
}>;
|
|
45
49
|
}): Promise<void>;
|
|
46
50
|
/**
|
|
47
|
-
* Fetches children for expanded nodes
|
|
51
|
+
* Fetches children for expanded nodes sequentially to ensure parent nodes are loaded before children
|
|
48
52
|
* @param expandedNodes Array of node UUIDs to fetch children for
|
|
49
53
|
* @param fetchChildrenCallback Function to fetch children for a single node
|
|
50
|
-
* @param delayBetweenRequests Delay in milliseconds between requests (default: 100ms)
|
|
51
54
|
*/
|
|
52
|
-
export declare function fetchChildrenForExpandedNodes(expandedNodes: UUID[], fetchChildrenCallback: (nodeId: UUID
|
|
55
|
+
export declare function fetchChildrenForExpandedNodes(expandedNodes: UUID[], fetchChildrenCallback: (nodeId: UUID) => Promise<void>): Promise<void>;
|
|
@@ -54,18 +54,23 @@ async function initializeFromLastSelected() {
|
|
|
54
54
|
}
|
|
55
55
|
async function getExpansionPathsForSelected(selectedIds, expanded = []) {
|
|
56
56
|
const expandedSet = new Set(expanded);
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
const idToMinIndex = /* @__PURE__ */ new Map();
|
|
58
|
+
const paths = await Promise.all(selectedIds.map(fetchDirectoryPathSafe));
|
|
59
|
+
paths.filter((p) => !!p && p.length > 0).forEach((path) => {
|
|
60
|
+
path.forEach((element, index) => {
|
|
61
|
+
if (index < path.length - 1) {
|
|
62
|
+
const id = element.elementUuid;
|
|
63
|
+
expandedSet.add(id);
|
|
64
|
+
if (!idToMinIndex.has(id) || index < idToMinIndex.get(id)) {
|
|
65
|
+
idToMinIndex.set(id, index);
|
|
63
66
|
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
66
69
|
});
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
const expandedArray = Array.from(expandedSet).sort(
|
|
71
|
+
(a, b) => (idToMinIndex.get(a) ?? Infinity) - (idToMinIndex.get(b) ?? Infinity)
|
|
72
|
+
);
|
|
73
|
+
return expandedArray;
|
|
69
74
|
}
|
|
70
75
|
async function saveLastSelectedDirectoryFromNode(node) {
|
|
71
76
|
let lastSelectedDirId;
|
|
@@ -78,10 +83,11 @@ async function saveLastSelectedDirectoryFromNode(node) {
|
|
|
78
83
|
await saveLastSelectedDirectory(lastSelectedDirId);
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
|
-
function fetchChildrenForExpandedNodes(expandedNodes, fetchChildrenCallback
|
|
82
|
-
expandedNodes.
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
async function fetchChildrenForExpandedNodes(expandedNodes, fetchChildrenCallback) {
|
|
87
|
+
await expandedNodes.reduce(async (promise, nodeId) => {
|
|
88
|
+
await promise;
|
|
89
|
+
return fetchChildrenCallback(nodeId);
|
|
90
|
+
}, Promise.resolve());
|
|
85
91
|
}
|
|
86
92
|
export {
|
|
87
93
|
clearLastSelectedDirectory,
|
|
@@ -23,6 +23,7 @@ interface DndTableProps {
|
|
|
23
23
|
uploadButtonMessageId?: string;
|
|
24
24
|
handleResetButton?: () => void;
|
|
25
25
|
resetButtonMessageId?: string;
|
|
26
|
+
maxRows?: number;
|
|
26
27
|
}
|
|
27
28
|
export declare function DndTable(props: Readonly<DndTableProps>): import("react/jsx-runtime").JSX.Element;
|
|
28
29
|
export {};
|
|
@@ -5,7 +5,7 @@ import { Grid, TableContainer, Table, TableHead, TableRow, TableCell, Box, Table
|
|
|
5
5
|
import { DragIndicator } from "@mui/icons-material";
|
|
6
6
|
import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";
|
|
7
7
|
import { useIntl } from "react-intl";
|
|
8
|
-
import {
|
|
8
|
+
import { MAX_ROWS_NUMBER, SELECTED, DndColumnType } from "./dnd-table.type.js";
|
|
9
9
|
import { DndTableBottomLeftButtons } from "./dnd-table-bottom-left-buttons.js";
|
|
10
10
|
import { DndTableBottomRightButtons } from "./dnd-table-bottom-right-buttons.js";
|
|
11
11
|
import { DndTableAddRowsDialog } from "./dnd-table-add-rows-dialog.js";
|
|
@@ -29,9 +29,8 @@ import "localized-countries/data/fr";
|
|
|
29
29
|
import "localized-countries/data/en";
|
|
30
30
|
import { TableNumericalInput } from "../inputs/reactHookForm/tableInputs/table-numerical-input.js";
|
|
31
31
|
import { TableTextInput } from "../inputs/reactHookForm/tableInputs/table-text-input.js";
|
|
32
|
-
import "../../utils/types/equipmentType.js";
|
|
33
|
-
import "notistack";
|
|
34
32
|
import "../../utils/conversionUtils.js";
|
|
33
|
+
import "../../utils/types/equipmentType.js";
|
|
35
34
|
import "../../utils/yupConfig.js";
|
|
36
35
|
import "@react-querybuilder/material";
|
|
37
36
|
import "../filter/expert/expertFilterConstants.js";
|
|
@@ -163,7 +162,8 @@ function DndTable(props) {
|
|
|
163
162
|
handleUploadButton = void 0,
|
|
164
163
|
uploadButtonMessageId = void 0,
|
|
165
164
|
handleResetButton = void 0,
|
|
166
|
-
resetButtonMessageId = void 0
|
|
165
|
+
resetButtonMessageId = void 0,
|
|
166
|
+
maxRows = MAX_ROWS_NUMBER
|
|
167
167
|
} = props;
|
|
168
168
|
const intl = useIntl();
|
|
169
169
|
const { getValues, setValue, setError, clearErrors } = useFormContext();
|
|
@@ -192,7 +192,7 @@ function DndTable(props) {
|
|
|
192
192
|
);
|
|
193
193
|
}
|
|
194
194
|
const addNewRows = (numberOfRows) => {
|
|
195
|
-
if (currentRows.length + numberOfRows >
|
|
195
|
+
if (currentRows.length + numberOfRows > maxRows) {
|
|
196
196
|
setError(arrayFormName, {
|
|
197
197
|
type: "custom",
|
|
198
198
|
message: intl.formatMessage(
|
|
@@ -200,7 +200,7 @@ function DndTable(props) {
|
|
|
200
200
|
id: "MaximumRowNumberError"
|
|
201
201
|
},
|
|
202
202
|
{
|
|
203
|
-
value:
|
|
203
|
+
value: maxRows
|
|
204
204
|
}
|
|
205
205
|
)
|
|
206
206
|
});
|
|
@@ -14,6 +14,6 @@ export interface UniqueNameInputProps {
|
|
|
14
14
|
fullWidth?: boolean;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
* Input component that constantly
|
|
17
|
+
* Input component that constantly checks if the field's value is available or not
|
|
18
18
|
*/
|
|
19
19
|
export declare function UniqueNameInput({ name, label, elementType, autoFocus, onManualChangeCallback, formProps, currentName, activeDirectory, sx, fullWidth, }: Readonly<UniqueNameInputProps>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useEffect } from "react";
|
|
3
2
|
import { FormattedMessage } from "react-intl";
|
|
4
3
|
import { TextField, InputAdornment, CircularProgress } from "@mui/material";
|
|
5
4
|
import { Check } from "@mui/icons-material";
|
|
6
|
-
import { useController
|
|
7
|
-
import "../../../../
|
|
8
|
-
import { elementAlreadyExists } from "../../../../services/directory.js";
|
|
9
|
-
import { useDebounce } from "../../../../hooks/useDebounce.js";
|
|
10
|
-
import "localized-countries";
|
|
11
|
-
import "localized-countries/data/fr";
|
|
12
|
-
import "localized-countries/data/en";
|
|
13
|
-
import "notistack";
|
|
14
|
-
import { FieldConstants } from "../../../../utils/constants/fieldConstants.js";
|
|
15
|
-
import "../../../../utils/conversionUtils.js";
|
|
16
|
-
import "../../../../utils/yupConfig.js";
|
|
5
|
+
import { useController } from "react-hook-form";
|
|
6
|
+
import { useUniqueNameValidation } from "../../../../hooks/use-unique-name-validation.js";
|
|
17
7
|
function UniqueNameInput({
|
|
18
8
|
name,
|
|
19
9
|
label,
|
|
@@ -26,77 +16,18 @@ function UniqueNameInput({
|
|
|
26
16
|
sx,
|
|
27
17
|
fullWidth = true
|
|
28
18
|
}) {
|
|
29
|
-
var _a;
|
|
30
19
|
const {
|
|
31
20
|
field: { onChange, onBlur, value, ref },
|
|
32
|
-
fieldState: { error
|
|
21
|
+
fieldState: { error }
|
|
33
22
|
} = useController({
|
|
34
23
|
name
|
|
35
24
|
});
|
|
36
|
-
const {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
25
|
+
const { isValidating } = useUniqueNameValidation({
|
|
26
|
+
name,
|
|
27
|
+
currentName,
|
|
28
|
+
elementType,
|
|
29
|
+
activeDirectory
|
|
40
30
|
});
|
|
41
|
-
const {
|
|
42
|
-
setError,
|
|
43
|
-
clearErrors,
|
|
44
|
-
trigger,
|
|
45
|
-
formState: { errors }
|
|
46
|
-
} = useFormContext();
|
|
47
|
-
const isValidating = (_a = errors.root) == null ? void 0 : _a.isValidating;
|
|
48
|
-
const directory = selectedDirectory || activeDirectory;
|
|
49
|
-
const handleCheckName = useCallback(
|
|
50
|
-
(nameValue) => {
|
|
51
|
-
if (nameValue !== currentName && directory) {
|
|
52
|
-
elementAlreadyExists(directory, nameValue, elementType).then((alreadyExist) => {
|
|
53
|
-
if (alreadyExist) {
|
|
54
|
-
setError(name, {
|
|
55
|
-
type: "validate",
|
|
56
|
-
message: "nameAlreadyUsed"
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}).catch((e) => {
|
|
60
|
-
setError(name, {
|
|
61
|
-
type: "validate",
|
|
62
|
-
message: "nameValidityCheckErrorMsg"
|
|
63
|
-
});
|
|
64
|
-
console.error(e == null ? void 0 : e.message);
|
|
65
|
-
}).finally(() => {
|
|
66
|
-
clearErrors("root.isValidating");
|
|
67
|
-
trigger("root.isValidating");
|
|
68
|
-
});
|
|
69
|
-
} else {
|
|
70
|
-
trigger("root.isValidating");
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
[currentName, directory, elementType, setError, name, clearErrors, trigger]
|
|
74
|
-
);
|
|
75
|
-
const debouncedHandleCheckName = useDebounce(handleCheckName, 700);
|
|
76
|
-
useEffect(() => {
|
|
77
|
-
const trimmedValue = value.trim();
|
|
78
|
-
if (selectedDirectory) {
|
|
79
|
-
debouncedHandleCheckName(trimmedValue);
|
|
80
|
-
}
|
|
81
|
-
if (!isDirty) {
|
|
82
|
-
clearErrors(name);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (trimmedValue) {
|
|
86
|
-
clearErrors(name);
|
|
87
|
-
setError("root.isValidating", {
|
|
88
|
-
type: "validate",
|
|
89
|
-
message: "cantSubmitWhileValidating"
|
|
90
|
-
});
|
|
91
|
-
debouncedHandleCheckName(trimmedValue);
|
|
92
|
-
} else {
|
|
93
|
-
clearErrors("root.isValidating");
|
|
94
|
-
setError(name, {
|
|
95
|
-
type: "validate",
|
|
96
|
-
message: "nameEmpty"
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}, [debouncedHandleCheckName, setError, clearErrors, name, value, isDirty, selectedDirectory]);
|
|
100
31
|
const handleManualChange = (e) => {
|
|
101
32
|
onChange(e.target.value);
|
|
102
33
|
onManualChangeCallback == null ? void 0 : onManualChangeCallback();
|
|
@@ -8,12 +8,8 @@ import "@mui/icons-material";
|
|
|
8
8
|
import "react-hook-form";
|
|
9
9
|
import "../../../inputs/reactHookForm/provider/CustomFormProvider.js";
|
|
10
10
|
import * as yup from "yup";
|
|
11
|
-
import "../../../../utils/types/equipmentType.js";
|
|
12
|
-
import "localized-countries";
|
|
13
|
-
import "localized-countries/data/fr";
|
|
14
|
-
import "localized-countries/data/en";
|
|
15
|
-
import "notistack";
|
|
16
11
|
import "../../../../utils/conversionUtils.js";
|
|
12
|
+
import "../../../../utils/types/equipmentType.js";
|
|
17
13
|
import "../../../filter/HeaderFilterForm.js";
|
|
18
14
|
import { getNameElementEditorSchema } from "../name-element-editor/name-element-editor-utils.js";
|
|
19
15
|
const LIMIT_REDUCTIONS_FORM = "limitReductionsForm";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { UUID } from 'crypto';
|
|
2
|
+
import { ElementType } from '../utils';
|
|
3
|
+
interface UseUniqueNameValidationParams {
|
|
4
|
+
name: string;
|
|
5
|
+
currentName?: string;
|
|
6
|
+
elementType: ElementType;
|
|
7
|
+
activeDirectory?: string;
|
|
8
|
+
elementExists?: (directory: UUID, name: string, type: ElementType) => Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
export declare function useUniqueNameValidation({ name, currentName, elementType, activeDirectory, elementExists, }: UseUniqueNameValidationParams): {
|
|
11
|
+
isValidating: Partial<{
|
|
12
|
+
type: string | number;
|
|
13
|
+
message: import('react-hook-form').Message;
|
|
14
|
+
}> | undefined;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { useCallback, useEffect } from "react";
|
|
2
|
+
import { useFormContext, useController } from "react-hook-form";
|
|
3
|
+
import { FieldConstants } from "../utils/constants/fieldConstants.js";
|
|
4
|
+
import "../utils/conversionUtils.js";
|
|
5
|
+
import "react/jsx-runtime";
|
|
6
|
+
import "@mui/icons-material";
|
|
7
|
+
import "../utils/types/equipmentType.js";
|
|
8
|
+
import "../utils/yupConfig.js";
|
|
9
|
+
import { useDebounce } from "./useDebounce.js";
|
|
10
|
+
import { elementAlreadyExists } from "../services/directory.js";
|
|
11
|
+
function useUniqueNameValidation({
|
|
12
|
+
name,
|
|
13
|
+
currentName = "",
|
|
14
|
+
elementType,
|
|
15
|
+
activeDirectory,
|
|
16
|
+
elementExists = elementAlreadyExists
|
|
17
|
+
}) {
|
|
18
|
+
var _a;
|
|
19
|
+
const {
|
|
20
|
+
setError,
|
|
21
|
+
clearErrors,
|
|
22
|
+
trigger,
|
|
23
|
+
formState: { errors, defaultValues }
|
|
24
|
+
} = useFormContext();
|
|
25
|
+
const {
|
|
26
|
+
field: { value },
|
|
27
|
+
fieldState: { isDirty }
|
|
28
|
+
} = useController({ name });
|
|
29
|
+
const {
|
|
30
|
+
field: { value: selectedDirectory }
|
|
31
|
+
} = useController({
|
|
32
|
+
name: FieldConstants.DIRECTORY
|
|
33
|
+
});
|
|
34
|
+
const defaultFieldValue = defaultValues == null ? void 0 : defaultValues[name];
|
|
35
|
+
const directory = selectedDirectory || activeDirectory;
|
|
36
|
+
const isValidating = (_a = errors.root) == null ? void 0 : _a.isValidating;
|
|
37
|
+
const handleCheckName = useCallback(
|
|
38
|
+
(nameValue) => {
|
|
39
|
+
if (nameValue !== currentName && directory) {
|
|
40
|
+
elementExists(directory, nameValue, elementType).then((alreadyExist) => {
|
|
41
|
+
if (alreadyExist) {
|
|
42
|
+
setError(name, {
|
|
43
|
+
type: "validate",
|
|
44
|
+
message: "nameAlreadyUsed"
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}).catch(() => {
|
|
48
|
+
setError(name, {
|
|
49
|
+
type: "validate",
|
|
50
|
+
message: "nameValidityCheckErrorMsg"
|
|
51
|
+
});
|
|
52
|
+
}).finally(() => {
|
|
53
|
+
clearErrors("root.isValidating");
|
|
54
|
+
trigger("root.isValidating");
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
trigger("root.isValidating");
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
[currentName, directory, elementType, name, setError, clearErrors, trigger, elementExists]
|
|
61
|
+
);
|
|
62
|
+
const debouncedHandleCheckName = useDebounce(handleCheckName, 700);
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
var _a2, _b;
|
|
65
|
+
const trimmedValue = (_a2 = value == null ? void 0 : value.trim) == null ? void 0 : _a2.call(value);
|
|
66
|
+
if (!trimmedValue && isDirty) {
|
|
67
|
+
clearErrors("root.isValidating");
|
|
68
|
+
setError(name, {
|
|
69
|
+
type: "validate",
|
|
70
|
+
message: "nameEmpty"
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (!isDirty || ((_b = defaultFieldValue == null ? void 0 : defaultFieldValue.trim) == null ? void 0 : _b.call(defaultFieldValue)) === trimmedValue) {
|
|
75
|
+
clearErrors(name);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
setError("root.isValidating", {
|
|
79
|
+
type: "validate",
|
|
80
|
+
message: "cantSubmitWhileValidating"
|
|
81
|
+
});
|
|
82
|
+
if (directory) {
|
|
83
|
+
debouncedHandleCheckName(trimmedValue);
|
|
84
|
+
}
|
|
85
|
+
}, [value, debouncedHandleCheckName, setError, clearErrors, name, isDirty, defaultFieldValue, directory]);
|
|
86
|
+
return {
|
|
87
|
+
isValidating
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
useUniqueNameValidation
|
|
92
|
+
};
|
|
@@ -54,6 +54,7 @@ const useModificationLabelComputer = () => {
|
|
|
54
54
|
});
|
|
55
55
|
case MODIFICATION_TYPES.CREATE_COUPLING_DEVICE.type:
|
|
56
56
|
case MODIFICATION_TYPES.CREATE_VOLTAGE_LEVEL_TOPOLOGY.type:
|
|
57
|
+
case MODIFICATION_TYPES.CREATE_VOLTAGE_LEVEL_SECTION.type:
|
|
57
58
|
return modificationMetadata.voltageLevelId;
|
|
58
59
|
default:
|
|
59
60
|
return modificationMetadata.equipmentId || "";
|