@gridsuite/commons-ui 0.73.1 → 0.75.0
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/filter/constants/FilterConstants.d.ts +2 -2
- package/dist/components/filter/constants/FilterConstants.js +2 -2
- package/dist/components/filter/criteriaBased/CriteriaBasedFilterEditionDialog.d.ts +4 -4
- package/dist/components/filter/criteriaBased/CriteriaBasedFilterEditionDialog.js +7 -9
- package/dist/components/filter/expert/ExpertFilterEditionDialog.d.ts +4 -4
- package/dist/components/filter/expert/ExpertFilterEditionDialog.js +7 -9
- package/dist/components/filter/explicitNaming/ExplicitNamingFilterEditionDialog.d.ts +4 -4
- package/dist/components/filter/explicitNaming/ExplicitNamingFilterEditionDialog.js +7 -9
- package/dist/components/filter/filter.type.d.ts +6 -7
- package/dist/components/filter/index.js +2 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +10 -2
- package/dist/components/notifications/NotificationsProvider.d.ts +6 -0
- package/dist/components/notifications/NotificationsProvider.js +54 -0
- package/dist/components/notifications/contexts/NotificationsContext.d.ts +23 -0
- package/dist/components/notifications/contexts/NotificationsContext.js +14 -0
- package/dist/components/notifications/hooks/useListenerManager.d.ts +7 -0
- package/dist/components/notifications/hooks/useListenerManager.js +50 -0
- package/dist/components/notifications/hooks/useNotificationsListener.d.ts +11 -0
- package/dist/components/notifications/hooks/useNotificationsListener.js +33 -0
- package/dist/components/notifications/index.d.ts +4 -0
- package/dist/components/notifications/index.js +10 -0
- package/dist/index.js +10 -2
- package/dist/services/appsMetadata.d.ts +1 -1
- package/dist/services/appsMetadata.js +2 -2
- package/dist/translations/en/networkModificationsEn.d.ts +1 -1
- package/dist/translations/en/networkModificationsEn.js +1 -1
- package/dist/utils/mapper/getFileIcon.js +3 -1
- package/dist/utils/types/elementType.d.ts +2 -1
- package/dist/utils/types/elementType.js +1 -0
- package/package.json +2 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ItemSelectionForCopy } from '../filter.type';
|
|
2
2
|
|
|
3
3
|
export declare const DISTRIBUTION_KEY = "distributionKey";
|
|
4
4
|
export declare const FilterType: {
|
|
@@ -15,4 +15,4 @@ export declare const FilterType: {
|
|
|
15
15
|
label: string;
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
|
-
export declare const
|
|
18
|
+
export declare const NO_ITEM_SELECTION_FOR_COPY: ItemSelectionForCopy;
|
|
@@ -4,7 +4,7 @@ const FilterType = {
|
|
|
4
4
|
EXPLICIT_NAMING: { id: "IDENTIFIER_LIST", label: "filter.explicitNaming" },
|
|
5
5
|
EXPERT: { id: "EXPERT", label: "filter.expert" }
|
|
6
6
|
};
|
|
7
|
-
const
|
|
7
|
+
const NO_ITEM_SELECTION_FOR_COPY = {
|
|
8
8
|
sourceItemUuid: null,
|
|
9
9
|
nameItem: null,
|
|
10
10
|
descriptionItem: null,
|
|
@@ -15,5 +15,5 @@ const NO_SELECTION_FOR_COPY = {
|
|
|
15
15
|
export {
|
|
16
16
|
DISTRIBUTION_KEY,
|
|
17
17
|
FilterType,
|
|
18
|
-
|
|
18
|
+
NO_ITEM_SELECTION_FOR_COPY
|
|
19
19
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ItemSelectionForCopy } from '../filter.type';
|
|
2
2
|
import { ElementExistsType } from '../../../utils/types/elementType';
|
|
3
3
|
import { UUID } from 'crypto';
|
|
4
4
|
|
|
@@ -10,10 +10,10 @@ export interface CriteriaBasedFilterEditionDialogProps {
|
|
|
10
10
|
onClose: () => void;
|
|
11
11
|
broadcastChannel: BroadcastChannel;
|
|
12
12
|
getFilterById: (id: string) => Promise<any>;
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
itemSelectionForCopy: ItemSelectionForCopy;
|
|
14
|
+
setItemSelectionForCopy: (selection: ItemSelectionForCopy) => void;
|
|
15
15
|
activeDirectory?: UUID;
|
|
16
16
|
elementExists?: ElementExistsType;
|
|
17
17
|
language?: string;
|
|
18
18
|
}
|
|
19
|
-
export declare function CriteriaBasedFilterEditionDialog({ id, name, titleId, open, onClose, broadcastChannel, getFilterById,
|
|
19
|
+
export declare function CriteriaBasedFilterEditionDialog({ id, name, titleId, open, onClose, broadcastChannel, getFilterById, itemSelectionForCopy, setItemSelectionForCopy, activeDirectory, elementExists, language, }: Readonly<CriteriaBasedFilterEditionDialogProps>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -9,7 +9,7 @@ import { FieldConstants } from "../../../utils/constants/fieldConstants.js";
|
|
|
9
9
|
import "../../../utils/yupConfig.js";
|
|
10
10
|
import { CustomMuiDialog } from "../../dialogs/customMuiDialog/CustomMuiDialog.js";
|
|
11
11
|
import { FilterForm } from "../FilterForm.js";
|
|
12
|
-
import { FilterType,
|
|
12
|
+
import { FilterType, NO_ITEM_SELECTION_FOR_COPY } from "../constants/FilterConstants.js";
|
|
13
13
|
import { criteriaBasedFilterSchema } from "./CriteriaBasedFilterForm.js";
|
|
14
14
|
import { backToFrontTweak, frontToBackTweak } from "./criteriaBasedFilterUtils.js";
|
|
15
15
|
import * as yup from "yup";
|
|
@@ -27,8 +27,8 @@ function CriteriaBasedFilterEditionDialog({
|
|
|
27
27
|
onClose,
|
|
28
28
|
broadcastChannel,
|
|
29
29
|
getFilterById,
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
itemSelectionForCopy,
|
|
31
|
+
setItemSelectionForCopy,
|
|
32
32
|
activeDirectory,
|
|
33
33
|
elementExists,
|
|
34
34
|
language
|
|
@@ -67,11 +67,9 @@ function CriteriaBasedFilterEditionDialog({
|
|
|
67
67
|
const onSubmit = useCallback(
|
|
68
68
|
(filterForm) => {
|
|
69
69
|
saveFilter(frontToBackTweak(id, filterForm), filterForm[FieldConstants.NAME]).then(() => {
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
broadcastChannel.postMessage({
|
|
73
|
-
NO_SELECTION_FOR_COPY
|
|
74
|
-
});
|
|
70
|
+
if (itemSelectionForCopy.sourceItemUuid === id) {
|
|
71
|
+
setItemSelectionForCopy(NO_ITEM_SELECTION_FOR_COPY);
|
|
72
|
+
broadcastChannel.postMessage({ NO_SELECTION_FOR_COPY: NO_ITEM_SELECTION_FOR_COPY });
|
|
75
73
|
}
|
|
76
74
|
}).catch((error) => {
|
|
77
75
|
snackError({
|
|
@@ -79,7 +77,7 @@ function CriteriaBasedFilterEditionDialog({
|
|
|
79
77
|
});
|
|
80
78
|
});
|
|
81
79
|
},
|
|
82
|
-
[broadcastChannel, id,
|
|
80
|
+
[broadcastChannel, id, itemSelectionForCopy.sourceItemUuid, snackError, setItemSelectionForCopy]
|
|
83
81
|
);
|
|
84
82
|
const isDataReady = dataFetchStatus === FetchStatus.FETCH_SUCCESS;
|
|
85
83
|
return /* @__PURE__ */ jsx(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ItemSelectionForCopy } from '../filter.type';
|
|
2
2
|
import { ElementExistsType } from '../../../utils/types/elementType';
|
|
3
3
|
import { UUID } from 'crypto';
|
|
4
4
|
|
|
@@ -9,13 +9,13 @@ export interface ExpertFilterEditionDialogProps {
|
|
|
9
9
|
open: boolean;
|
|
10
10
|
onClose: () => void;
|
|
11
11
|
broadcastChannel: BroadcastChannel;
|
|
12
|
-
|
|
12
|
+
itemSelectionForCopy: ItemSelectionForCopy;
|
|
13
|
+
setItemSelectionForCopy: (selection: ItemSelectionForCopy) => void;
|
|
13
14
|
getFilterById: (id: string) => Promise<{
|
|
14
15
|
[prop: string]: any;
|
|
15
16
|
}>;
|
|
16
|
-
setSelectionForCopy: (selection: SelectionForCopy) => void;
|
|
17
17
|
activeDirectory?: UUID;
|
|
18
18
|
elementExists?: ElementExistsType;
|
|
19
19
|
language?: string;
|
|
20
20
|
}
|
|
21
|
-
export declare function ExpertFilterEditionDialog({ id, name, titleId, open, onClose, broadcastChannel,
|
|
21
|
+
export declare function ExpertFilterEditionDialog({ id, name, titleId, open, onClose, broadcastChannel, itemSelectionForCopy, getFilterById, setItemSelectionForCopy, activeDirectory, elementExists, language, }: Readonly<ExpertFilterEditionDialogProps>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -7,7 +7,7 @@ import { FetchStatus } from "../../../utils/constants/fetchStatus.js";
|
|
|
7
7
|
import { FieldConstants } from "../../../utils/constants/fieldConstants.js";
|
|
8
8
|
import "../../../utils/yupConfig.js";
|
|
9
9
|
import { CustomMuiDialog } from "../../dialogs/customMuiDialog/CustomMuiDialog.js";
|
|
10
|
-
import { FilterType,
|
|
10
|
+
import { FilterType, NO_ITEM_SELECTION_FOR_COPY } from "../constants/FilterConstants.js";
|
|
11
11
|
import { FilterForm } from "../FilterForm.js";
|
|
12
12
|
import { saveExpertFilter } from "../utils/filterApi.js";
|
|
13
13
|
import { expertFilterSchema, EXPERT_FILTER_QUERY } from "./ExpertFilterForm.js";
|
|
@@ -26,9 +26,9 @@ function ExpertFilterEditionDialog({
|
|
|
26
26
|
open,
|
|
27
27
|
onClose,
|
|
28
28
|
broadcastChannel,
|
|
29
|
-
|
|
29
|
+
itemSelectionForCopy,
|
|
30
30
|
getFilterById,
|
|
31
|
-
|
|
31
|
+
setItemSelectionForCopy,
|
|
32
32
|
activeDirectory,
|
|
33
33
|
elementExists,
|
|
34
34
|
language
|
|
@@ -83,14 +83,12 @@ function ExpertFilterEditionDialog({
|
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
85
|
);
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
broadcastChannel.postMessage({
|
|
89
|
-
NO_SELECTION_FOR_COPY
|
|
90
|
-
});
|
|
86
|
+
if (itemSelectionForCopy.sourceItemUuid === id) {
|
|
87
|
+
setItemSelectionForCopy(NO_ITEM_SELECTION_FOR_COPY);
|
|
88
|
+
broadcastChannel.postMessage({ NO_SELECTION_FOR_COPY: NO_ITEM_SELECTION_FOR_COPY });
|
|
91
89
|
}
|
|
92
90
|
},
|
|
93
|
-
[broadcastChannel, id, onClose,
|
|
91
|
+
[broadcastChannel, id, onClose, itemSelectionForCopy.sourceItemUuid, snackError, setItemSelectionForCopy]
|
|
94
92
|
);
|
|
95
93
|
const isDataReady = dataFetchStatus === FetchStatus.FETCH_SUCCESS;
|
|
96
94
|
return /* @__PURE__ */ jsx(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ItemSelectionForCopy } from '../filter.type';
|
|
2
2
|
import { ElementExistsType } from '../../../utils/types/elementType';
|
|
3
3
|
import { UUID } from 'crypto';
|
|
4
4
|
|
|
@@ -9,11 +9,11 @@ export interface ExplicitNamingFilterEditionDialogProps {
|
|
|
9
9
|
open: boolean;
|
|
10
10
|
onClose: () => void;
|
|
11
11
|
broadcastChannel: BroadcastChannel;
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
itemSelectionForCopy: ItemSelectionForCopy;
|
|
13
|
+
setItemSelectionForCopy: (selection: ItemSelectionForCopy) => void;
|
|
14
14
|
getFilterById: (id: string) => Promise<any>;
|
|
15
15
|
activeDirectory?: UUID;
|
|
16
16
|
elementExists?: ElementExistsType;
|
|
17
17
|
language?: string;
|
|
18
18
|
}
|
|
19
|
-
export declare function ExplicitNamingFilterEditionDialog({ id, name, titleId, open, onClose, broadcastChannel,
|
|
19
|
+
export declare function ExplicitNamingFilterEditionDialog({ id, name, titleId, open, onClose, broadcastChannel, itemSelectionForCopy, setItemSelectionForCopy, getFilterById, activeDirectory, elementExists, language, }: Readonly<ExplicitNamingFilterEditionDialogProps>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -12,7 +12,7 @@ import { saveExplicitNamingFilter } from "../utils/filterApi.js";
|
|
|
12
12
|
import { explicitNamingFilterSchema, FILTER_EQUIPMENTS_ATTRIBUTES } from "./ExplicitNamingFilterForm.js";
|
|
13
13
|
import { FetchStatus } from "../../../utils/constants/fetchStatus.js";
|
|
14
14
|
import { FilterForm } from "../FilterForm.js";
|
|
15
|
-
import { FilterType,
|
|
15
|
+
import { FilterType, NO_ITEM_SELECTION_FOR_COPY } from "../constants/FilterConstants.js";
|
|
16
16
|
import * as yup from "yup";
|
|
17
17
|
const formSchema = yup.object().shape({
|
|
18
18
|
[FieldConstants.NAME]: yup.string().trim().required("nameEmpty"),
|
|
@@ -27,8 +27,8 @@ function ExplicitNamingFilterEditionDialog({
|
|
|
27
27
|
open,
|
|
28
28
|
onClose,
|
|
29
29
|
broadcastChannel,
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
itemSelectionForCopy,
|
|
31
|
+
setItemSelectionForCopy,
|
|
32
32
|
getFilterById,
|
|
33
33
|
activeDirectory,
|
|
34
34
|
elementExists,
|
|
@@ -86,14 +86,12 @@ function ExplicitNamingFilterEditionDialog({
|
|
|
86
86
|
},
|
|
87
87
|
onClose
|
|
88
88
|
);
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
broadcastChannel.postMessage({
|
|
92
|
-
NO_SELECTION_FOR_COPY
|
|
93
|
-
});
|
|
89
|
+
if (itemSelectionForCopy.sourceItemUuid === id) {
|
|
90
|
+
setItemSelectionForCopy(NO_ITEM_SELECTION_FOR_COPY);
|
|
91
|
+
broadcastChannel.postMessage({ NO_SELECTION_FOR_COPY: NO_ITEM_SELECTION_FOR_COPY });
|
|
94
92
|
}
|
|
95
93
|
},
|
|
96
|
-
[broadcastChannel, id,
|
|
94
|
+
[broadcastChannel, id, itemSelectionForCopy, onClose, snackError, setItemSelectionForCopy]
|
|
97
95
|
);
|
|
98
96
|
const isDataReady = dataFetchStatus === FetchStatus.FETCH_SUCCESS;
|
|
99
97
|
return /* @__PURE__ */ jsx(
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
+
import { UUID } from 'crypto';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
3
|
-
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
-
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
-
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
4
|
+
* Represent an item/object in directories.
|
|
6
5
|
*/
|
|
7
|
-
export type
|
|
8
|
-
sourceItemUuid:
|
|
6
|
+
export type ItemSelectionForCopy = {
|
|
7
|
+
sourceItemUuid: UUID | null;
|
|
9
8
|
typeItem: string | null;
|
|
10
9
|
nameItem: string | null;
|
|
11
10
|
descriptionItem: string | null;
|
|
12
|
-
parentDirectoryUuid:
|
|
11
|
+
parentDirectoryUuid: UUID | null;
|
|
13
12
|
specificTypeItem: string | null;
|
|
14
13
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FilterCreationDialog } from "./FilterCreationDialog.js";
|
|
2
2
|
import { FilterForm } from "./FilterForm.js";
|
|
3
|
-
import { DISTRIBUTION_KEY, FilterType,
|
|
3
|
+
import { DISTRIBUTION_KEY, FilterType, NO_ITEM_SELECTION_FOR_COPY } from "./constants/FilterConstants.js";
|
|
4
4
|
import { CriteriaBasedFilterEditionDialog } from "./criteriaBased/CriteriaBasedFilterEditionDialog.js";
|
|
5
5
|
import { CriteriaBasedFilterForm, criteriaBasedFilterEmptyFormData, criteriaBasedFilterSchema } from "./criteriaBased/CriteriaBasedFilterForm.js";
|
|
6
6
|
import { CriteriaBasedForm } from "./criteriaBased/CriteriaBasedForm.js";
|
|
@@ -47,7 +47,7 @@ export {
|
|
|
47
47
|
FilterType,
|
|
48
48
|
FreePropertiesTypes,
|
|
49
49
|
LOAD_TYPE_OPTIONS,
|
|
50
|
-
|
|
50
|
+
NO_ITEM_SELECTION_FOR_COPY,
|
|
51
51
|
OPERATOR_OPTIONS,
|
|
52
52
|
OperatorType,
|
|
53
53
|
PHASE_REGULATION_MODE_OPTIONS,
|
package/dist/components/index.js
CHANGED
|
@@ -25,7 +25,7 @@ import { useElementSearch } from "./elementSearch/hooks/useElementSearch.js";
|
|
|
25
25
|
import { TagRenderer } from "./elementSearch/tagRenderer/TagRenderer.js";
|
|
26
26
|
import { FilterCreationDialog } from "./filter/FilterCreationDialog.js";
|
|
27
27
|
import { FilterForm } from "./filter/FilterForm.js";
|
|
28
|
-
import { DISTRIBUTION_KEY, FilterType,
|
|
28
|
+
import { DISTRIBUTION_KEY, FilterType, NO_ITEM_SELECTION_FOR_COPY } from "./filter/constants/FilterConstants.js";
|
|
29
29
|
import { CriteriaBasedFilterEditionDialog } from "./filter/criteriaBased/CriteriaBasedFilterEditionDialog.js";
|
|
30
30
|
import { CriteriaBasedFilterForm, criteriaBasedFilterEmptyFormData, criteriaBasedFilterSchema } from "./filter/criteriaBased/CriteriaBasedFilterForm.js";
|
|
31
31
|
import { CriteriaBasedForm } from "./filter/criteriaBased/CriteriaBasedForm.js";
|
|
@@ -104,6 +104,10 @@ import { TopBar } from "./topBar/TopBar.js";
|
|
|
104
104
|
import { GridLogo, LogoText } from "./topBar/GridLogo.js";
|
|
105
105
|
import { AboutDialog } from "./topBar/AboutDialog.js";
|
|
106
106
|
import { TreeViewFinder, generateTreeViewFinderClass } from "./treeViewFinder/TreeViewFinder.js";
|
|
107
|
+
import { NotificationsProvider } from "./notifications/NotificationsProvider.js";
|
|
108
|
+
import { NotificationsContext } from "./notifications/contexts/NotificationsContext.js";
|
|
109
|
+
import { useNotificationsListener } from "./notifications/hooks/useNotificationsListener.js";
|
|
110
|
+
import { useListenerManager } from "./notifications/hooks/useListenerManager.js";
|
|
107
111
|
export {
|
|
108
112
|
AboutDialog,
|
|
109
113
|
AddButton,
|
|
@@ -193,7 +197,9 @@ export {
|
|
|
193
197
|
MultipleAutocompleteInput,
|
|
194
198
|
MultipleSelectionDialog,
|
|
195
199
|
NAME,
|
|
196
|
-
|
|
200
|
+
NO_ITEM_SELECTION_FOR_COPY,
|
|
201
|
+
NotificationsContext,
|
|
202
|
+
NotificationsProvider,
|
|
197
203
|
NumericEditor,
|
|
198
204
|
OPERATOR_OPTIONS,
|
|
199
205
|
OperatorType,
|
|
@@ -289,5 +295,7 @@ export {
|
|
|
289
295
|
useConvertValue,
|
|
290
296
|
useCustomFormContext,
|
|
291
297
|
useElementSearch,
|
|
298
|
+
useListenerManager,
|
|
299
|
+
useNotificationsListener,
|
|
292
300
|
useValid
|
|
293
301
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
|
|
3
|
+
export type NotificationsProviderProps = {
|
|
4
|
+
urls: Record<string, string>;
|
|
5
|
+
};
|
|
6
|
+
export declare function NotificationsProvider({ urls, children }: PropsWithChildren<NotificationsProviderProps>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo } from "react";
|
|
3
|
+
import ReconnectingWebSocket from "reconnecting-websocket";
|
|
4
|
+
import { NotificationsContext } from "./contexts/NotificationsContext.js";
|
|
5
|
+
import { useListenerManager } from "./hooks/useListenerManager.js";
|
|
6
|
+
const DELAY_BEFORE_WEBSOCKET_CONNECTED = 12e3;
|
|
7
|
+
function NotificationsProvider({ urls, children }) {
|
|
8
|
+
const {
|
|
9
|
+
broadcast: broadcastMessage,
|
|
10
|
+
addListener: addListenerMessage,
|
|
11
|
+
removeListener: removeListenerMessage
|
|
12
|
+
} = useListenerManager(urls);
|
|
13
|
+
const {
|
|
14
|
+
broadcast: broadcastOnReopen,
|
|
15
|
+
addListener: addListenerOnReopen,
|
|
16
|
+
removeListener: removeListenerOnReopen
|
|
17
|
+
} = useListenerManager(urls);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
const connections = Object.keys(urls).filter((u) => urls[u] != null).map((urlKey) => {
|
|
20
|
+
const rws = new ReconnectingWebSocket(() => urls[urlKey], [], {
|
|
21
|
+
// this option set the minimum duration being connected before reset the retry count to 0
|
|
22
|
+
minUptime: DELAY_BEFORE_WEBSOCKET_CONNECTED
|
|
23
|
+
});
|
|
24
|
+
rws.onmessage = broadcastMessage(urlKey);
|
|
25
|
+
rws.onclose = (event) => {
|
|
26
|
+
console.error(`Unexpected ${urlKey} Notification WebSocket closed`, event);
|
|
27
|
+
};
|
|
28
|
+
rws.onerror = (event) => {
|
|
29
|
+
console.error(`Unexpected ${urlKey} Notification WebSocket error`, event);
|
|
30
|
+
};
|
|
31
|
+
rws.onopen = () => {
|
|
32
|
+
console.info(`${urlKey} Notification Websocket connected`);
|
|
33
|
+
broadcastOnReopen(urlKey);
|
|
34
|
+
};
|
|
35
|
+
return rws;
|
|
36
|
+
});
|
|
37
|
+
return () => {
|
|
38
|
+
connections.forEach((c) => c.close());
|
|
39
|
+
};
|
|
40
|
+
}, [broadcastMessage, broadcastOnReopen, urls]);
|
|
41
|
+
const contextValue = useMemo(
|
|
42
|
+
() => ({
|
|
43
|
+
addListenerEvent: addListenerMessage,
|
|
44
|
+
removeListenerEvent: removeListenerMessage,
|
|
45
|
+
addListenerOnReopen,
|
|
46
|
+
removeListenerOnReopen
|
|
47
|
+
}),
|
|
48
|
+
[addListenerMessage, removeListenerMessage, addListenerOnReopen, removeListenerOnReopen]
|
|
49
|
+
);
|
|
50
|
+
return /* @__PURE__ */ jsx(NotificationsContext.Provider, { value: contextValue, children });
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
NotificationsProvider
|
|
54
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2024, RTE (http://www.rte-france.com)
|
|
3
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
6
|
+
*/
|
|
7
|
+
/// <reference types="react" />
|
|
8
|
+
export type ListenerEventWS = {
|
|
9
|
+
id: string;
|
|
10
|
+
callback: (event: MessageEvent) => void;
|
|
11
|
+
};
|
|
12
|
+
export type ListenerOnReopen = {
|
|
13
|
+
id: string;
|
|
14
|
+
callback: () => void;
|
|
15
|
+
};
|
|
16
|
+
export type NotificationsContextType = {
|
|
17
|
+
addListenerEvent: (urlKey: string, l: ListenerEventWS) => void;
|
|
18
|
+
removeListenerEvent: (urlKey: string, idListener: string) => void;
|
|
19
|
+
addListenerOnReopen: (urlKey: string, l: ListenerOnReopen) => void;
|
|
20
|
+
removeListenerOnReopen: (urlKey: string, idListener: string) => void;
|
|
21
|
+
};
|
|
22
|
+
export type NotificationsContextRecordType = Record<string, NotificationsContextType>;
|
|
23
|
+
export declare const NotificationsContext: import('react').Context<NotificationsContextType>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
const NotificationsContext = createContext({
|
|
3
|
+
addListenerEvent: () => {
|
|
4
|
+
},
|
|
5
|
+
removeListenerEvent: () => {
|
|
6
|
+
},
|
|
7
|
+
addListenerOnReopen: () => {
|
|
8
|
+
},
|
|
9
|
+
removeListenerOnReopen: () => {
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
export {
|
|
13
|
+
NotificationsContext
|
|
14
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ListenerEventWS, ListenerOnReopen } from '../contexts/NotificationsContext';
|
|
2
|
+
|
|
3
|
+
export declare const useListenerManager: <TListener extends ListenerEventWS | ListenerOnReopen, TMessage extends MessageEvent<any>>(urls: Record<string, string>) => {
|
|
4
|
+
addListener: (urlKey: string, listener: TListener) => void;
|
|
5
|
+
removeListener: (urlKey: string, id: string) => void;
|
|
6
|
+
broadcast: (urlKey: string) => (event: TMessage) => void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useRef, useEffect, useCallback } from "react";
|
|
2
|
+
const useListenerManager = (urls) => {
|
|
3
|
+
const urlsListenersRef = useRef({});
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
urlsListenersRef.current = Object.keys(urls).reduce((acc, urlKey) => {
|
|
6
|
+
acc[urlKey] = urlsListenersRef.current[urlKey] ?? [];
|
|
7
|
+
return acc;
|
|
8
|
+
}, {});
|
|
9
|
+
}, [urls]);
|
|
10
|
+
const addListenerEvent = useCallback((urlKey, listener) => {
|
|
11
|
+
const urlsListeners = urlsListenersRef.current;
|
|
12
|
+
if (urlKey in urlsListeners) {
|
|
13
|
+
urlsListeners[urlKey].push(listener);
|
|
14
|
+
} else {
|
|
15
|
+
urlsListeners[urlKey] = [listener];
|
|
16
|
+
}
|
|
17
|
+
urlsListenersRef.current = urlsListeners;
|
|
18
|
+
}, []);
|
|
19
|
+
const removeListenerEvent = useCallback((urlKey, id) => {
|
|
20
|
+
var _a;
|
|
21
|
+
const listeners = (_a = urlsListenersRef.current) == null ? void 0 : _a[urlKey];
|
|
22
|
+
if (listeners) {
|
|
23
|
+
const newListerners = listeners.filter((l) => l.id !== id);
|
|
24
|
+
urlsListenersRef.current = {
|
|
25
|
+
...urlsListenersRef.current,
|
|
26
|
+
[urlKey]: newListerners
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}, []);
|
|
30
|
+
const broadcast = useCallback(
|
|
31
|
+
(urlKey) => (event) => {
|
|
32
|
+
var _a;
|
|
33
|
+
const listeners = (_a = urlsListenersRef.current) == null ? void 0 : _a[urlKey];
|
|
34
|
+
if (listeners) {
|
|
35
|
+
listeners.forEach(({ callback }) => {
|
|
36
|
+
callback(event);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
[]
|
|
41
|
+
);
|
|
42
|
+
return {
|
|
43
|
+
addListener: addListenerEvent,
|
|
44
|
+
removeListener: removeListenerEvent,
|
|
45
|
+
broadcast
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
export {
|
|
49
|
+
useListenerManager
|
|
50
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2024, RTE (http://www.rte-france.com)
|
|
3
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
5
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
6
|
+
*/
|
|
7
|
+
export declare const useNotificationsListener: (listenerKey: string, { listenerCallbackMessage, listenerCallbackOnReopen, propsId, }: {
|
|
8
|
+
listenerCallbackMessage?: ((event: MessageEvent<any>) => void) | undefined;
|
|
9
|
+
listenerCallbackOnReopen?: (() => void) | undefined;
|
|
10
|
+
propsId?: string | undefined;
|
|
11
|
+
}) => void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useContext, useEffect } from "react";
|
|
2
|
+
import { v4 } from "uuid";
|
|
3
|
+
import { NotificationsContext } from "../contexts/NotificationsContext.js";
|
|
4
|
+
const useNotificationsListener = (listenerKey, {
|
|
5
|
+
listenerCallbackMessage,
|
|
6
|
+
listenerCallbackOnReopen,
|
|
7
|
+
propsId
|
|
8
|
+
}) => {
|
|
9
|
+
const { addListenerEvent, removeListenerEvent, addListenerOnReopen, removeListenerOnReopen } = useContext(NotificationsContext);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const id = propsId ?? v4();
|
|
12
|
+
if (listenerCallbackMessage) {
|
|
13
|
+
addListenerEvent(listenerKey, {
|
|
14
|
+
id,
|
|
15
|
+
callback: listenerCallbackMessage
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return () => removeListenerEvent(listenerKey, id);
|
|
19
|
+
}, [addListenerEvent, removeListenerEvent, listenerKey, listenerCallbackMessage, propsId]);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
const id = propsId ?? v4();
|
|
22
|
+
if (listenerCallbackOnReopen) {
|
|
23
|
+
addListenerOnReopen(listenerKey, {
|
|
24
|
+
id,
|
|
25
|
+
callback: listenerCallbackOnReopen
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return () => removeListenerOnReopen(listenerKey, id);
|
|
29
|
+
}, [addListenerOnReopen, removeListenerOnReopen, listenerKey, listenerCallbackOnReopen, propsId]);
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
useNotificationsListener
|
|
33
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NotificationsProvider } from "./NotificationsProvider.js";
|
|
2
|
+
import { NotificationsContext } from "./contexts/NotificationsContext.js";
|
|
3
|
+
import { useNotificationsListener } from "./hooks/useNotificationsListener.js";
|
|
4
|
+
import { useListenerManager } from "./hooks/useListenerManager.js";
|
|
5
|
+
export {
|
|
6
|
+
NotificationsContext,
|
|
7
|
+
NotificationsProvider,
|
|
8
|
+
useListenerManager,
|
|
9
|
+
useNotificationsListener
|
|
10
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -26,7 +26,7 @@ import { useElementSearch } from "./components/elementSearch/hooks/useElementSea
|
|
|
26
26
|
import { TagRenderer } from "./components/elementSearch/tagRenderer/TagRenderer.js";
|
|
27
27
|
import { FilterCreationDialog } from "./components/filter/FilterCreationDialog.js";
|
|
28
28
|
import { FilterForm } from "./components/filter/FilterForm.js";
|
|
29
|
-
import { DISTRIBUTION_KEY, FilterType,
|
|
29
|
+
import { DISTRIBUTION_KEY, FilterType, NO_ITEM_SELECTION_FOR_COPY } from "./components/filter/constants/FilterConstants.js";
|
|
30
30
|
import { CriteriaBasedFilterEditionDialog } from "./components/filter/criteriaBased/CriteriaBasedFilterEditionDialog.js";
|
|
31
31
|
import { CriteriaBasedFilterForm, criteriaBasedFilterEmptyFormData, criteriaBasedFilterSchema } from "./components/filter/criteriaBased/CriteriaBasedFilterForm.js";
|
|
32
32
|
import { CriteriaBasedForm } from "./components/filter/criteriaBased/CriteriaBasedForm.js";
|
|
@@ -105,6 +105,10 @@ import { TopBar } from "./components/topBar/TopBar.js";
|
|
|
105
105
|
import { GridLogo, LogoText } from "./components/topBar/GridLogo.js";
|
|
106
106
|
import { AboutDialog } from "./components/topBar/AboutDialog.js";
|
|
107
107
|
import { TreeViewFinder, generateTreeViewFinderClass } from "./components/treeViewFinder/TreeViewFinder.js";
|
|
108
|
+
import { NotificationsProvider } from "./components/notifications/NotificationsProvider.js";
|
|
109
|
+
import { NotificationsContext } from "./components/notifications/contexts/NotificationsContext.js";
|
|
110
|
+
import { useNotificationsListener } from "./components/notifications/hooks/useNotificationsListener.js";
|
|
111
|
+
import { useListenerManager } from "./components/notifications/hooks/useListenerManager.js";
|
|
108
112
|
import { useStateBoolean } from "./hooks/customStates/useStateBoolean.js";
|
|
109
113
|
import { useStateNumber } from "./hooks/customStates/useStateNumber.js";
|
|
110
114
|
import { useModificationLabelComputer } from "./hooks/useModificationLabelComputer.js";
|
|
@@ -290,7 +294,9 @@ export {
|
|
|
290
294
|
MultipleAutocompleteInput,
|
|
291
295
|
MultipleSelectionDialog,
|
|
292
296
|
NAME,
|
|
293
|
-
|
|
297
|
+
NO_ITEM_SELECTION_FOR_COPY,
|
|
298
|
+
NotificationsContext,
|
|
299
|
+
NotificationsProvider,
|
|
294
300
|
NumericEditor,
|
|
295
301
|
OPERATOR_OPTIONS,
|
|
296
302
|
OperatingStatus,
|
|
@@ -494,8 +500,10 @@ export {
|
|
|
494
500
|
useDebounce,
|
|
495
501
|
useElementSearch,
|
|
496
502
|
useIntlRef,
|
|
503
|
+
useListenerManager,
|
|
497
504
|
useLocalizedCountries,
|
|
498
505
|
useModificationLabelComputer,
|
|
506
|
+
useNotificationsListener,
|
|
499
507
|
usePredefinedProperties,
|
|
500
508
|
usePrevious,
|
|
501
509
|
useSnackMessage,
|
|
@@ -8,7 +8,7 @@ export type Env = {
|
|
|
8
8
|
};
|
|
9
9
|
export declare function fetchEnv(): Promise<Env>;
|
|
10
10
|
export declare function fetchAppsMetadata(): Promise<Metadata[]>;
|
|
11
|
-
export declare
|
|
11
|
+
export declare function isStudyMetadata(metadata: Metadata): metadata is StudyMetadata;
|
|
12
12
|
export declare function fetchStudyMetadata(): Promise<StudyMetadata>;
|
|
13
13
|
export declare function fetchFavoriteAndDefaultCountries(): Promise<{
|
|
14
14
|
favoriteCountries: string[];
|
|
@@ -7,9 +7,9 @@ async function fetchAppsMetadata() {
|
|
|
7
7
|
const res = await fetch(`${env.appsMetadataServerUrl}/apps-metadata.json`);
|
|
8
8
|
return res.json();
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
function isStudyMetadata(metadata) {
|
|
11
11
|
return metadata.name === "Study";
|
|
12
|
-
}
|
|
12
|
+
}
|
|
13
13
|
async function fetchStudyMetadata() {
|
|
14
14
|
console.info(`Fetching study metadata...`);
|
|
15
15
|
const studyMetadata = (await fetchAppsMetadata()).filter(isStudyMetadata);
|
|
@@ -58,5 +58,5 @@ export declare const networkModificationsEn: {
|
|
|
58
58
|
'network_modifications.TABULAR_CREATION': string;
|
|
59
59
|
'network_modifications.tabular.GENERATOR_CREATION': string;
|
|
60
60
|
'network_modifications.LCC_CREATION': string;
|
|
61
|
-
'network_modifications.
|
|
61
|
+
'network_modifications.STATIC_VAR_COMPENSATOR_CREATION': string;
|
|
62
62
|
};
|
|
@@ -52,7 +52,7 @@ const networkModificationsEn = {
|
|
|
52
52
|
"network_modifications.TABULAR_CREATION": "Tabular creation - {computedLabel}",
|
|
53
53
|
"network_modifications.tabular.GENERATOR_CREATION": "generator creations",
|
|
54
54
|
"network_modifications.LCC_CREATION": "Creating HVDC (LCC) {computedLabel}",
|
|
55
|
-
"network_modifications.
|
|
55
|
+
"network_modifications.STATIC_VAR_COMPENSATOR_CREATION": "Creating static var compensator {computedLabel}"
|
|
56
56
|
};
|
|
57
57
|
export {
|
|
58
58
|
networkModificationsEn
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Calculate, Settings, Article, NoteAlt, OfflineBolt, Photo, PhotoLibrary } from "@mui/icons-material";
|
|
2
|
+
import { TableView, Calculate, Settings, Article, NoteAlt, OfflineBolt, Photo, PhotoLibrary } from "@mui/icons-material";
|
|
3
3
|
import { ElementType } from "../types/elementType.js";
|
|
4
4
|
function getFileIcon(type, style) {
|
|
5
5
|
switch (type) {
|
|
@@ -22,6 +22,8 @@ function getFileIcon(type, style) {
|
|
|
22
22
|
return /* @__PURE__ */ jsx(Settings, { sx: style });
|
|
23
23
|
case ElementType.SPREADSHEET_CONFIG:
|
|
24
24
|
return /* @__PURE__ */ jsx(Calculate, { sx: style });
|
|
25
|
+
case ElementType.SPREADSHEET_CONFIG_COLLECTION:
|
|
26
|
+
return /* @__PURE__ */ jsx(TableView, { sx: style });
|
|
25
27
|
case ElementType.DIRECTORY:
|
|
26
28
|
return void 0;
|
|
27
29
|
default:
|
|
@@ -13,6 +13,7 @@ export declare enum ElementType {
|
|
|
13
13
|
LOADFLOW_PARAMETERS = "LOADFLOW_PARAMETERS",
|
|
14
14
|
SENSITIVITY_PARAMETERS = "SENSITIVITY_PARAMETERS",
|
|
15
15
|
SHORT_CIRCUIT_PARAMETERS = "SHORT_CIRCUIT_PARAMETERS",
|
|
16
|
-
SPREADSHEET_CONFIG = "SPREADSHEET_CONFIG"
|
|
16
|
+
SPREADSHEET_CONFIG = "SPREADSHEET_CONFIG",
|
|
17
|
+
SPREADSHEET_CONFIG_COLLECTION = "SPREADSHEET_CONFIG_COLLECTION"
|
|
17
18
|
}
|
|
18
19
|
export type ElementExistsType = (directory: UUID, value: string, elementType: ElementType) => Promise<boolean>;
|
|
@@ -12,6 +12,7 @@ var ElementType = /* @__PURE__ */ ((ElementType2) => {
|
|
|
12
12
|
ElementType2["SENSITIVITY_PARAMETERS"] = "SENSITIVITY_PARAMETERS";
|
|
13
13
|
ElementType2["SHORT_CIRCUIT_PARAMETERS"] = "SHORT_CIRCUIT_PARAMETERS";
|
|
14
14
|
ElementType2["SPREADSHEET_CONFIG"] = "SPREADSHEET_CONFIG";
|
|
15
|
+
ElementType2["SPREADSHEET_CONFIG_COLLECTION"] = "SPREADSHEET_CONFIG_COLLECTION";
|
|
15
16
|
return ElementType2;
|
|
16
17
|
})(ElementType || {});
|
|
17
18
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridsuite/commons-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.75.0",
|
|
4
4
|
"description": "common react components for gridsuite applications",
|
|
5
5
|
"engines": {
|
|
6
6
|
"npm": ">=9",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"react-dnd-html5-backend": "^16.0.1",
|
|
44
44
|
"react-querybuilder": "^7.2.0",
|
|
45
45
|
"react-virtualized": "^9.22.5",
|
|
46
|
+
"reconnecting-websocket": "^4.4.0",
|
|
46
47
|
"uuid": "^9.0.1"
|
|
47
48
|
},
|
|
48
49
|
"peerDependencies": {
|