wenay-react2 1.0.20 → 1.0.21
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/README.md +383 -382
- package/lib/common/api.d.ts +28 -0
- package/lib/common/api.js +41 -16
- package/lib/common/src/components/Buttons/MiniButton.d.ts +1 -0
- package/lib/common/src/components/Buttons/MiniButton.js +2 -2
- package/lib/common/src/components/Dnd/DraggableOutlineDiv.d.ts +1 -0
- package/lib/common/src/components/Dnd/DraggableOutlineDiv.js +7 -6
- package/lib/common/src/components/Dnd/RNDFunc.js +28 -17
- package/lib/common/src/components/Dnd/RNDFunc3.d.ts +27 -17
- package/lib/common/src/components/Dnd/RNDFunc3.js +107 -105
- package/lib/common/src/components/Dnd/Resizable.js +3 -3
- package/lib/common/src/components/Menu/RightMenu.js +11 -17
- package/lib/common/src/components/Menu/StickerMenu.js +42 -28
- package/lib/common/src/components/Menu/index.d.ts +1 -1
- package/lib/common/src/components/Menu/index.js +1 -1
- package/lib/common/src/components/Modal/LeftModal.d.ts +14 -12
- package/lib/common/src/components/Modal/LeftModal.js +30 -16
- package/lib/common/src/components/Modal/Modal.d.ts +26 -12
- package/lib/common/src/components/Modal/Modal.js +66 -89
- package/lib/common/src/components/Modal/ModalContextProvider.d.ts +20 -3
- package/lib/common/src/components/Modal/ModalContextProvider.js +35 -8
- package/lib/common/src/components/MyResizeObserver.js +15 -18
- package/lib/common/src/components/Other.js +3 -2
- package/lib/common/src/components/Parameters.js +7 -6
- package/lib/common/src/components/ParametersEngine.js +25 -54
- package/lib/common/src/grid/agGrid4/agGrid4.d.ts +53 -0
- package/lib/common/src/grid/agGrid4/agGrid4.js +132 -0
- package/lib/common/src/grid/agGrid4/core.d.ts +56 -0
- package/lib/common/src/grid/agGrid4/core.js +127 -0
- package/lib/common/src/grid/agGrid4/index.d.ts +6 -0
- package/lib/common/src/grid/agGrid4/index.js +3 -0
- package/lib/common/src/grid/agGrid4/theme.d.ts +7 -0
- package/lib/common/src/grid/agGrid4/theme.js +18 -0
- package/lib/common/src/hooks/useAddDownAnyKey.d.ts +21 -2
- package/lib/common/src/hooks/useAddDownAnyKey.js +46 -8
- package/lib/common/src/hooks/useDraggable.d.ts +20 -2
- package/lib/common/src/hooks/useDraggable.js +146 -115
- package/lib/common/src/hooks/useOutside.d.ts +24 -4
- package/lib/common/src/hooks/useOutside.js +76 -27
- package/lib/common/src/logs/logs.d.ts +5 -2
- package/lib/common/src/logs/logs.js +15 -31
- package/lib/common/src/logs/logs3.d.ts +9 -9
- package/lib/common/src/logs/logs3.js +47 -38
- package/lib/common/src/logs/miniLogs.d.ts +3 -3
- package/lib/common/src/logs/miniLogs.js +28 -36
- package/lib/common/src/menu/menu.d.ts +18 -18
- package/lib/common/src/menu/menu.js +48 -24
- package/lib/common/src/menu/menuMouse.js +4 -1
- package/lib/common/src/menu/menuR.d.ts +2 -2
- package/lib/common/src/menu/menuR.js +34 -34
- package/lib/common/src/myChart/1/myChart.d.ts +5 -5
- package/lib/common/src/myChart/1/myChart.js +58 -47
- package/lib/common/src/myChart/1/myChartTest.js +8 -4
- package/lib/common/src/myChart/chartEngine/chartEngineReact.d.ts +24 -27
- package/lib/common/src/myChart/chartEngine/chartEngineReact.js +166 -117
- package/lib/common/src/styles/styleGrid.d.ts +2 -1
- package/lib/common/src/styles/styleGrid.js +10 -12
- package/lib/common/src/styles/tokens.d.ts +39 -0
- package/lib/common/src/styles/tokens.js +40 -0
- package/lib/common/src/utils/applyTransactionAsyncUpdate.d.ts +7 -0
- package/lib/common/src/utils/applyTransactionAsyncUpdate.js +19 -12
- package/lib/common/src/utils/arrayPromise.d.ts +6 -0
- package/lib/common/src/utils/arrayPromise.js +7 -1
- package/lib/common/src/utils/cache.js +24 -21
- package/lib/common/src/utils/inputAutoStep.d.ts +1 -1
- package/lib/common/src/utils/inputAutoStep.js +30 -19
- package/lib/common/src/utils/mapMemory.js +9 -10
- package/lib/common/updateBy.d.ts +21 -2
- package/lib/common/updateBy.js +66 -31
- package/lib/index.js +0 -2
- package/lib/style/menuRight.css +13 -26
- package/lib/style/style.css +51 -39
- package/lib/style/tokens.css +34 -0
- package/package.json +2 -2
|
@@ -1,38 +1,76 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
+
import React, { useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
export const StyleOtherRow = { display: "flex", flexDirection: "row", flex: "auto 1 1" };
|
|
4
4
|
export const StyleOtherColum = { display: "flex", flexDirection: "column", flex: "auto 0 1" };
|
|
5
|
-
export function
|
|
6
|
-
const
|
|
5
|
+
export function useOutsideApi(options) {
|
|
6
|
+
const { outsideClick, onOutside, ref, status = options.enabled ?? true } = options;
|
|
7
|
+
const internalRef = useRef(null); // useRef is always inside the body, not in a default parameter - otherwise it breaks the Rules of Hooks
|
|
7
8
|
const r = ref ?? internalRef;
|
|
9
|
+
const outsideClickRef = useRef(outsideClick ?? onOutside);
|
|
10
|
+
const [enabled, setEnabled] = useState(status);
|
|
11
|
+
const enabledRef = useRef(enabled);
|
|
12
|
+
outsideClickRef.current = outsideClick ?? onOutside;
|
|
13
|
+
enabledRef.current = enabled;
|
|
8
14
|
useEffect(() => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
setEnabled(status);
|
|
16
|
+
}, [status]);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
function handleClickOutside(event) {
|
|
19
|
+
if (!enabledRef.current)
|
|
20
|
+
return;
|
|
21
|
+
if (r.current && event.target instanceof Node && !r.current.contains(event.target))
|
|
22
|
+
outsideClickRef.current?.();
|
|
16
23
|
}
|
|
17
|
-
|
|
18
|
-
|
|
24
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
25
|
+
document.addEventListener("touchstart", handleClickOutside);
|
|
26
|
+
return () => {
|
|
27
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
28
|
+
document.removeEventListener("touchstart", handleClickOutside);
|
|
29
|
+
};
|
|
30
|
+
}, [r]);
|
|
31
|
+
const props = useMemo(() => ({ ref: r }), [r]);
|
|
32
|
+
return useMemo(() => {
|
|
33
|
+
const api = {
|
|
34
|
+
ref: r,
|
|
35
|
+
props,
|
|
36
|
+
bind: props,
|
|
37
|
+
contains(target) {
|
|
38
|
+
return !!(r.current && target instanceof Node && r.current.contains(target));
|
|
39
|
+
},
|
|
40
|
+
enable() { setEnabled(true); },
|
|
41
|
+
disable() { setEnabled(false); },
|
|
42
|
+
get enabled() { return enabledRef.current; },
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(api, "current", {
|
|
45
|
+
configurable: true,
|
|
46
|
+
get: () => r.current,
|
|
47
|
+
set: (node) => { r.current = node; },
|
|
48
|
+
});
|
|
49
|
+
return api;
|
|
50
|
+
}, [props, r]);
|
|
51
|
+
}
|
|
52
|
+
export function useOutside(options) {
|
|
53
|
+
return useOutsideApi(options);
|
|
54
|
+
}
|
|
55
|
+
/** @deprecated Use `useOutside(options)` and read `api.ref`, `api.props`, or `api.current`. */
|
|
56
|
+
export function useOutsideOld(options) {
|
|
57
|
+
return useOutsideApi(options).ref;
|
|
19
58
|
}
|
|
20
59
|
export const DivOutsideClick = React.forwardRef(({ children, outsideClick, zIndex, style = {}, status = true, ...other }, forwardedRef) => {
|
|
21
60
|
const style2 = zIndex ? { ...style, zIndex } : style;
|
|
22
61
|
const internalRef = useOutside({ outsideClick: outsideClick, status });
|
|
23
|
-
// Combine refs if forwardedRef is provided
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
else if (forwardedRef) {
|
|
31
|
-
forwardedRef.current = node;
|
|
32
|
-
}
|
|
62
|
+
// Combine refs if forwardedRef is provided; stable identity, otherwise React
|
|
63
|
+
// re-runs the ref (null + node) on every render
|
|
64
|
+
const combinedRef = React.useCallback((node) => {
|
|
65
|
+
internalRef.current = node;
|
|
66
|
+
if (typeof forwardedRef === 'function') {
|
|
67
|
+
forwardedRef(node);
|
|
33
68
|
}
|
|
34
|
-
|
|
35
|
-
|
|
69
|
+
else if (forwardedRef) {
|
|
70
|
+
forwardedRef.current = node;
|
|
71
|
+
}
|
|
72
|
+
}, [forwardedRef, internalRef]);
|
|
73
|
+
return _jsx("div", { ref: forwardedRef ? combinedRef : internalRef, style: style2, ...other, children: children });
|
|
36
74
|
});
|
|
37
75
|
// Deprecated: Use DivOutsideClick instead
|
|
38
76
|
export const DivOutsideClick2 = DivOutsideClick;
|
|
@@ -41,9 +79,20 @@ function ButtonBase({ children, button, style = {}, className = "", state: [a, s
|
|
|
41
79
|
}
|
|
42
80
|
const saveStatus = {};
|
|
43
81
|
export function Button({ keySave, statusDef, outClick, ...data }) {
|
|
44
|
-
|
|
82
|
+
// The keySave feature was dead: saveStatus was read but not written. Now status
|
|
83
|
+
// persists in memory for the session on each toggle.
|
|
84
|
+
if (keySave && saveStatus[keySave] != null)
|
|
45
85
|
statusDef = saveStatus[keySave];
|
|
46
|
-
const
|
|
86
|
+
const [status, setStatusRaw] = useState(statusDef ?? false);
|
|
87
|
+
const setStatus = (v) => {
|
|
88
|
+
setStatusRaw(prev => {
|
|
89
|
+
const next = typeof v === "function" ? v(prev) : v;
|
|
90
|
+
if (keySave)
|
|
91
|
+
saveStatus[keySave] = next;
|
|
92
|
+
return next;
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
const state = [status, setStatus];
|
|
47
96
|
const handleOutsideClick = () => {
|
|
48
97
|
state[1](false);
|
|
49
98
|
if (typeof outClick == "function")
|
|
@@ -53,7 +102,7 @@ export function Button({ keySave, statusDef, outClick, ...data }) {
|
|
|
53
102
|
}
|
|
54
103
|
export function ButtonHover(props) {
|
|
55
104
|
const [hover, setHover] = useState(false);
|
|
56
|
-
return _jsxs("div", { onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), style: { position: "relative" }, children: [typeof props.button == "function" ? props.button(hover) : props.button, hover &&
|
|
105
|
+
return _jsxs("div", { onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), style: { position: "relative", width: "min-content" }, children: [typeof props.button == "function" ? props.button(hover) : props.button, hover &&
|
|
57
106
|
_jsx("div", { style: { position: "absolute" }, children: typeof props.children == "function" ? props.children({ onClose: () => setHover(false) }) : props.children })] });
|
|
58
107
|
}
|
|
59
108
|
export const ButtonOutClick = ({ outClick = true, ...a }) => Button({ ...a, outClick });
|
|
@@ -89,7 +89,7 @@ export declare function getLogsApi<T extends object = {}>(setting: {
|
|
|
89
89
|
set(a: Params.SimpleParams<ReturnType<typeof getSettingLogs>>): void;
|
|
90
90
|
};
|
|
91
91
|
React: {
|
|
92
|
-
Setting:
|
|
92
|
+
Setting: typeof InputSettingLogs;
|
|
93
93
|
Message: typeof MessageEventLogs;
|
|
94
94
|
PageLogs: typeof PageLogs;
|
|
95
95
|
};
|
|
@@ -146,11 +146,14 @@ export declare const logsApi: {
|
|
|
146
146
|
set(a: Params.SimpleParams<ReturnType<typeof getSettingLogs>>): void;
|
|
147
147
|
};
|
|
148
148
|
React: {
|
|
149
|
-
Setting:
|
|
149
|
+
Setting: typeof InputSettingLogs;
|
|
150
150
|
Message: typeof MessageEventLogs;
|
|
151
151
|
PageLogs: typeof PageLogs;
|
|
152
152
|
};
|
|
153
153
|
};
|
|
154
|
+
declare function InputSettingLogs({}: {
|
|
155
|
+
update?: number;
|
|
156
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
154
157
|
export declare function PageLogs({ update }: {
|
|
155
158
|
update?: number;
|
|
156
159
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -14,13 +14,13 @@ const datumMiniConst = {
|
|
|
14
14
|
last: []
|
|
15
15
|
};
|
|
16
16
|
const getSettingLogs = () => ({
|
|
17
|
-
minVarLogs: { name: "
|
|
18
|
-
minVarMessage: { name: "
|
|
19
|
-
timeShow: { name: "
|
|
20
|
-
show: { name: "
|
|
17
|
+
minVarLogs: { name: "min. importance for notifications", range: { min: 0, max: 25, step: 1 }, value: 0 },
|
|
18
|
+
minVarMessage: { name: "min. importance for log table", range: { min: 0, max: 25, step: 1 }, value: 0 },
|
|
19
|
+
timeShow: { name: "screen display time", range: { min: 1, max: 20, step: 1 }, value: 2 },
|
|
20
|
+
show: { name: "show", value: true }
|
|
21
21
|
});
|
|
22
22
|
const settingLogs = { params: Params.GetSimpleParams(getSettingLogs()) };
|
|
23
|
-
// varMin -
|
|
23
|
+
// varMin - minimum importance
|
|
24
24
|
export function getLogsApi(setting) {
|
|
25
25
|
const datum = staticGetAdd("settingLogs", settingLogs);
|
|
26
26
|
function addToArr(arr, data, limit) {
|
|
@@ -29,18 +29,10 @@ export function getLogsApi(setting) {
|
|
|
29
29
|
arr.length = limit;
|
|
30
30
|
}
|
|
31
31
|
let num = 0;
|
|
32
|
-
const SettingLogsReact = ({}) => _jsx(ParametersReact
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
, {
|
|
35
|
-
// @ts-ignore
|
|
36
|
-
params: Params.mergeParamValuesToInfos(getSettingLogs(), datum.params), onChange: (e) => {
|
|
37
|
-
datum.params = Params.GetSimpleParams(e);
|
|
38
|
-
renderBy(datum);
|
|
39
|
-
} });
|
|
40
32
|
return {
|
|
41
33
|
addLogs(a) {
|
|
42
34
|
const item = { ...a, num: num++ };
|
|
43
|
-
addToArr(datumMiniConst.last, item, 50);
|
|
35
|
+
addToArr(datumMiniConst.last, item, setting.limit ?? 50);
|
|
44
36
|
addToArr(datumConst.map.get(a.id) ?? datumConst.map.set(a.id, []).get(a.id), item, setting.limitPer);
|
|
45
37
|
renderBy(datumConst);
|
|
46
38
|
renderBy(datumMiniConst);
|
|
@@ -55,7 +47,7 @@ export function getLogsApi(setting) {
|
|
|
55
47
|
},
|
|
56
48
|
},
|
|
57
49
|
React: {
|
|
58
|
-
Setting:
|
|
50
|
+
Setting: InputSettingLogs,
|
|
59
51
|
Message: MessageEventLogs,
|
|
60
52
|
PageLogs: PageLogs
|
|
61
53
|
}
|
|
@@ -75,10 +67,7 @@ function InputSettingLogs({}) {
|
|
|
75
67
|
}
|
|
76
68
|
export function PageLogs({ update }) {
|
|
77
69
|
const datumFull = datumConst;
|
|
78
|
-
const rowData = [...datumFull.map.values()].
|
|
79
|
-
...e,
|
|
80
|
-
time: (e.time)
|
|
81
|
-
})));
|
|
70
|
+
const rowData = [...datumFull.map.values()].flat();
|
|
82
71
|
const datum = datumMiniConst;
|
|
83
72
|
const setting = staticGetAdd("settingLogs", settingLogs);
|
|
84
73
|
const apiGrid = useRef(null);
|
|
@@ -103,12 +92,7 @@ export function PageLogs({ update }) {
|
|
|
103
92
|
const data = datum.last[0];
|
|
104
93
|
if (data) { // data.time timeLocalToStr_yyyymmdd_hhmmss_ms
|
|
105
94
|
apiGrid.current?.api.applyTransactionAsync({
|
|
106
|
-
add: [
|
|
107
|
-
{
|
|
108
|
-
...data,
|
|
109
|
-
time: data.time
|
|
110
|
-
}
|
|
111
|
-
]
|
|
95
|
+
add: [{ ...data }]
|
|
112
96
|
});
|
|
113
97
|
}
|
|
114
98
|
});
|
|
@@ -193,7 +177,7 @@ function Message({ logs }) {
|
|
|
193
177
|
let red = (logs.var ?? 0) * 10;
|
|
194
178
|
if (red > 255)
|
|
195
179
|
red = 255;
|
|
196
|
-
return _jsxs("div", { className: "testAnime", style: { width: "200px", color: "rgb(255,255,255)", height: "auto", marginTop: "10px", borderRight: "5px solid #5D9FFA", background: `rgb(${red},73,35)` }, children: [_jsx("p", { style: { textAlign: "center", fontSize: "10px", marginBottom: "1px" }, children: "
|
|
180
|
+
return _jsxs("div", { className: "testAnime", style: { width: "200px", color: "rgb(255,255,255)", height: "auto", marginTop: "10px", borderRight: "5px solid #5D9FFA", background: `rgb(${red},73,35)` }, children: [_jsx("p", { style: { textAlign: "center", fontSize: "10px", marginBottom: "1px" }, children: "notification" }), _jsx("hr", { style: {
|
|
197
181
|
backgroundImage: "linear-gradient(to right, transparent, rgba(255, 255, 255, 1), transparent)",
|
|
198
182
|
border: 0,
|
|
199
183
|
height: "1px",
|
|
@@ -205,11 +189,12 @@ function Message({ logs }) {
|
|
|
205
189
|
const tt = {};
|
|
206
190
|
let r = 0;
|
|
207
191
|
export function MessageEventLogs({ zIndex }) {
|
|
208
|
-
let max = 8;
|
|
209
192
|
const setting = staticGetAdd("settingLogs", settingLogs);
|
|
210
193
|
updateBy(tt);
|
|
211
194
|
updateBy(datumMiniConst, () => {
|
|
212
195
|
const last = datumMiniConst.last[0];
|
|
196
|
+
if (!last)
|
|
197
|
+
return;
|
|
213
198
|
if (setting.params.minVarMessage && (!last.var || last.var < setting.params.minVarMessage))
|
|
214
199
|
return;
|
|
215
200
|
let key = String(r++);
|
|
@@ -217,18 +202,17 @@ export function MessageEventLogs({ zIndex }) {
|
|
|
217
202
|
setTimeout(() => {
|
|
218
203
|
if (tt[key]) {
|
|
219
204
|
delete tt[key];
|
|
220
|
-
|
|
221
|
-
renderBy(tt);
|
|
205
|
+
renderBy(tt, 100);
|
|
222
206
|
}
|
|
223
207
|
}, setting.params.timeShow ? setting.params.timeShow * 1000 : 2000);
|
|
224
208
|
renderBy(tt);
|
|
225
209
|
});
|
|
226
210
|
const tr = [...Object.values(tt)].reverse().slice(0, 10);
|
|
227
|
-
return _jsxs("div", { style: { maxHeight: "50vh", position: "absolute", right: "1px", zIndex }, children: [
|
|
211
|
+
return _jsxs("div", { style: { maxHeight: "50vh", position: "absolute", right: "1px", zIndex }, children: [_jsx("div", { onClick: () => { setting.params.show = !setting.params.show; renderBy(tt); }, style: { margin: 3, padding: 3, right: 0, position: "absolute", zIndex: 120,
|
|
228
212
|
...setting.params.show ?
|
|
229
213
|
{ background: "rgb(58,58,58)", fontSize: "25px" } :
|
|
230
214
|
{ background: "rgb(144,60,60)" }
|
|
231
|
-
}, children: setting.params.show ? "X" : "log" }),
|
|
215
|
+
}, children: setting.params.show ? "X" : "log" }), _jsx("div", { children: setting.params.show ? tr : null })] });
|
|
232
216
|
}
|
|
233
217
|
const defPageBase = {
|
|
234
218
|
keyPage: "PageLogs"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
/** -----------------------------
|
|
3
|
-
* 1.
|
|
3
|
+
* 1. Log types
|
|
4
4
|
* -----------------------------
|
|
5
5
|
*/
|
|
6
6
|
export interface tLogsInput<T extends object = {}> {
|
|
@@ -14,7 +14,7 @@ export interface tLogs<T extends object = {}> extends tLogsInput<T> {
|
|
|
14
14
|
num: number;
|
|
15
15
|
}
|
|
16
16
|
/** -----------------------------
|
|
17
|
-
* 3.
|
|
17
|
+
* 3. Context interface
|
|
18
18
|
* -----------------------------
|
|
19
19
|
*/
|
|
20
20
|
interface LogsContextValue {
|
|
@@ -33,30 +33,30 @@ export declare function LogsProvider({ children }: {
|
|
|
33
33
|
children: React.ReactNode;
|
|
34
34
|
}): import("react/jsx-runtime").JSX.Element;
|
|
35
35
|
/** -----------------------------
|
|
36
|
-
* 5.
|
|
36
|
+
* 5. Hook for convenient context access
|
|
37
37
|
* -----------------------------
|
|
38
38
|
*/
|
|
39
39
|
export declare function useLogsContext(): LogsContextValue;
|
|
40
40
|
/** -----------------------------
|
|
41
|
-
* 6.
|
|
42
|
-
* (
|
|
41
|
+
* 6. LogsTable component
|
|
42
|
+
* (PageLogs equivalent)
|
|
43
43
|
* -----------------------------
|
|
44
44
|
*/
|
|
45
45
|
export declare function LogsTable(): import("react/jsx-runtime").JSX.Element;
|
|
46
46
|
export declare function LogsNotifications(): import("react/jsx-runtime").JSX.Element;
|
|
47
47
|
/** -----------------------------
|
|
48
|
-
* 8.
|
|
49
|
-
* (
|
|
48
|
+
* 8. LogsSettings component
|
|
49
|
+
* (InputSettingLogs equivalent)
|
|
50
50
|
* -----------------------------
|
|
51
51
|
*/
|
|
52
52
|
export declare function LogsSettings(): import("react/jsx-runtime").JSX.Element;
|
|
53
53
|
/** -----------------------------
|
|
54
|
-
* 9. MainPage
|
|
54
|
+
* 9. MainPage - tabs (Table / Settings)
|
|
55
55
|
* -----------------------------
|
|
56
56
|
*/
|
|
57
57
|
export declare function MainPage(): import("react/jsx-runtime").JSX.Element;
|
|
58
58
|
/** -----------------------------
|
|
59
|
-
* 10.
|
|
59
|
+
* 10. Root App component
|
|
60
60
|
* -----------------------------
|
|
61
61
|
*/
|
|
62
62
|
export default function AppLogs(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,52 +2,52 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { createContext, useContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { AgGridReact } from 'ag-grid-react';
|
|
4
4
|
/** -----------------------------
|
|
5
|
-
* 2.
|
|
6
|
-
*
|
|
5
|
+
* 2. staticGetAdd function -
|
|
6
|
+
* loads and saves data in localStorage.
|
|
7
7
|
* -----------------------------
|
|
8
8
|
*/
|
|
9
9
|
function staticGetAdd(key, defaultValue) {
|
|
10
10
|
try {
|
|
11
11
|
const stored = localStorage.getItem(key);
|
|
12
|
-
//
|
|
12
|
+
// If localStorage has no value, write defaultValue
|
|
13
13
|
if (!stored) {
|
|
14
14
|
localStorage.setItem(key, JSON.stringify(defaultValue));
|
|
15
15
|
return defaultValue;
|
|
16
16
|
}
|
|
17
|
-
//
|
|
18
|
-
//
|
|
17
|
+
// If a value was found, try to merge it with defaultValue
|
|
18
|
+
// in case new fields were added to defaultValue
|
|
19
19
|
const parsed = JSON.parse(stored);
|
|
20
20
|
return { ...defaultValue, ...parsed };
|
|
21
21
|
}
|
|
22
22
|
catch (error) {
|
|
23
|
-
console.error("
|
|
23
|
+
console.error("localStorage read error:", error);
|
|
24
24
|
return defaultValue;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
/** -----------------------------
|
|
28
|
-
* 4.
|
|
29
|
-
*
|
|
28
|
+
* 4. Create the context itself
|
|
29
|
+
* and provider for logs and settings
|
|
30
30
|
* -----------------------------
|
|
31
31
|
*/
|
|
32
32
|
const LogsContext = createContext(null);
|
|
33
33
|
export function LogsProvider({ children }) {
|
|
34
|
-
// 4.1.
|
|
35
|
-
const savedSettings = staticGetAdd("logSettings", {
|
|
34
|
+
// 4.1. Load settings from localStorage once (lazy init: the provider rerenders on every addLog)
|
|
35
|
+
const [savedSettings] = useState(() => staticGetAdd("logSettings", {
|
|
36
36
|
minVarLogs: 0,
|
|
37
37
|
minVarMessage: 0,
|
|
38
38
|
timeShow: 2,
|
|
39
39
|
showMessages: true
|
|
40
|
-
});
|
|
41
|
-
// 4.2.
|
|
42
|
-
//
|
|
40
|
+
}));
|
|
41
|
+
// 4.2. In-memory log list (logs are not saved to localStorage,
|
|
42
|
+
// only settings are, but logs can be saved too if needed)
|
|
43
43
|
const [logs, setLogs] = useState([]);
|
|
44
44
|
const counterRef = useRef(0);
|
|
45
|
-
// 4.3.
|
|
45
|
+
// 4.3. Settings themselves, initialized from staticGetAdd output
|
|
46
46
|
const [minVarLogs, setMinVarLogs] = useState(savedSettings.minVarLogs);
|
|
47
47
|
const [minVarMessage, setMinVarMessage] = useState(savedSettings.minVarMessage);
|
|
48
48
|
const [timeShow, setTimeShow] = useState(savedSettings.timeShow);
|
|
49
49
|
const [showMessages, setShowMessages] = useState(savedSettings.showMessages);
|
|
50
|
-
// 4.4.
|
|
50
|
+
// 4.4. Watch settings changes and save them back to localStorage
|
|
51
51
|
useEffect(() => {
|
|
52
52
|
const toSave = {
|
|
53
53
|
minVarLogs,
|
|
@@ -57,17 +57,17 @@ export function LogsProvider({ children }) {
|
|
|
57
57
|
};
|
|
58
58
|
localStorage.setItem("logSettings", JSON.stringify(toSave));
|
|
59
59
|
}, [minVarLogs, minVarMessage, timeShow, showMessages]);
|
|
60
|
-
// 4.5.
|
|
60
|
+
// 4.5. Function for adding a log, generates the num field automatically
|
|
61
61
|
const addLog = useCallback((input) => {
|
|
62
62
|
counterRef.current += 1;
|
|
63
63
|
const num = counterRef.current;
|
|
64
64
|
setLogs((prevLogs) => {
|
|
65
65
|
const newLog = { ...input, num };
|
|
66
|
-
//
|
|
66
|
+
// Limit to 500 logs; this can be changed
|
|
67
67
|
return [newLog, ...prevLogs].slice(0, 500);
|
|
68
68
|
});
|
|
69
69
|
}, []);
|
|
70
|
-
// 4.6.
|
|
70
|
+
// 4.6. Return the context provider
|
|
71
71
|
return (_jsx(LogsContext.Provider, { value: {
|
|
72
72
|
logs,
|
|
73
73
|
addLog,
|
|
@@ -82,7 +82,7 @@ export function LogsProvider({ children }) {
|
|
|
82
82
|
}, children: children }));
|
|
83
83
|
}
|
|
84
84
|
/** -----------------------------
|
|
85
|
-
* 5.
|
|
85
|
+
* 5. Hook for convenient context access
|
|
86
86
|
* -----------------------------
|
|
87
87
|
*/
|
|
88
88
|
export function useLogsContext() {
|
|
@@ -93,18 +93,18 @@ export function useLogsContext() {
|
|
|
93
93
|
return ctx;
|
|
94
94
|
}
|
|
95
95
|
/** -----------------------------
|
|
96
|
-
* 6.
|
|
97
|
-
* (
|
|
96
|
+
* 6. LogsTable component
|
|
97
|
+
* (PageLogs equivalent)
|
|
98
98
|
* -----------------------------
|
|
99
99
|
*/
|
|
100
100
|
export function LogsTable() {
|
|
101
101
|
const { logs, minVarLogs } = useLogsContext();
|
|
102
102
|
const gridRef = useRef(null);
|
|
103
|
-
//
|
|
103
|
+
// Column definitions
|
|
104
104
|
const columnDefs = useMemo(() => [
|
|
105
105
|
{
|
|
106
106
|
field: 'time',
|
|
107
|
-
headerName: '
|
|
107
|
+
headerName: 'Time',
|
|
108
108
|
sort: 'desc',
|
|
109
109
|
valueFormatter: (params) => {
|
|
110
110
|
const dateObj = params.value;
|
|
@@ -115,10 +115,10 @@ export function LogsTable() {
|
|
|
115
115
|
width: 120,
|
|
116
116
|
},
|
|
117
117
|
{ field: 'id', headerName: 'ID', width: 80 },
|
|
118
|
-
{ field: 'var', headerName: '
|
|
118
|
+
{ field: 'var', headerName: 'Importance', width: 90 },
|
|
119
119
|
{
|
|
120
120
|
field: 'txt',
|
|
121
|
-
headerName: '
|
|
121
|
+
headerName: 'Message',
|
|
122
122
|
flex: 1,
|
|
123
123
|
wrapText: true,
|
|
124
124
|
autoHeight: true
|
|
@@ -130,7 +130,7 @@ export function LogsTable() {
|
|
|
130
130
|
filter: true,
|
|
131
131
|
wrapText: true,
|
|
132
132
|
}), []);
|
|
133
|
-
//
|
|
133
|
+
// Watch minVarLogs and configure the AG Grid filter
|
|
134
134
|
useEffect(() => {
|
|
135
135
|
if (gridRef.current?.api) {
|
|
136
136
|
if (minVarLogs > 0) {
|
|
@@ -158,30 +158,39 @@ export function LogsNotifications() {
|
|
|
158
158
|
const { logs, minVarMessage, timeShow, showMessages, setShowMessages } = useLogsContext();
|
|
159
159
|
const [notifications, setNotifications] = useState([]);
|
|
160
160
|
const counterRef = useRef(0);
|
|
161
|
+
const lastLogRef = useRef(null);
|
|
162
|
+
const timersRef = useRef(new Set());
|
|
161
163
|
useEffect(() => {
|
|
162
164
|
if (logs.length === 0)
|
|
163
165
|
return;
|
|
164
166
|
const newestLog = logs[0];
|
|
167
|
+
// gate by log identity: a settings change must not re-add the same log
|
|
168
|
+
if (newestLog === lastLogRef.current)
|
|
169
|
+
return;
|
|
170
|
+
lastLogRef.current = newestLog;
|
|
165
171
|
if ((newestLog.var ?? 0) < minVarMessage)
|
|
166
172
|
return;
|
|
167
173
|
counterRef.current += 1;
|
|
168
174
|
const newItem = { id: counterRef.current, log: newestLog };
|
|
169
175
|
setNotifications((prev) => [newItem, ...prev]);
|
|
170
|
-
//
|
|
176
|
+
// Remove notification after timeShow seconds; per-item timers are NOT cancelled
|
|
177
|
+
// when the next log arrives - the old cleanup froze every notification but the last
|
|
171
178
|
const timer = setTimeout(() => {
|
|
179
|
+
timersRef.current.delete(timer);
|
|
172
180
|
setNotifications((prev) => prev.filter((item) => item.id !== newItem.id));
|
|
173
181
|
}, timeShow * 1000);
|
|
174
|
-
|
|
182
|
+
timersRef.current.add(timer);
|
|
175
183
|
}, [logs, minVarMessage, timeShow]);
|
|
184
|
+
useEffect(() => () => { timersRef.current.forEach(clearTimeout); }, []);
|
|
176
185
|
if (!showMessages) {
|
|
177
|
-
//
|
|
186
|
+
// If popups are hidden, show only "log"
|
|
178
187
|
return (_jsx("div", { style: { position: 'absolute', right: 10, top: 10, zIndex: 999 }, children: _jsx("div", { style: {
|
|
179
188
|
background: 'rgb(144,60,60)',
|
|
180
189
|
padding: '6px 10px',
|
|
181
190
|
cursor: 'pointer'
|
|
182
191
|
}, onClick: () => setShowMessages(true), children: "log" }) }));
|
|
183
192
|
}
|
|
184
|
-
//
|
|
193
|
+
// Otherwise render the current notification list
|
|
185
194
|
return (_jsxs("div", { style: { position: 'absolute', right: 10, top: 10, zIndex: 999 }, children: [_jsx("div", { style: {
|
|
186
195
|
background: 'rgb(58,58,58)',
|
|
187
196
|
fontSize: '20px',
|
|
@@ -199,7 +208,7 @@ export function LogsNotifications() {
|
|
|
199
208
|
backgroundColor: `rgb(${red},73,35)`,
|
|
200
209
|
padding: 8,
|
|
201
210
|
wordWrap: 'break-word'
|
|
202
|
-
}, children: [_jsx("p", { style: { textAlign: 'center', fontSize: 10, marginBottom: 1 }, children: "
|
|
211
|
+
}, children: [_jsx("p", { style: { textAlign: 'center', fontSize: 10, marginBottom: 1 }, children: "notification" }), _jsx("hr", { style: {
|
|
203
212
|
backgroundImage: 'linear-gradient(to right, transparent, rgba(255, 255, 255, 1), transparent)',
|
|
204
213
|
border: 0,
|
|
205
214
|
height: 1,
|
|
@@ -208,16 +217,16 @@ export function LogsNotifications() {
|
|
|
208
217
|
}) })] }));
|
|
209
218
|
}
|
|
210
219
|
/** -----------------------------
|
|
211
|
-
* 8.
|
|
212
|
-
* (
|
|
220
|
+
* 8. LogsSettings component
|
|
221
|
+
* (InputSettingLogs equivalent)
|
|
213
222
|
* -----------------------------
|
|
214
223
|
*/
|
|
215
224
|
export function LogsSettings() {
|
|
216
225
|
const { minVarLogs, setMinVarLogs, minVarMessage, setMinVarMessage, timeShow, setTimeShow, showMessages, setShowMessages } = useLogsContext();
|
|
217
|
-
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10, padding: 10 }, children: [_jsxs("label", { children: ["
|
|
226
|
+
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10, padding: 10 }, children: [_jsxs("label", { children: ["Minimum importance for the ", _jsx("b", { children: "table" }), " (minVarLogs):", _jsx("input", { type: "number", value: minVarLogs, onChange: (e) => setMinVarLogs(Number(e.target.value)), style: { marginLeft: 8 } })] }), _jsxs("label", { children: ["Minimum importance for ", _jsx("b", { children: "notifications" }), " (minVarMessage):", _jsx("input", { type: "number", value: minVarMessage, onChange: (e) => setMinVarMessage(Number(e.target.value)), style: { marginLeft: 8 } })] }), _jsxs("label", { children: ["Display time (sec) (timeShow):", _jsx("input", { type: "number", value: timeShow, onChange: (e) => setTimeShow(Number(e.target.value)), style: { marginLeft: 8 } })] }), _jsxs("label", { children: ["Show popups (showMessages):", _jsx("input", { type: "checkbox", checked: showMessages, onChange: (e) => setShowMessages(e.target.checked), style: { marginLeft: 8 } })] })] }));
|
|
218
227
|
}
|
|
219
228
|
/** -----------------------------
|
|
220
|
-
* 9. MainPage
|
|
229
|
+
* 9. MainPage - tabs (Table / Settings)
|
|
221
230
|
* -----------------------------
|
|
222
231
|
*/
|
|
223
232
|
export function MainPage() {
|
|
@@ -228,16 +237,16 @@ export function MainPage() {
|
|
|
228
237
|
border: 'none',
|
|
229
238
|
padding: '8px',
|
|
230
239
|
cursor: 'pointer'
|
|
231
|
-
}, children: "
|
|
240
|
+
}, children: "Log table" }), _jsx("button", { onClick: () => setCurrentTab('settings'), style: {
|
|
232
241
|
backgroundColor: currentTab === 'settings' ? '#666' : '#444',
|
|
233
242
|
color: 'white',
|
|
234
243
|
border: 'none',
|
|
235
244
|
padding: '8px',
|
|
236
245
|
cursor: 'pointer'
|
|
237
|
-
}, children: "
|
|
246
|
+
}, children: "Settings" })] }), _jsxs("div", { style: { flex: 1, position: 'relative' }, children: [currentTab === 'table' && _jsx(LogsTable, {}), currentTab === 'settings' && _jsx(LogsSettings, {})] })] }));
|
|
238
247
|
}
|
|
239
248
|
/** -----------------------------
|
|
240
|
-
* 10.
|
|
249
|
+
* 10. Root App component
|
|
241
250
|
* -----------------------------
|
|
242
251
|
*/
|
|
243
252
|
export default function AppLogs() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CellMouseDownEvent } from "ag-grid-community";
|
|
2
|
-
export declare function MiniLogs({ data, onClick }: {
|
|
3
|
-
data:
|
|
4
|
-
onClick?: (e: CellMouseDownEvent<
|
|
2
|
+
export declare function MiniLogs<T = any>({ data, onClick }: {
|
|
3
|
+
data: T[];
|
|
4
|
+
onClick?: (e: CellMouseDownEvent<T>) => any;
|
|
5
5
|
}): import("react/jsx-runtime").JSX.Element;
|