wenay-react2 1.0.35 → 1.0.36
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 +12 -56
- package/lib/common/api.d.ts +28 -28
- package/lib/common/api.js +31 -31
- package/lib/common/src/components/Buttons/MiniButton.d.ts +1 -3
- package/lib/common/src/components/Buttons/MiniButton.js +1 -3
- package/lib/common/src/components/Dnd/{RNDFunc.d.ts → DragArea.d.ts} +1 -1
- package/lib/common/src/components/Dnd/{RNDFunc.js → DragArea.js} +1 -1
- package/lib/common/src/components/Dnd/{RNDFunc3.d.ts → FloatingWindow.d.ts} +7 -7
- package/lib/common/src/components/Dnd/{RNDFunc3.js → FloatingWindow.js} +10 -10
- package/lib/common/src/components/Dnd/OutlineDragDemo.d.ts +1 -0
- package/lib/common/src/components/Dnd/{DraggableOutlineDiv.js → OutlineDragDemo.js} +1 -2
- package/lib/common/src/components/Dnd/Resizable.js +1 -1
- package/lib/common/src/components/Dnd/index.d.ts +3 -3
- package/lib/common/src/components/Dnd/index.js +3 -3
- package/lib/common/src/components/Input.d.ts +5 -5
- package/lib/common/src/components/Input.js +10 -10
- package/lib/common/src/components/Menu/RightMenu.d.ts +25 -5
- package/lib/common/src/components/Menu/RightMenu.js +27 -19
- package/lib/common/src/components/Menu/RightMenuStore.d.ts +2 -2
- package/lib/common/src/components/Menu/RightMenuStore.js +1 -1
- package/lib/common/src/components/Modal/LeftModal.js +4 -4
- package/lib/common/src/components/Modal/Modal.d.ts +11 -17
- package/lib/common/src/components/Modal/Modal.js +15 -21
- package/lib/common/src/components/Modal/ModalContextProvider.d.ts +0 -6
- package/lib/common/src/components/Modal/ModalContextProvider.js +2 -9
- package/lib/common/src/components/Other.d.ts +2 -2
- package/lib/common/src/components/Other.js +5 -5
- package/lib/common/src/components/Parameters.d.ts +3 -3
- package/lib/common/src/components/Parameters.js +3 -3
- package/lib/common/src/components/{ParametersEngine.d.ts → ParamsEditor.d.ts} +1 -1
- package/lib/common/src/components/{ParametersEngine.js → ParamsEditor.js} +10 -10
- package/lib/common/src/components/Settings/SettingsDialog.d.ts +4 -4
- package/lib/common/src/components/Toolbar/Toolbar.d.ts +50 -37
- package/lib/common/src/components/Toolbar/Toolbar.js +60 -23
- package/lib/common/src/components/UiSlot/UiSlot.d.ts +3 -3
- package/lib/common/src/components/UiSlot/UiSlot.js +6 -6
- package/lib/common/src/grid/agGrid4/agGrid4.d.ts +4 -4
- package/lib/common/src/grid/agGrid4/agGrid4.js +6 -6
- package/lib/common/src/grid/agGrid4/index.d.ts +3 -3
- package/lib/common/src/grid/agGrid4/index.js +1 -1
- package/lib/common/src/grid/agGrid4/theme.d.ts +3 -3
- package/lib/common/src/grid/columnState/CardList.d.ts +11 -0
- package/lib/common/src/grid/columnState/CardList.js +28 -0
- package/lib/common/src/grid/columnState/ColumnDots.d.ts +9 -0
- package/lib/common/src/grid/columnState/ColumnDots.js +121 -0
- package/lib/common/src/grid/columnState/ColumnsMenu.d.ts +65 -0
- package/lib/common/src/grid/columnState/ColumnsMenu.js +123 -0
- package/lib/common/src/grid/columnState/columnState.d.ts +113 -0
- package/lib/common/src/grid/columnState/columnState.js +284 -0
- package/lib/common/src/grid/columnState/index.d.ts +4 -0
- package/lib/common/src/grid/columnState/index.js +4 -0
- package/lib/common/src/hooks/index.d.ts +1 -1
- package/lib/common/src/hooks/index.js +1 -1
- package/lib/common/src/hooks/useKeyboard.d.ts +18 -0
- package/lib/common/src/hooks/{useAddDownAnyKey.js → useKeyboard.js} +16 -24
- package/lib/common/src/hooks/useObserveStore.d.ts +12 -12
- package/lib/common/src/hooks/useObserveStore.js +2 -2
- package/lib/common/src/hooks/useOutside.d.ts +12 -19
- package/lib/common/src/hooks/useOutside.js +9 -16
- package/lib/common/src/hooks/useReorder.d.ts +4 -4
- package/lib/common/src/hooks/useReorderBoard.d.ts +15 -15
- package/lib/common/src/hooks/useReplay.d.ts +9 -9
- package/lib/common/src/hooks/useReplay.js +7 -7
- package/lib/common/src/logs/logs.d.ts +3 -3
- package/lib/common/src/logs/logs.js +11 -13
- package/lib/common/src/logs/{logs3.d.ts → logsContext.d.ts} +4 -4
- package/lib/common/src/logs/{logs3.js → logsContext.js} +4 -4
- package/lib/common/src/menu/menu.d.ts +16 -16
- package/lib/common/src/menu/menu.js +12 -11
- package/lib/common/src/menu/menuMouse.d.ts +71 -13
- package/lib/common/src/menu/menuMouse.js +189 -21
- package/lib/common/src/menu/menuR.d.ts +3 -3
- package/lib/common/src/menu/menuR.js +5 -5
- package/lib/common/src/styles/styleGrid.d.ts +1 -1
- package/lib/common/src/styles/tokens.d.ts +1 -1
- package/lib/common/src/styles/tokens.js +1 -1
- package/lib/common/src/utils/cache.d.ts +11 -11
- package/lib/common/src/utils/cache.js +0 -0
- package/lib/common/src/utils/gridRows.d.ts +37 -0
- package/lib/common/src/utils/{applyTransactionAsyncUpdate.js → gridRows.js} +6 -38
- package/lib/common/src/utils/index.d.ts +2 -2
- package/lib/common/src/utils/index.js +2 -2
- package/lib/common/src/utils/inputAutoStep.d.ts +2 -2
- package/lib/common/src/utils/inputAutoStep.js +26 -37
- package/lib/common/src/utils/{mapMemory.d.ts → memoryStore.d.ts} +13 -13
- package/lib/common/src/utils/{mapMemory.js → memoryStore.js} +32 -32
- package/lib/common/src/utils/observableMap.d.ts +5 -5
- package/lib/common/src/utils/observableMap.js +3 -3
- package/lib/common/updateBy.js +2 -2
- package/lib/style/style.css +3 -3
- package/lib/style/tokens.css +1 -1
- package/package.json +49 -49
- package/lib/common/src/components/Dnd/DraggableOutlineDiv.d.ts +0 -2
- package/lib/common/src/hooks/useAddDownAnyKey.d.ts +0 -24
- package/lib/common/src/utils/applyTransactionAsyncUpdate.d.ts +0 -53
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReorderItem } from './useReorder';
|
|
2
2
|
/** useReorderBoard - the columns extension of useReorder: keyed blocks live in
|
|
3
3
|
* VERTICAL columns (plain consumer divs), one block drags between/within them,
|
|
4
4
|
* ONE commit on drop. Column "gravity" is pure consumer CSS (justify-content:
|
|
@@ -8,19 +8,19 @@ import { tReorderItem } from './useReorder';
|
|
|
8
8
|
* drag. Children of a column div must be exactly its items, 1:1, in order.
|
|
9
9
|
* Same non-goals as useReorder: no nesting, no spans/collision packing, no
|
|
10
10
|
* autoscroll - that day is a ready-made dnd library. */
|
|
11
|
-
export type
|
|
11
|
+
export type BoardPosition = {
|
|
12
12
|
col: string;
|
|
13
13
|
index: number;
|
|
14
14
|
};
|
|
15
|
-
export type
|
|
15
|
+
export type BoardColumn = {
|
|
16
16
|
key: string;
|
|
17
17
|
items: string[];
|
|
18
18
|
};
|
|
19
|
-
export type
|
|
19
|
+
export type ReorderBoardOptions = {
|
|
20
20
|
/** columns in board order; each column's div children must render items 1:1 */
|
|
21
|
-
columns:
|
|
21
|
+
columns: BoardColumn[];
|
|
22
22
|
/** ONE commit on drop; skipped when nothing moved */
|
|
23
|
-
commit: (next:
|
|
23
|
+
commit: (next: BoardColumn[]) => void;
|
|
24
24
|
/** false = this key cannot start a drag (default: all can) */
|
|
25
25
|
canDrag?: (key: string) => boolean;
|
|
26
26
|
/** hold before the drag starts; default 0 */
|
|
@@ -28,12 +28,12 @@ export type tReorderBoardOptions = {
|
|
|
28
28
|
/** the block was grabbed */
|
|
29
29
|
onDragStart?: (e: {
|
|
30
30
|
key: string;
|
|
31
|
-
from:
|
|
31
|
+
from: BoardPosition;
|
|
32
32
|
}) => void;
|
|
33
33
|
/** every pointer move while dragging; position = pointer delta in local px */
|
|
34
34
|
onDragMove?: (e: {
|
|
35
35
|
key: string;
|
|
36
|
-
over:
|
|
36
|
+
over: BoardPosition;
|
|
37
37
|
position: {
|
|
38
38
|
x: number;
|
|
39
39
|
y: number;
|
|
@@ -42,20 +42,20 @@ export type tReorderBoardOptions = {
|
|
|
42
42
|
/** the target slot changed (compare prev.col != over.col for column crossings) */
|
|
43
43
|
onOverChange?: (e: {
|
|
44
44
|
key: string;
|
|
45
|
-
over:
|
|
46
|
-
prev:
|
|
45
|
+
over: BoardPosition;
|
|
46
|
+
prev: BoardPosition | null;
|
|
47
47
|
}) => void;
|
|
48
48
|
/** drop; committed=false when nothing moved (plain click) */
|
|
49
49
|
onDragEnd?: (e: {
|
|
50
50
|
key: string;
|
|
51
|
-
from:
|
|
52
|
-
over:
|
|
51
|
+
from: BoardPosition;
|
|
52
|
+
over: BoardPosition;
|
|
53
53
|
committed: boolean;
|
|
54
54
|
}) => void;
|
|
55
55
|
};
|
|
56
|
-
export declare function useReorderBoard(o:
|
|
56
|
+
export declare function useReorderBoard(o: ReorderBoardOptions): {
|
|
57
57
|
columnRef: (col: string) => (el: HTMLElement | null) => void;
|
|
58
|
-
item: (key: string) =>
|
|
58
|
+
item: (key: string) => ReorderItem;
|
|
59
59
|
dragKey: string | null;
|
|
60
|
-
over:
|
|
60
|
+
over: BoardPosition | null;
|
|
61
61
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type StoreDrain =
|
|
3
|
-
type StoreEachCtx =
|
|
4
|
-
type StorePatch =
|
|
1
|
+
import { Observe, Replay } from "wenay-common2";
|
|
2
|
+
type StoreDrain = Observe.StoreDrain;
|
|
3
|
+
type StoreEachCtx = Observe.StoreEachCtx;
|
|
4
|
+
type StorePatch = Observe.StorePatch;
|
|
5
5
|
type ReplayEvent<Z extends any[]> = Replay.ReplayEvent<Z>;
|
|
6
6
|
type ReplayRemote<Z extends any[]> = Replay.ReplayRemote<Z>;
|
|
7
7
|
type StaleInfo = Replay.StaleInfo;
|
|
@@ -65,14 +65,14 @@ export declare function useReplaySubscribe<Z extends any[]>(remote: ReplayRemote
|
|
|
65
65
|
export type UseStoreReplaySyncOptions = UseReplaySubscribeOptions;
|
|
66
66
|
export type StoreReplaySyncController = ReplaySubscribeController;
|
|
67
67
|
/**
|
|
68
|
-
* Sync an existing mirror store from a store replay line (`
|
|
69
|
-
* Thin lifecycle wrapper over `
|
|
68
|
+
* Sync an existing mirror store from a store replay line (`Observe.exposeStoreReplay(...).api.replay`).
|
|
69
|
+
* Thin lifecycle wrapper over `Observe.syncStoreReplay`: the keyframe (root patch) and the
|
|
70
70
|
* patch tail are applied to the store by the library; UI subscribes to the store as usual
|
|
71
71
|
* (useStoreNode/useStoreSelect).
|
|
72
72
|
*/
|
|
73
|
-
export declare function useStoreReplaySync<T extends object>(store:
|
|
73
|
+
export declare function useStoreReplaySync<T extends object>(store: Observe.Store<T> | null | undefined, remote: ReplayRemote<[StorePatch]> | null | undefined, options?: UseStoreReplaySyncOptions): StoreReplaySyncController;
|
|
74
74
|
export type StoreReplayMirrorController<T extends object> = StoreReplaySyncController & {
|
|
75
|
-
readonly store:
|
|
75
|
+
readonly store: Observe.Store<T>;
|
|
76
76
|
};
|
|
77
77
|
/**
|
|
78
78
|
* Convenience: create a local mirror store and keep it synced from a store replay line.
|
|
@@ -92,7 +92,7 @@ export type UseStoreReplayEachOptions<T extends object> = UseStoreReplaySyncOpti
|
|
|
92
92
|
drain?: StoreDrain;
|
|
93
93
|
};
|
|
94
94
|
/**
|
|
95
|
-
* Per-key fold over a store replay line — React counterpart of `
|
|
95
|
+
* Per-key fold over a store replay line — React counterpart of `Observe.syncStoreReplayEach`
|
|
96
96
|
* (internal mirror store + syncStoreReplay + store.each()). cb fires once per CHANGED top-level
|
|
97
97
|
* key per drain window with the current value; the first delivery is the keyframe EXPANDED per
|
|
98
98
|
* key; (key, undefined) = key deleted — cold start / reconnect are not special cases for per-key
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { Observe, Replay } from "wenay-common2";
|
|
3
3
|
import { useStoreEach } from "./useObserveStore";
|
|
4
4
|
/**
|
|
5
5
|
* React bridge over the Replay stack (snapshot + sequenced delta line) of wenay-common2.
|
|
@@ -112,8 +112,8 @@ export function useReplaySubscribe(remote, cb, options = {}) {
|
|
|
112
112
|
return useMemo(() => ({ ready, error, stale, seq, lastTs, restart }), [ready, error, stale, seq, lastTs, restart]);
|
|
113
113
|
}
|
|
114
114
|
/**
|
|
115
|
-
* Sync an existing mirror store from a store replay line (`
|
|
116
|
-
* Thin lifecycle wrapper over `
|
|
115
|
+
* Sync an existing mirror store from a store replay line (`Observe.exposeStoreReplay(...).api.replay`).
|
|
116
|
+
* Thin lifecycle wrapper over `Observe.syncStoreReplay`: the keyframe (root patch) and the
|
|
117
117
|
* patch tail are applied to the store by the library; UI subscribes to the store as usual
|
|
118
118
|
* (useStoreNode/useStoreSelect).
|
|
119
119
|
*/
|
|
@@ -139,7 +139,7 @@ export function useStoreReplaySync(store, remote, options = {}) {
|
|
|
139
139
|
setError(null);
|
|
140
140
|
if (staleMs === undefined)
|
|
141
141
|
setStale(false); // see useReplaySubscribe: stale re-syncs from common2, no reset-to-false flicker
|
|
142
|
-
const off =
|
|
142
|
+
const off = Observe.syncStoreReplay(store, remote, {
|
|
143
143
|
since: seqRef.current,
|
|
144
144
|
policy,
|
|
145
145
|
hint: hintRef.current,
|
|
@@ -196,14 +196,14 @@ export function useStoreReplaySync(store, remote, options = {}) {
|
|
|
196
196
|
export function useStoreReplayMirror(remote, initial, options = {}) {
|
|
197
197
|
const storeRef = useRef(null);
|
|
198
198
|
if (!storeRef.current || storeRef.current.remote !== remote) {
|
|
199
|
-
storeRef.current = { remote, store:
|
|
199
|
+
storeRef.current = { remote, store: Observe.createStore(initial) };
|
|
200
200
|
}
|
|
201
201
|
const store = storeRef.current.store;
|
|
202
202
|
const sync = useStoreReplaySync(store, remote, options);
|
|
203
203
|
return useMemo(() => ({ ...sync, store }), [sync, store]);
|
|
204
204
|
}
|
|
205
205
|
/**
|
|
206
|
-
* Per-key fold over a store replay line — React counterpart of `
|
|
206
|
+
* Per-key fold over a store replay line — React counterpart of `Observe.syncStoreReplayEach`
|
|
207
207
|
* (internal mirror store + syncStoreReplay + store.each()). cb fires once per CHANGED top-level
|
|
208
208
|
* key per drain window with the current value; the first delivery is the keyframe EXPANDED per
|
|
209
209
|
* key; (key, undefined) = key deleted — cold start / reconnect are not special cases for per-key
|
|
@@ -219,7 +219,7 @@ export function useStoreReplayEach(remote, cb, options = {}) {
|
|
|
219
219
|
const { initial, drain, ...syncOptions } = options;
|
|
220
220
|
const storeRef = useRef(null);
|
|
221
221
|
if (!storeRef.current || storeRef.current.remote !== remote) {
|
|
222
|
-
storeRef.current = { remote, store:
|
|
222
|
+
storeRef.current = { remote, store: Observe.createStore((initial ?? {}), drain !== undefined ? { drain } : undefined) };
|
|
223
223
|
}
|
|
224
224
|
const store = storeRef.current.store;
|
|
225
225
|
// each BEFORE sync: effects run in hook-call order, so the per-key subscriber already exists
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Params } from "wenay-common2";
|
|
2
|
-
type
|
|
2
|
+
type LogInput<T extends object> = T & {
|
|
3
3
|
id: string;
|
|
4
4
|
var?: number;
|
|
5
5
|
time: Date;
|
|
@@ -43,7 +43,7 @@ export declare function getLogsApi<T extends object = {}>(setting: {
|
|
|
43
43
|
limitPer: number;
|
|
44
44
|
varMin?: number;
|
|
45
45
|
}): {
|
|
46
|
-
addLogs(a:
|
|
46
|
+
addLogs(a: LogInput<T>): void;
|
|
47
47
|
params: {
|
|
48
48
|
def: () => {
|
|
49
49
|
minVarLogs: {
|
|
@@ -160,7 +160,7 @@ export declare function PageLogs({ update }: {
|
|
|
160
160
|
export declare function MessageEventLogs({ zIndex }: {
|
|
161
161
|
zIndex?: number;
|
|
162
162
|
}): import("react/jsx-runtime").JSX.Element;
|
|
163
|
-
export declare function
|
|
163
|
+
export declare function LogsPage({ update }: {
|
|
164
164
|
update?: number;
|
|
165
165
|
}): import("react/jsx-runtime").JSX.Element;
|
|
166
166
|
export {};
|
|
@@ -3,9 +3,9 @@ import { AgGridReact } from "ag-grid-react";
|
|
|
3
3
|
import { useCallback, useEffect, useRef } from "react";
|
|
4
4
|
import { copyToClipboard, Params, timeLocalToStr_hhmmss } from "wenay-common2";
|
|
5
5
|
import { renderBy, updateBy } from "../../updateBy";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { contextMenu } from "../menu/menuMouse";
|
|
7
|
+
import { memoryGetOrCreate } from "../utils/memoryStore";
|
|
8
|
+
import { ParamsEditor } from "../components/ParamsEditor";
|
|
9
9
|
const cashLogs = new Map();
|
|
10
10
|
const datumConst = {
|
|
11
11
|
map: cashLogs,
|
|
@@ -22,7 +22,7 @@ const getSettingLogs = () => ({
|
|
|
22
22
|
const settingLogs = { params: Params.GetSimpleParams(getSettingLogs()) };
|
|
23
23
|
// varMin - minimum importance
|
|
24
24
|
export function getLogsApi(setting) {
|
|
25
|
-
const datum =
|
|
25
|
+
const datum = memoryGetOrCreate("settingLogs", settingLogs);
|
|
26
26
|
function addToArr(arr, data, limit) {
|
|
27
27
|
arr.unshift(data);
|
|
28
28
|
if (arr.length > limit)
|
|
@@ -55,8 +55,8 @@ export function getLogsApi(setting) {
|
|
|
55
55
|
}
|
|
56
56
|
export const logsApi = getLogsApi({ limitPer: 500 });
|
|
57
57
|
function InputSettingLogs({}) {
|
|
58
|
-
const datum =
|
|
59
|
-
return _jsx(
|
|
58
|
+
const datum = memoryGetOrCreate("settingLogs", settingLogs);
|
|
59
|
+
return _jsx(ParamsEditor
|
|
60
60
|
// @ts-ignore
|
|
61
61
|
, {
|
|
62
62
|
// @ts-ignore
|
|
@@ -69,7 +69,7 @@ export function PageLogs({ update }) {
|
|
|
69
69
|
const datumFull = datumConst;
|
|
70
70
|
const rowData = [...datumFull.map.values()].flat();
|
|
71
71
|
const datum = datumMiniConst;
|
|
72
|
-
const setting =
|
|
72
|
+
const setting = memoryGetOrCreate("settingLogs", settingLogs);
|
|
73
73
|
const apiGrid = useRef(null);
|
|
74
74
|
useEffect(() => {
|
|
75
75
|
apiGrid.current?.api.sizeColumnsToFit();
|
|
@@ -160,10 +160,8 @@ export function PageLogs({ update }) {
|
|
|
160
160
|
filter: true,
|
|
161
161
|
wrapText: true,
|
|
162
162
|
}, headerHeight: 30, rowHeight: 26, autoSizePadding: 1, rowData: rowData, columnDefs: columns, onCellMouseDown: (e) => {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
// copyToClipboard(e.value)
|
|
166
|
-
mouseMenuApi.map.set("sym", [
|
|
163
|
+
if (e.event instanceof MouseEvent && e.event.button == 2) {
|
|
164
|
+
contextMenu.openAt(e.event, [
|
|
167
165
|
{
|
|
168
166
|
name: "copy", onClick: () => { copyToClipboard(e.value); }
|
|
169
167
|
}
|
|
@@ -189,7 +187,7 @@ function Message({ logs }) {
|
|
|
189
187
|
const tt = {};
|
|
190
188
|
let r = 0;
|
|
191
189
|
export function MessageEventLogs({ zIndex }) {
|
|
192
|
-
const setting =
|
|
190
|
+
const setting = memoryGetOrCreate("settingLogs", settingLogs);
|
|
193
191
|
updateBy(tt);
|
|
194
192
|
updateBy(datumMiniConst, () => {
|
|
195
193
|
const last = datumMiniConst.last[0];
|
|
@@ -222,7 +220,7 @@ const pages = [
|
|
|
222
220
|
{ name: "setting", key: "InputSettingLogs", page: InputSettingLogs },
|
|
223
221
|
];
|
|
224
222
|
const map = Object.fromEntries(pages.map(e => [e.key, e.page]));
|
|
225
|
-
export function
|
|
223
|
+
export function LogsPage({ update }) {
|
|
226
224
|
const datum = defPageBase;
|
|
227
225
|
updateBy(datum);
|
|
228
226
|
const Page = map[datum.keyPage];
|
|
@@ -3,14 +3,14 @@ import React from 'react';
|
|
|
3
3
|
* 1. Log types
|
|
4
4
|
* -----------------------------
|
|
5
5
|
*/
|
|
6
|
-
export interface
|
|
6
|
+
export interface LogInput<T extends object = {}> {
|
|
7
7
|
id: string;
|
|
8
8
|
var?: number;
|
|
9
9
|
time: Date;
|
|
10
10
|
txt: string;
|
|
11
11
|
[key: string]: any;
|
|
12
12
|
}
|
|
13
|
-
export interface
|
|
13
|
+
export interface LogEntry<T extends object = {}> extends LogInput<T> {
|
|
14
14
|
num: number;
|
|
15
15
|
}
|
|
16
16
|
/** -----------------------------
|
|
@@ -18,8 +18,8 @@ export interface tLogs<T extends object = {}> extends tLogsInput<T> {
|
|
|
18
18
|
* -----------------------------
|
|
19
19
|
*/
|
|
20
20
|
interface LogsContextValue {
|
|
21
|
-
logs:
|
|
22
|
-
addLog: (input:
|
|
21
|
+
logs: LogEntry[];
|
|
22
|
+
addLog: (input: LogInput) => void;
|
|
23
23
|
minVarLogs: number;
|
|
24
24
|
setMinVarLogs: (value: number) => void;
|
|
25
25
|
minVarMessage: number;
|
|
@@ -2,11 +2,11 @@ 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.
|
|
5
|
+
* 2. memoryGetOrCreate function -
|
|
6
6
|
* loads and saves data in localStorage.
|
|
7
7
|
* -----------------------------
|
|
8
8
|
*/
|
|
9
|
-
function
|
|
9
|
+
function memoryGetOrCreate(key, defaultValue) {
|
|
10
10
|
try {
|
|
11
11
|
const stored = localStorage.getItem(key);
|
|
12
12
|
// If localStorage has no value, write defaultValue
|
|
@@ -32,7 +32,7 @@ function staticGetAdd(key, defaultValue) {
|
|
|
32
32
|
const LogsContext = createContext(null);
|
|
33
33
|
export function LogsProvider({ children }) {
|
|
34
34
|
// 4.1. Load settings from localStorage once (lazy init: the provider rerenders on every addLog)
|
|
35
|
-
const [savedSettings] = useState(() =>
|
|
35
|
+
const [savedSettings] = useState(() => memoryGetOrCreate("logSettings", {
|
|
36
36
|
minVarLogs: 0,
|
|
37
37
|
minVarMessage: 0,
|
|
38
38
|
timeShow: 2,
|
|
@@ -42,7 +42,7 @@ export function LogsProvider({ children }) {
|
|
|
42
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. Settings themselves, initialized from
|
|
45
|
+
// 4.3. Settings themselves, initialized from memoryGetOrCreate 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);
|
|
@@ -2,22 +2,22 @@ import React, { ReactElement } from 'react';
|
|
|
2
2
|
/*******************************************************
|
|
3
3
|
* Menu data types
|
|
4
4
|
*******************************************************/
|
|
5
|
-
export type
|
|
5
|
+
export type MenuItemStrict<T = any> = {
|
|
6
6
|
name: string | ((status?: T) => string);
|
|
7
7
|
getStatus?: (() => T) | null;
|
|
8
8
|
onClick?: ((e: any) => void | undefined | null | ((void | undefined | null | Promise<any> | (() => Promise<any>))[]) | Promise<any>) | null;
|
|
9
9
|
active?: (() => boolean) | null;
|
|
10
10
|
status?: boolean;
|
|
11
|
-
next?: (() => (
|
|
11
|
+
next?: (() => (MenuItem<any> | false)[] | Promise<(MenuItem<any> | false)[]>) | null;
|
|
12
12
|
func?: (() => React.ReactElement | Promise<React.ReactElement>) | null;
|
|
13
|
-
onFocus?: (() =>
|
|
13
|
+
onFocus?: (() => MenuItem<any>[] | Promise<MenuItem<any>[]>) | null;
|
|
14
14
|
menuElement?: typeof MenuElement;
|
|
15
15
|
};
|
|
16
|
-
export type
|
|
16
|
+
export type MenuItem<T = any> = MenuItemStrict<T> | false | null | undefined;
|
|
17
17
|
/*******************************************************
|
|
18
18
|
* Helper type
|
|
19
19
|
*******************************************************/
|
|
20
|
-
type
|
|
20
|
+
type MenuProgressCounters = {
|
|
21
21
|
ok?: number;
|
|
22
22
|
error?: number;
|
|
23
23
|
count?: number;
|
|
@@ -25,20 +25,20 @@ type tCounters = {
|
|
|
25
25
|
/*******************************************************
|
|
26
26
|
* Displays counter/progress with animation and ok/error counts
|
|
27
27
|
*******************************************************/
|
|
28
|
-
declare function
|
|
29
|
-
data:
|
|
28
|
+
declare function MenuProgress({ data }: {
|
|
29
|
+
data: MenuProgressCounters;
|
|
30
30
|
}): ReactElement;
|
|
31
31
|
/*******************************************************
|
|
32
32
|
* Main menu element with onClick and counters
|
|
33
33
|
*******************************************************/
|
|
34
34
|
declare function MenuElement({ data: item, toLeft, className, update, }: {
|
|
35
|
-
data: Pick<
|
|
35
|
+
data: Pick<MenuItemStrict, "onClick" | "active" | "name" | "getStatus">;
|
|
36
36
|
toLeft: boolean;
|
|
37
37
|
className?: (active?: boolean) => string;
|
|
38
38
|
update: () => void;
|
|
39
39
|
}): ReactElement;
|
|
40
40
|
/*******************************************************
|
|
41
|
-
*
|
|
41
|
+
* Menu renders the popup menu with support for
|
|
42
42
|
* nested submenus and their state management.
|
|
43
43
|
*
|
|
44
44
|
* @param {Object} props - Component props.
|
|
@@ -47,7 +47,7 @@ declare function MenuElement({ data: item, toLeft, className, update, }: {
|
|
|
47
47
|
* @param {number} props.coordinate.y - Y coordinate for menu placement.
|
|
48
48
|
* @param {boolean} [props.coordinate.toLeft=false] - Whether the menu should be shifted left.
|
|
49
49
|
* @param {number} [props.coordinate.left=0] - Additional left offset when the menu has nested items.
|
|
50
|
-
* @param {
|
|
50
|
+
* @param {MenuItemStrict[]} props.data - Array of objects describing menu items.
|
|
51
51
|
* @param {number} [props.zIndex] - Menu z-index for overlap visibility.
|
|
52
52
|
* @param {Function} [props.menu] - Function that generates a custom React element for the whole menu.
|
|
53
53
|
* @param {Function} [props.menuElement] - Function that generates a custom React element for one menu item.
|
|
@@ -55,10 +55,10 @@ declare function MenuElement({ data: item, toLeft, className, update, }: {
|
|
|
55
55
|
*
|
|
56
56
|
* @returns {ReactElement} Visual menu element.
|
|
57
57
|
*/
|
|
58
|
-
type
|
|
59
|
-
menu?: (arr:
|
|
60
|
-
menuElement?: (item:
|
|
61
|
-
data:
|
|
58
|
+
type MenuProps = {
|
|
59
|
+
menu?: (arr: MenuItem[]) => ReactElement;
|
|
60
|
+
menuElement?: (item: MenuItem) => ReactElement;
|
|
61
|
+
data: MenuItem[];
|
|
62
62
|
zIndex?: number;
|
|
63
63
|
className?: (active?: boolean) => string;
|
|
64
64
|
coordinate?: {
|
|
@@ -68,5 +68,5 @@ type MenuBaseProps = {
|
|
|
68
68
|
left?: number;
|
|
69
69
|
};
|
|
70
70
|
};
|
|
71
|
-
export declare function
|
|
72
|
-
export {
|
|
71
|
+
export declare function Menu({ coordinate, data, zIndex, menu, className, menuElement, }: MenuProps): ReactElement;
|
|
72
|
+
export { MenuProgress, MenuElement };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { promiseProgress, sleepAsync } from "wenay-common2";
|
|
4
4
|
/*******************************************************
|
|
5
5
|
* Displays counter/progress with animation and ok/error counts
|
|
6
6
|
*******************************************************/
|
|
7
|
-
function
|
|
7
|
+
function MenuProgress({ data }) {
|
|
8
8
|
const [count, setCount] = useState(0);
|
|
9
9
|
const formatLabel = () => {
|
|
10
10
|
if (!data.ok && !data.error)
|
|
@@ -54,7 +54,7 @@ function MenuElement({ data: item, toLeft, className, update, }) {
|
|
|
54
54
|
// If this is an array of tasks, promises, or functions
|
|
55
55
|
if (Array.isArray(result)) {
|
|
56
56
|
const tasks = result.filter(Boolean);
|
|
57
|
-
const pa =
|
|
57
|
+
const pa = promiseProgress(tasks);
|
|
58
58
|
setProgress({});
|
|
59
59
|
unsubOk.current?.();
|
|
60
60
|
unsubErr.current?.();
|
|
@@ -71,8 +71,9 @@ function MenuElement({ data: item, toLeft, className, update, }) {
|
|
|
71
71
|
setProgress(null);
|
|
72
72
|
}
|
|
73
73
|
};
|
|
74
|
-
unsubOk.current = pa.
|
|
75
|
-
unsubErr.current = pa.
|
|
74
|
+
unsubOk.current = pa.onOk((data, i, countOk, countError, count) => onTick(countOk, countError, count));
|
|
75
|
+
unsubErr.current = pa.onError((error, i, countOk, countError, count) => onTick(countOk, countError, count));
|
|
76
|
+
void pa.allSettled();
|
|
76
77
|
}
|
|
77
78
|
// If this is a single promise
|
|
78
79
|
else if (result instanceof Promise) {
|
|
@@ -108,7 +109,7 @@ function MenuElement({ data: item, toLeft, className, update, }) {
|
|
|
108
109
|
}
|
|
109
110
|
}, children: _jsxs("div", { className: "toLine", children: [typeof item.name === "string"
|
|
110
111
|
? item.name
|
|
111
|
-
: item.name(item.getStatus?.()), progress && _jsx(
|
|
112
|
+
: item.name(item.getStatus?.()), progress && _jsx(MenuProgress, { data: progress })] }) }));
|
|
112
113
|
}
|
|
113
114
|
const MenuItemWrapper = ({ item, index, update, className, isLeftAligned, leftPos, menuElement, fullArray, }) => {
|
|
114
115
|
const [childMenu, setChildMenu] = useState([]);
|
|
@@ -186,24 +187,24 @@ const MenuItemWrapper = ({ item, index, update, className, isLeftAligned, leftPo
|
|
|
186
187
|
data: item,
|
|
187
188
|
className,
|
|
188
189
|
update,
|
|
189
|
-
}) ?? (_jsx(MenuElement, { toLeft: isLeftAligned, data: item, className: className, update: update })), _jsxs("div", { children: [item.status && childMenu.length > 0 && (_jsx("div", { style: { position: "relative" }, children: _jsx(
|
|
190
|
+
}) ?? (_jsx(MenuElement, { toLeft: isLeftAligned, data: item, className: className, update: update })), _jsxs("div", { children: [item.status && childMenu.length > 0 && (_jsx("div", { style: { position: "relative" }, children: _jsx(Menu, { data: childMenu, coordinate: {
|
|
190
191
|
x: 3,
|
|
191
192
|
y: 0,
|
|
192
193
|
toLeft: isLeftAligned,
|
|
193
194
|
left: leftPos,
|
|
194
|
-
} }) })), item.status && asyncFuncElement && (_jsx("div", { style: { position: "relative" }, children: _jsx(
|
|
195
|
+
} }) })), item.status && asyncFuncElement && (_jsx("div", { style: { position: "relative" }, children: _jsx(Menu, { menu: () => asyncFuncElement, data: [], coordinate: {
|
|
195
196
|
x: 3,
|
|
196
197
|
y: 0,
|
|
197
198
|
toLeft: isLeftAligned,
|
|
198
199
|
left: leftPos,
|
|
199
|
-
} }) })), item.status && onFocusMenu.length > 0 && (_jsx("div", { style: { position: "relative" }, children: _jsx(
|
|
200
|
+
} }) })), item.status && onFocusMenu.length > 0 && (_jsx("div", { style: { position: "relative" }, children: _jsx(Menu, { data: onFocusMenu, coordinate: {
|
|
200
201
|
x: 3,
|
|
201
202
|
y: 0,
|
|
202
203
|
toLeft: isLeftAligned,
|
|
203
204
|
left: leftPos,
|
|
204
205
|
} }) }))] })] }));
|
|
205
206
|
};
|
|
206
|
-
export function
|
|
207
|
+
export function Menu({ coordinate = { x: 0, y: 0, toLeft: false, left: 0 }, data, zIndex, menu, className, menuElement, }) {
|
|
207
208
|
const [, forceUpdate] = useState(false);
|
|
208
209
|
const update = () => forceUpdate((p) => !p);
|
|
209
210
|
const refMenu = useRef(null);
|
|
@@ -251,4 +252,4 @@ export function MenuBase({ coordinate = { x: 0, y: 0, toLeft: false, left: 0 },
|
|
|
251
252
|
? menu(dataMemo)
|
|
252
253
|
: dataMemo.map((item, i, arr) => (_jsx(MenuItemWrapper, { item: item, index: i, update: update, className: className, isLeftAligned: isLeftAligned, leftPos: leftPos, menuElement: menuElement, fullArray: dataMemo }, typeof item.name === "string" ? item.name : i))) }));
|
|
253
254
|
}
|
|
254
|
-
export {
|
|
255
|
+
export { MenuProgress, MenuElement };
|
|
@@ -1,7 +1,62 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Menu, MenuItem, MenuItemStrict } from "./menu";
|
|
3
|
+
export type ContextMenuPoint = {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
};
|
|
7
|
+
export type ContextMenuAnchor = ContextMenuPoint | {
|
|
8
|
+
clientX: number;
|
|
9
|
+
clientY: number;
|
|
10
|
+
target?: EventTarget | null;
|
|
11
|
+
preventDefault?: () => void;
|
|
12
|
+
stopPropagation?: () => void;
|
|
13
|
+
};
|
|
14
|
+
export type ContextMenuState = {
|
|
15
|
+
open: boolean;
|
|
16
|
+
items: MenuItemStrict[];
|
|
17
|
+
point: ContextMenuPoint;
|
|
18
|
+
source?: string;
|
|
19
|
+
layerId?: string;
|
|
20
|
+
seq: number;
|
|
21
|
+
};
|
|
22
|
+
export type ContextMenuLayerProps = {
|
|
23
|
+
children: React.ReactElement;
|
|
24
|
+
zIndex?: number;
|
|
25
|
+
other?: () => MenuItem[];
|
|
26
|
+
statusOn?: boolean;
|
|
27
|
+
onUnClick?: (e: boolean) => void;
|
|
28
|
+
onConsume?: () => void;
|
|
29
|
+
className?: (active?: boolean) => string;
|
|
30
|
+
};
|
|
31
|
+
export declare function createContextMenu(data?: {
|
|
32
|
+
name?: string;
|
|
33
|
+
}): {
|
|
34
|
+
bb: (b?: boolean) => boolean | undefined;
|
|
35
|
+
readonly map: Map<string, MenuItem[]>;
|
|
36
|
+
readonly menuMouse: {
|
|
37
|
+
name: string;
|
|
38
|
+
readonly value: {
|
|
39
|
+
status: boolean;
|
|
40
|
+
clicks: number;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
getState: () => ContextMenuState;
|
|
44
|
+
subscribe: (cb: () => void) => () => void;
|
|
45
|
+
openAt: (anchor: ContextMenuAnchor, items: readonly MenuItem[] | null | undefined, opts?: {
|
|
46
|
+
source?: string;
|
|
47
|
+
layerId?: string;
|
|
48
|
+
}) => boolean;
|
|
49
|
+
openAtPoint: (point: ContextMenuPoint, items: readonly MenuItem[] | null | undefined, opts?: {
|
|
50
|
+
source?: string;
|
|
51
|
+
layerId?: string;
|
|
52
|
+
}) => boolean;
|
|
53
|
+
close: () => void;
|
|
54
|
+
Layer: ({ children, other, statusOn, onUnClick, onConsume, zIndex, className }: ContextMenuLayerProps) => import("react/jsx-runtime").JSX.Element;
|
|
55
|
+
MenuView: typeof Menu;
|
|
56
|
+
};
|
|
57
|
+
export declare const contextMenu: {
|
|
3
58
|
bb: (b?: boolean) => boolean | undefined;
|
|
4
|
-
readonly map: Map<string,
|
|
59
|
+
readonly map: Map<string, MenuItem[]>;
|
|
5
60
|
readonly menuMouse: {
|
|
6
61
|
name: string;
|
|
7
62
|
readonly value: {
|
|
@@ -9,14 +64,17 @@ export declare const mouseMenuApi: {
|
|
|
9
64
|
clicks: number;
|
|
10
65
|
};
|
|
11
66
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
67
|
+
getState: () => ContextMenuState;
|
|
68
|
+
subscribe: (cb: () => void) => () => void;
|
|
69
|
+
openAt: (anchor: ContextMenuAnchor, items: readonly MenuItem[] | null | undefined, opts?: {
|
|
70
|
+
source?: string;
|
|
71
|
+
layerId?: string;
|
|
72
|
+
}) => boolean;
|
|
73
|
+
openAtPoint: (point: ContextMenuPoint, items: readonly MenuItem[] | null | undefined, opts?: {
|
|
74
|
+
source?: string;
|
|
75
|
+
layerId?: string;
|
|
76
|
+
}) => boolean;
|
|
77
|
+
close: () => void;
|
|
78
|
+
Layer: ({ children, other, statusOn, onUnClick, onConsume, zIndex, className }: ContextMenuLayerProps) => import("react/jsx-runtime").JSX.Element;
|
|
79
|
+
MenuView: typeof Menu;
|
|
22
80
|
};
|