@gridsuite/commons-ui 0.74.0 → 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/index.d.ts +1 -0
- package/dist/components/index.js +8 -0
- 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 +8 -0
- 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
package/dist/components/index.js
CHANGED
|
@@ -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,
|
|
@@ -194,6 +198,8 @@ export {
|
|
|
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
|
@@ -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";
|
|
@@ -291,6 +295,8 @@ export {
|
|
|
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,
|
|
@@ -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": {
|