@etsoo/react 1.8.21 → 1.8.23
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/__tests__/EventWatcher.tsx +2 -1
- package/__tests__/States.tsx +27 -29
- package/__tests__/tsconfig.json +5 -4
- package/lib/cjs/app/CoreConstants.js +17 -0
- package/lib/cjs/app/EventWatcher.js +45 -0
- package/lib/cjs/app/InputDialogProps.js +2 -0
- package/lib/cjs/app/ReactUtils.js +173 -0
- package/lib/cjs/components/DnDList.js +136 -0
- package/lib/cjs/components/DynamicRouter.js +39 -0
- package/lib/cjs/components/GridColumn.js +46 -0
- package/lib/cjs/components/GridLoader.js +49 -0
- package/lib/cjs/components/GridMethodRef.js +2 -0
- package/lib/cjs/components/ListItemReact.js +2 -0
- package/lib/cjs/components/ScrollRestoration.js +37 -0
- package/lib/cjs/components/ScrollerGrid.js +254 -0
- package/lib/cjs/components/ScrollerList.js +205 -0
- package/lib/cjs/custom/CustomFieldReact.js +2 -0
- package/lib/cjs/index.js +54 -0
- package/lib/cjs/notifier/Notifier.js +82 -0
- package/lib/cjs/states/CultureState.js +46 -0
- package/lib/cjs/states/IState.js +2 -0
- package/lib/cjs/states/PageState.js +46 -0
- package/lib/cjs/states/State.js +48 -0
- package/lib/cjs/states/UserState.js +80 -0
- package/lib/cjs/uses/useAsyncState.js +39 -0
- package/lib/cjs/uses/useCombinedRefs.js +29 -0
- package/lib/cjs/uses/useDelayedExecutor.js +17 -0
- package/lib/cjs/uses/useDimensions.js +98 -0
- package/lib/cjs/uses/useParamsEx.js +15 -0
- package/lib/cjs/uses/useRefs.js +17 -0
- package/lib/cjs/uses/useRequiredContext.js +19 -0
- package/lib/cjs/uses/useSearchParamsEx.js +19 -0
- package/lib/cjs/uses/useTimeout.js +29 -0
- package/lib/cjs/uses/useWindowScroll.js +53 -0
- package/lib/cjs/uses/useWindowSize.js +53 -0
- package/lib/mjs/app/CoreConstants.d.ts +13 -0
- package/lib/mjs/app/EventWatcher.d.ts +35 -0
- package/lib/mjs/app/InputDialogProps.d.ts +19 -0
- package/lib/mjs/app/ReactUtils.d.ts +41 -0
- package/lib/mjs/components/DnDList.d.ts +74 -0
- package/lib/mjs/components/DynamicRouter.d.ts +24 -0
- package/lib/mjs/components/GridColumn.d.ts +193 -0
- package/lib/mjs/components/GridLoader.d.ts +155 -0
- package/lib/mjs/components/GridMethodRef.d.ts +31 -0
- package/lib/mjs/components/ListItemReact.d.ts +6 -0
- package/lib/mjs/components/ScrollRestoration.d.ts +4 -0
- package/lib/mjs/components/ScrollerGrid.d.ts +112 -0
- package/lib/mjs/components/ScrollerList.d.ts +66 -0
- package/lib/mjs/custom/CustomFieldReact.d.ts +22 -0
- package/lib/mjs/index.d.ts +33 -0
- package/lib/mjs/notifier/Notifier.d.ts +143 -0
- package/lib/mjs/states/CultureState.d.ts +41 -0
- package/lib/mjs/states/IState.d.ts +49 -0
- package/lib/mjs/states/PageState.d.ts +61 -0
- package/lib/mjs/states/State.d.ts +18 -0
- package/lib/mjs/states/UserState.d.ts +56 -0
- package/lib/mjs/uses/useAsyncState.d.ts +11 -0
- package/lib/mjs/uses/useCombinedRefs.d.ts +6 -0
- package/lib/mjs/uses/useDelayedExecutor.d.ts +5 -0
- package/lib/mjs/uses/useDimensions.d.ts +17 -0
- package/lib/mjs/uses/useParamsEx.d.ts +6 -0
- package/lib/mjs/uses/useRefs.d.ts +8 -0
- package/lib/mjs/uses/useRequiredContext.d.ts +7 -0
- package/lib/mjs/uses/useSearchParamsEx.d.ts +6 -0
- package/lib/mjs/uses/useTimeout.d.ts +8 -0
- package/lib/mjs/uses/useWindowScroll.d.ts +12 -0
- package/lib/mjs/uses/useWindowSize.d.ts +10 -0
- package/package.json +21 -24
- package/tsconfig.cjs.json +20 -0
- package/tsconfig.json +3 -3
- package/vite.config.ts +11 -0
- /package/lib/{app → cjs/app}/CoreConstants.d.ts +0 -0
- /package/lib/{app → cjs/app}/EventWatcher.d.ts +0 -0
- /package/lib/{app → cjs/app}/InputDialogProps.d.ts +0 -0
- /package/lib/{app → cjs/app}/ReactUtils.d.ts +0 -0
- /package/lib/{components → cjs/components}/DnDList.d.ts +0 -0
- /package/lib/{components → cjs/components}/DynamicRouter.d.ts +0 -0
- /package/lib/{components → cjs/components}/GridColumn.d.ts +0 -0
- /package/lib/{components → cjs/components}/GridLoader.d.ts +0 -0
- /package/lib/{components → cjs/components}/GridMethodRef.d.ts +0 -0
- /package/lib/{components → cjs/components}/ListItemReact.d.ts +0 -0
- /package/lib/{components → cjs/components}/ScrollRestoration.d.ts +0 -0
- /package/lib/{components → cjs/components}/ScrollerGrid.d.ts +0 -0
- /package/lib/{components → cjs/components}/ScrollerList.d.ts +0 -0
- /package/lib/{custom → cjs/custom}/CustomFieldReact.d.ts +0 -0
- /package/lib/{index.d.ts → cjs/index.d.ts} +0 -0
- /package/lib/{notifier → cjs/notifier}/Notifier.d.ts +0 -0
- /package/lib/{states → cjs/states}/CultureState.d.ts +0 -0
- /package/lib/{states → cjs/states}/IState.d.ts +0 -0
- /package/lib/{states → cjs/states}/PageState.d.ts +0 -0
- /package/lib/{states → cjs/states}/State.d.ts +0 -0
- /package/lib/{states → cjs/states}/UserState.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useAsyncState.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useCombinedRefs.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useDelayedExecutor.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useDimensions.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useParamsEx.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useRefs.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useRequiredContext.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useSearchParamsEx.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useTimeout.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useWindowScroll.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useWindowSize.d.ts +0 -0
- /package/lib/{app → mjs/app}/CoreConstants.js +0 -0
- /package/lib/{app → mjs/app}/EventWatcher.js +0 -0
- /package/lib/{app → mjs/app}/InputDialogProps.js +0 -0
- /package/lib/{app → mjs/app}/ReactUtils.js +0 -0
- /package/lib/{components → mjs/components}/DnDList.js +0 -0
- /package/lib/{components → mjs/components}/DynamicRouter.js +0 -0
- /package/lib/{components → mjs/components}/GridColumn.js +0 -0
- /package/lib/{components → mjs/components}/GridLoader.js +0 -0
- /package/lib/{components → mjs/components}/GridMethodRef.js +0 -0
- /package/lib/{components → mjs/components}/ListItemReact.js +0 -0
- /package/lib/{components → mjs/components}/ScrollRestoration.js +0 -0
- /package/lib/{components → mjs/components}/ScrollerGrid.js +0 -0
- /package/lib/{components → mjs/components}/ScrollerList.js +0 -0
- /package/lib/{custom → mjs/custom}/CustomFieldReact.js +0 -0
- /package/lib/{index.js → mjs/index.js} +0 -0
- /package/lib/{notifier → mjs/notifier}/Notifier.js +0 -0
- /package/lib/{states → mjs/states}/CultureState.js +0 -0
- /package/lib/{states → mjs/states}/IState.js +0 -0
- /package/lib/{states → mjs/states}/PageState.js +0 -0
- /package/lib/{states → mjs/states}/State.js +0 -0
- /package/lib/{states → mjs/states}/UserState.js +0 -0
- /package/lib/{uses → mjs/uses}/useAsyncState.js +0 -0
- /package/lib/{uses → mjs/uses}/useCombinedRefs.js +0 -0
- /package/lib/{uses → mjs/uses}/useDelayedExecutor.js +0 -0
- /package/lib/{uses → mjs/uses}/useDimensions.js +0 -0
- /package/lib/{uses → mjs/uses}/useParamsEx.js +0 -0
- /package/lib/{uses → mjs/uses}/useRefs.js +0 -0
- /package/lib/{uses → mjs/uses}/useRequiredContext.js +0 -0
- /package/lib/{uses → mjs/uses}/useSearchParamsEx.js +0 -0
- /package/lib/{uses → mjs/uses}/useTimeout.js +0 -0
- /package/lib/{uses → mjs/uses}/useWindowScroll.js +0 -0
- /package/lib/{uses → mjs/uses}/useWindowSize.js +0 -0
|
@@ -13,11 +13,12 @@ function App(props: { callback: () => void }) {
|
|
|
13
13
|
once: true
|
|
14
14
|
});
|
|
15
15
|
}, []);
|
|
16
|
+
|
|
16
17
|
return <button onClick={(event) => watcher.do(event)}></button>;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
test("Tests for EventWatcher", () => {
|
|
20
|
-
const callback =
|
|
21
|
+
const callback = vi.fn();
|
|
21
22
|
render(<App callback={callback} />);
|
|
22
23
|
const button = screen.getByRole<HTMLButtonElement>("button");
|
|
23
24
|
button.click();
|
package/__tests__/States.tsx
CHANGED
|
@@ -1,39 +1,37 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { render, screen } from
|
|
3
|
-
import { useAsyncState } from
|
|
4
|
-
import { act } from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, screen } from "@testing-library/react";
|
|
3
|
+
import { useAsyncState } from "../src/uses/useAsyncState";
|
|
4
|
+
import { act } from "react";
|
|
5
5
|
|
|
6
6
|
function App(props: { callback: (state: number) => void }) {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const { callback } = props;
|
|
8
|
+
const [state, setState] = useAsyncState(0);
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const [state1] = useAsyncState<number>();
|
|
11
|
+
expect(state1).toBeUndefined();
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
const click = async () => {
|
|
14
|
+
const currentState = await setState((prev) => prev + 1);
|
|
15
|
+
callback(currentState + 1);
|
|
16
|
+
};
|
|
17
|
+
callback(state);
|
|
18
|
+
return <button onClick={click}>State: {state}</button>;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
test(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
test("Tests for useAsyncState", async () => {
|
|
22
|
+
const callback = vi.fn();
|
|
23
|
+
render(<App callback={callback} />);
|
|
24
|
+
const button = screen.getByRole<HTMLButtonElement>("button");
|
|
25
|
+
expect(button.innerHTML).toBe("State: 0");
|
|
26
|
+
act(() => {
|
|
27
|
+
button.click();
|
|
28
|
+
});
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
expect(button.innerHTML).toBe("State: 1");
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
expect(callback).toHaveBeenLastCalledWith(2);
|
|
32
|
+
// Wait for the state to be updated
|
|
33
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}, 100);
|
|
35
|
+
// Expect to happen
|
|
36
|
+
expect(callback).toHaveBeenLastCalledWith(2);
|
|
39
37
|
});
|
package/__tests__/tsconfig.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
"target": "
|
|
4
|
-
"module": "
|
|
5
|
-
"moduleResolution": "
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ES2022",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
6
|
"allowJs": false,
|
|
7
7
|
"skipLibCheck": true,
|
|
8
8
|
"esModuleInterop": true,
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"isolatedModules": true,
|
|
14
14
|
"noEmit": true,
|
|
15
15
|
"jsx": "react",
|
|
16
|
-
"declaration": true
|
|
16
|
+
"declaration": true,
|
|
17
|
+
"types": ["vitest/globals"]
|
|
17
18
|
},
|
|
18
19
|
"include": [".."]
|
|
19
20
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CoreConstants = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Core constants
|
|
6
|
+
*/
|
|
7
|
+
var CoreConstants;
|
|
8
|
+
(function (CoreConstants) {
|
|
9
|
+
/**
|
|
10
|
+
* User id saved field
|
|
11
|
+
*/
|
|
12
|
+
CoreConstants.FieldUserIdSaved = "UserIdSaved";
|
|
13
|
+
/**
|
|
14
|
+
* Rresh token cache field
|
|
15
|
+
*/
|
|
16
|
+
CoreConstants.FieldRefreshToken = "RefreshToken";
|
|
17
|
+
})(CoreConstants || (exports.CoreConstants = CoreConstants = {}));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EventWatcher = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Event watcher
|
|
6
|
+
*/
|
|
7
|
+
class EventWatcher {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.actions = [];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Add action
|
|
13
|
+
* @param action Action
|
|
14
|
+
*/
|
|
15
|
+
add(action) {
|
|
16
|
+
this.actions.push(action);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Do the event
|
|
20
|
+
* @param event Event
|
|
21
|
+
*/
|
|
22
|
+
do(event) {
|
|
23
|
+
// Type
|
|
24
|
+
const type = typeof event === "string" ? event : event.type;
|
|
25
|
+
// Execute
|
|
26
|
+
const removeIndices = [];
|
|
27
|
+
this.actions.forEach((item, index) => {
|
|
28
|
+
if (!this.isMatch(item, type))
|
|
29
|
+
return;
|
|
30
|
+
item.action(event);
|
|
31
|
+
if (item.once)
|
|
32
|
+
removeIndices.push(index);
|
|
33
|
+
});
|
|
34
|
+
// Remove all once actions
|
|
35
|
+
removeIndices.reverse().forEach((index) => this.actions.splice(index, 1));
|
|
36
|
+
}
|
|
37
|
+
isMatch(action, type) {
|
|
38
|
+
if (action.type == null)
|
|
39
|
+
return true;
|
|
40
|
+
if (typeof action.type === "string")
|
|
41
|
+
return action.type === type;
|
|
42
|
+
return action.type.includes(type);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.EventWatcher = EventWatcher;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReactUtils = void 0;
|
|
4
|
+
const shared_1 = require("@etsoo/shared");
|
|
5
|
+
/**
|
|
6
|
+
* React utils
|
|
7
|
+
*/
|
|
8
|
+
var ReactUtils;
|
|
9
|
+
(function (ReactUtils) {
|
|
10
|
+
/**
|
|
11
|
+
* Format input value
|
|
12
|
+
* @param value Input value
|
|
13
|
+
* @returns Formatted value
|
|
14
|
+
*/
|
|
15
|
+
function formatInputValue(value) {
|
|
16
|
+
if (value === null)
|
|
17
|
+
return undefined;
|
|
18
|
+
if (typeof value === "number")
|
|
19
|
+
return value;
|
|
20
|
+
if (typeof value === "string")
|
|
21
|
+
return value;
|
|
22
|
+
if (Array.isArray(value))
|
|
23
|
+
return value;
|
|
24
|
+
return String(value);
|
|
25
|
+
}
|
|
26
|
+
ReactUtils.formatInputValue = formatInputValue;
|
|
27
|
+
/**
|
|
28
|
+
* Is safe click
|
|
29
|
+
* @param event Mouse event
|
|
30
|
+
* @returns Result
|
|
31
|
+
*/
|
|
32
|
+
function isSafeClick(event) {
|
|
33
|
+
// No target
|
|
34
|
+
// HTMLElement <= Element, SVGElement <= Element
|
|
35
|
+
if (!(event.target instanceof Element))
|
|
36
|
+
return true;
|
|
37
|
+
// Outside of the currentTarget
|
|
38
|
+
let target = event.target;
|
|
39
|
+
if (!event.currentTarget.contains(target))
|
|
40
|
+
return false;
|
|
41
|
+
while (target != null && target != event.currentTarget) {
|
|
42
|
+
const nodeName = target.nodeName.toUpperCase();
|
|
43
|
+
if (nodeName === "INPUT" ||
|
|
44
|
+
nodeName === "BUTTON" ||
|
|
45
|
+
nodeName === "A" ||
|
|
46
|
+
target.hasAttribute("onClick"))
|
|
47
|
+
return false;
|
|
48
|
+
target = target.parentElement;
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
ReactUtils.isSafeClick = isSafeClick;
|
|
53
|
+
/**
|
|
54
|
+
* Trigger input change event
|
|
55
|
+
* @param input Form input
|
|
56
|
+
* @param value New value
|
|
57
|
+
* @param cancelable Cancelable
|
|
58
|
+
*/
|
|
59
|
+
function triggerChange(input, value, cancelable = false) {
|
|
60
|
+
// Radio type not supported
|
|
61
|
+
if (input.type === "radio")
|
|
62
|
+
return;
|
|
63
|
+
// checked?
|
|
64
|
+
const checked = input.type === "checkbox";
|
|
65
|
+
// Property name
|
|
66
|
+
const property = checked ? "checked" : "value";
|
|
67
|
+
// input.value = newValue will not trigger the change event
|
|
68
|
+
// input type = 'hidden' will also not trigger the event
|
|
69
|
+
// https://coryrylan.com/blog/trigger-input-updates-with-react-controlled-inputs
|
|
70
|
+
var nativeInputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, property)?.set;
|
|
71
|
+
if (checked) {
|
|
72
|
+
const checkedValue = input.value == value;
|
|
73
|
+
nativeInputValueSetter?.call(input, checkedValue);
|
|
74
|
+
const clickEvent = new Event("click", {
|
|
75
|
+
bubbles: true,
|
|
76
|
+
cancelable
|
|
77
|
+
});
|
|
78
|
+
input.dispatchEvent(clickEvent);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
nativeInputValueSetter?.call(input, value);
|
|
82
|
+
const inputEvent = new Event("change", {
|
|
83
|
+
bubbles: true,
|
|
84
|
+
cancelable
|
|
85
|
+
});
|
|
86
|
+
input.dispatchEvent(inputEvent);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
ReactUtils.triggerChange = triggerChange;
|
|
90
|
+
/**
|
|
91
|
+
* Update refs
|
|
92
|
+
* @param refs Refs
|
|
93
|
+
* @param data Data
|
|
94
|
+
* @param callback Callback to update refs' value, return false continue to process
|
|
95
|
+
*/
|
|
96
|
+
function updateRefs(refs, data, callback) {
|
|
97
|
+
const local = callback == null
|
|
98
|
+
? undefined
|
|
99
|
+
: typeof callback === "function"
|
|
100
|
+
? callback
|
|
101
|
+
: (item, value) => {
|
|
102
|
+
item[callback] = value;
|
|
103
|
+
};
|
|
104
|
+
let k;
|
|
105
|
+
for (k in refs) {
|
|
106
|
+
const ref = refs[k];
|
|
107
|
+
const item = ref?.current;
|
|
108
|
+
if (item == null)
|
|
109
|
+
continue;
|
|
110
|
+
if (local && local(item, data[k]) !== false) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
else if (item instanceof HTMLInputElement ||
|
|
114
|
+
item instanceof HTMLTextAreaElement ||
|
|
115
|
+
item instanceof HTMLSelectElement) {
|
|
116
|
+
const value = shared_1.Utils.getNestedValue(data, item.name || k);
|
|
117
|
+
const isDateTime = item.type === "datetime-local";
|
|
118
|
+
if (isDateTime || item.type === "date") {
|
|
119
|
+
item.value =
|
|
120
|
+
shared_1.DateUtils.formatForInput(value, isDateTime ? false : undefined) ??
|
|
121
|
+
"";
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
item.value = `${value ?? ""}`;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
item.value = data[k];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
ReactUtils.updateRefs = updateRefs;
|
|
133
|
+
/**
|
|
134
|
+
* Update data with refs
|
|
135
|
+
* @param refs Refs
|
|
136
|
+
* @param data Data
|
|
137
|
+
* @param callback Callback to return new value
|
|
138
|
+
* @param ignoreEmpty Ignore empty string or not, default true
|
|
139
|
+
*/
|
|
140
|
+
function updateRefValues(refs, data, callback, ignoreEmpty = true) {
|
|
141
|
+
const local = callback == null
|
|
142
|
+
? undefined
|
|
143
|
+
: typeof callback === "function"
|
|
144
|
+
? callback
|
|
145
|
+
: (item) => item[callback];
|
|
146
|
+
const formatValue = (value) => {
|
|
147
|
+
if (ignoreEmpty && value === "")
|
|
148
|
+
return null;
|
|
149
|
+
return value;
|
|
150
|
+
};
|
|
151
|
+
let k;
|
|
152
|
+
for (k in refs) {
|
|
153
|
+
const ref = refs[k];
|
|
154
|
+
const item = ref?.current;
|
|
155
|
+
if (item == null)
|
|
156
|
+
continue;
|
|
157
|
+
if (local) {
|
|
158
|
+
data[k] = local(item);
|
|
159
|
+
}
|
|
160
|
+
else if (item instanceof HTMLInputElement) {
|
|
161
|
+
shared_1.Utils.setNestedValue(data, item.name || k, formatValue(shared_1.DomUtils.getInputValue(item)), true);
|
|
162
|
+
}
|
|
163
|
+
else if (item instanceof HTMLTextAreaElement ||
|
|
164
|
+
item instanceof HTMLSelectElement) {
|
|
165
|
+
shared_1.Utils.setNestedValue(data, item.name || k, formatValue(item.value), true);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
data[k] = item.value;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
ReactUtils.updateRefValues = updateRefValues;
|
|
173
|
+
})(ReactUtils || (exports.ReactUtils = ReactUtils = {}));
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DnDList = DnDList;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const core_1 = require("@dnd-kit/core");
|
|
9
|
+
const sortable_1 = require("@dnd-kit/sortable");
|
|
10
|
+
const utilities_1 = require("@dnd-kit/utilities");
|
|
11
|
+
const react_1 = __importDefault(require("react"));
|
|
12
|
+
function SortableItem(props) {
|
|
13
|
+
// Destruct
|
|
14
|
+
const { id, itemRenderer, style = {} } = props;
|
|
15
|
+
// Use sortable
|
|
16
|
+
const { attributes, listeners, setNodeRef, transform, transition, setActivatorNodeRef } = (0, sortable_1.useSortable)({ id });
|
|
17
|
+
const allStyle = {
|
|
18
|
+
...style,
|
|
19
|
+
transform: utilities_1.CSS.Transform.toString(transform),
|
|
20
|
+
transition
|
|
21
|
+
};
|
|
22
|
+
const nodeRef = {
|
|
23
|
+
style: allStyle,
|
|
24
|
+
ref: setNodeRef,
|
|
25
|
+
...attributes
|
|
26
|
+
};
|
|
27
|
+
const actionNodeRef = {
|
|
28
|
+
...listeners,
|
|
29
|
+
ref: setActivatorNodeRef
|
|
30
|
+
};
|
|
31
|
+
return itemRenderer(nodeRef, actionNodeRef);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* DnD (Drag and Drop) sortable list
|
|
35
|
+
* @param props Props
|
|
36
|
+
* @returns Component
|
|
37
|
+
*/
|
|
38
|
+
function DnDList(props) {
|
|
39
|
+
// Destruct
|
|
40
|
+
const { getItemStyle, keyField, itemRenderer, labelField, mRef, onChange, onDragEnd } = props;
|
|
41
|
+
// States
|
|
42
|
+
const [items, setItems] = react_1.default.useState([]);
|
|
43
|
+
const [activeId, setActiveId] = react_1.default.useState();
|
|
44
|
+
const changeItems = (newItems) => {
|
|
45
|
+
// Possible to alter items with the handler
|
|
46
|
+
if (onChange)
|
|
47
|
+
onChange(newItems);
|
|
48
|
+
// Update state
|
|
49
|
+
setItems(newItems);
|
|
50
|
+
};
|
|
51
|
+
// Drag event handlers
|
|
52
|
+
function handleDragStart(event) {
|
|
53
|
+
const { active } = event;
|
|
54
|
+
setActiveId(active.id);
|
|
55
|
+
}
|
|
56
|
+
function handleDragEnd(event) {
|
|
57
|
+
const { active, over } = event;
|
|
58
|
+
if (over && active.id !== over.id) {
|
|
59
|
+
// Indices
|
|
60
|
+
const oldIndex = items.findIndex((item) => item.id === active.id);
|
|
61
|
+
const newIndex = items.findIndex((item) => item.id === over.id);
|
|
62
|
+
// Clone
|
|
63
|
+
const newItems = [...items];
|
|
64
|
+
// Removed item
|
|
65
|
+
const [removed] = newItems.splice(oldIndex, 1);
|
|
66
|
+
// Insert to the destination index
|
|
67
|
+
newItems.splice(newIndex, 0, removed);
|
|
68
|
+
changeItems(newItems);
|
|
69
|
+
// Drag end handler
|
|
70
|
+
if (onDragEnd)
|
|
71
|
+
onDragEnd(newItems);
|
|
72
|
+
}
|
|
73
|
+
setActiveId(undefined);
|
|
74
|
+
}
|
|
75
|
+
// Methods
|
|
76
|
+
react_1.default.useImperativeHandle(mRef, () => {
|
|
77
|
+
return {
|
|
78
|
+
addItem(newItem) {
|
|
79
|
+
// Existence check
|
|
80
|
+
if (items.some((item) => item[labelField] === newItem[labelField])) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
// Clone
|
|
84
|
+
const newItems = [newItem, ...items];
|
|
85
|
+
// Update the state
|
|
86
|
+
changeItems(newItems);
|
|
87
|
+
return true;
|
|
88
|
+
},
|
|
89
|
+
addItems(inputItems) {
|
|
90
|
+
// Clone
|
|
91
|
+
const newItems = [...items];
|
|
92
|
+
// Insert items
|
|
93
|
+
inputItems.forEach((newItem) => {
|
|
94
|
+
// Existence check
|
|
95
|
+
if (newItems.some((item) => item[labelField] === newItem[labelField])) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
newItems.push(newItem);
|
|
99
|
+
});
|
|
100
|
+
// Update the state
|
|
101
|
+
changeItems(newItems);
|
|
102
|
+
return newItems.length - items.length;
|
|
103
|
+
},
|
|
104
|
+
editItem(newItem, index) {
|
|
105
|
+
// Existence check
|
|
106
|
+
const newIndex = items.findIndex((item) => item[labelField] === newItem[labelField]);
|
|
107
|
+
if (newIndex >= 0 && newIndex !== index) {
|
|
108
|
+
// Label field is the same with a different item
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
// Clone
|
|
112
|
+
const newItems = [...items];
|
|
113
|
+
// Remove the item
|
|
114
|
+
newItems.splice(index, 1, newItem);
|
|
115
|
+
// Update the state
|
|
116
|
+
changeItems(newItems);
|
|
117
|
+
return true;
|
|
118
|
+
},
|
|
119
|
+
deleteItem(index) {
|
|
120
|
+
// Clone
|
|
121
|
+
const newItems = [...items];
|
|
122
|
+
// Remove the item
|
|
123
|
+
newItems.splice(index, 1);
|
|
124
|
+
// Update the state
|
|
125
|
+
changeItems(newItems);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}, [items]);
|
|
129
|
+
react_1.default.useEffect(() => {
|
|
130
|
+
setItems(props.items);
|
|
131
|
+
}, [props.items]);
|
|
132
|
+
return ((0, jsx_runtime_1.jsx)(core_1.DndContext, { onDragStart: handleDragStart, onDragEnd: handleDragEnd, children: (0, jsx_runtime_1.jsx)(sortable_1.SortableContext, { items: items, strategy: sortable_1.verticalListSortingStrategy, children: items.map((item, index) => {
|
|
133
|
+
const id = item[keyField];
|
|
134
|
+
return ((0, jsx_runtime_1.jsx)(SortableItem, { id: id, style: getItemStyle(index, id === activeId), itemRenderer: (nodeRef, actionNodeRef) => itemRenderer(item, index, nodeRef, actionNodeRef) }, id));
|
|
135
|
+
}) }) }));
|
|
136
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DynamicRouter = DynamicRouter;
|
|
4
|
+
exports.createDynamicRouter = createDynamicRouter;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const appscript_1 = require("@etsoo/appscript");
|
|
7
|
+
const react_router_1 = require("react-router");
|
|
8
|
+
function getEntries(host) {
|
|
9
|
+
const startUrl = host.getStartUrl();
|
|
10
|
+
return startUrl == null ? undefined : [startUrl];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Dynamic router
|
|
14
|
+
* @param props Props
|
|
15
|
+
* @returns Component
|
|
16
|
+
*/
|
|
17
|
+
function DynamicRouter(props) {
|
|
18
|
+
// Destruct
|
|
19
|
+
const { basename, children } = props;
|
|
20
|
+
// Layout
|
|
21
|
+
const host = appscript_1.BridgeUtils.host;
|
|
22
|
+
return host == null ? ((0, jsx_runtime_1.jsx)(react_router_1.BrowserRouter, { basename: basename, children: children })) : ((0, jsx_runtime_1.jsx)(react_router_1.MemoryRouter, { basename: basename, initialEntries: getEntries(host), children: children }));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create dynamic router
|
|
26
|
+
* @param routes Routes
|
|
27
|
+
* @param opts Options
|
|
28
|
+
* @returns Router
|
|
29
|
+
*/
|
|
30
|
+
function createDynamicRouter(routes, opts) {
|
|
31
|
+
// Is host?
|
|
32
|
+
const host = appscript_1.BridgeUtils.host;
|
|
33
|
+
if (host == null) {
|
|
34
|
+
return (0, react_router_1.createBrowserRouter)(routes, opts);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
return (0, react_router_1.createMemoryRouter)(routes, opts);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GridDeletedCellBoxStyle = exports.GridAlignGet = exports.GridDataType = void 0;
|
|
4
|
+
const appscript_1 = require("@etsoo/appscript");
|
|
5
|
+
const shared_1 = require("@etsoo/shared");
|
|
6
|
+
/**
|
|
7
|
+
* Grid data type
|
|
8
|
+
*/
|
|
9
|
+
var GridDataType = shared_1.DataTypes.CombinedEnum;
|
|
10
|
+
exports.GridDataType = GridDataType;
|
|
11
|
+
/**
|
|
12
|
+
* Data align get
|
|
13
|
+
* @param align Align
|
|
14
|
+
* @param type Data type
|
|
15
|
+
*/
|
|
16
|
+
const GridAlignGet = (align, type) => {
|
|
17
|
+
if (align == null && type != null) {
|
|
18
|
+
if (type === GridDataType.Money ||
|
|
19
|
+
type === GridDataType.IntMoney ||
|
|
20
|
+
type === GridDataType.Int ||
|
|
21
|
+
type === GridDataType.Number)
|
|
22
|
+
return "right";
|
|
23
|
+
else if (type === GridDataType.Boolean)
|
|
24
|
+
return "center";
|
|
25
|
+
}
|
|
26
|
+
return align;
|
|
27
|
+
};
|
|
28
|
+
exports.GridAlignGet = GridAlignGet;
|
|
29
|
+
/**
|
|
30
|
+
* Grid deleted cell box style
|
|
31
|
+
* @param data Data
|
|
32
|
+
* @returns Result
|
|
33
|
+
*/
|
|
34
|
+
const GridDeletedCellBoxStyle = (data) => {
|
|
35
|
+
if (data == null)
|
|
36
|
+
return {};
|
|
37
|
+
const status = "status" in data
|
|
38
|
+
? data.status
|
|
39
|
+
: "entityStatus" in data
|
|
40
|
+
? data.entityStatus
|
|
41
|
+
: appscript_1.EntityStatus.Normal;
|
|
42
|
+
if (status === appscript_1.EntityStatus.Inactivated || status === appscript_1.EntityStatus.Deleted)
|
|
43
|
+
return { textDecoration: "line-through" };
|
|
44
|
+
return {};
|
|
45
|
+
};
|
|
46
|
+
exports.GridDeletedCellBoxStyle = GridDeletedCellBoxStyle;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GridSizeGet = void 0;
|
|
4
|
+
exports.GridDataGet = GridDataGet;
|
|
5
|
+
exports.GridDataGetData = GridDataGetData;
|
|
6
|
+
const shared_1 = require("@etsoo/shared");
|
|
7
|
+
/**
|
|
8
|
+
* Grid size calculation
|
|
9
|
+
* @param size Size
|
|
10
|
+
* @param input Input
|
|
11
|
+
*/
|
|
12
|
+
const GridSizeGet = (size, input) => {
|
|
13
|
+
if (typeof size === "function")
|
|
14
|
+
return size(input);
|
|
15
|
+
return size;
|
|
16
|
+
};
|
|
17
|
+
exports.GridSizeGet = GridSizeGet;
|
|
18
|
+
/**
|
|
19
|
+
* Grid data get with format
|
|
20
|
+
* @param data Data
|
|
21
|
+
* @param template Template
|
|
22
|
+
* @param keepSource Keep source data
|
|
23
|
+
* @returns Json data
|
|
24
|
+
*/
|
|
25
|
+
function GridDataGet(props, template, keepSource) {
|
|
26
|
+
// Destruct
|
|
27
|
+
const { data, ...rest } = props;
|
|
28
|
+
// DomUtils.dataAs(data, template);
|
|
29
|
+
return { ...GridDataGetData(data, template, keepSource), ...rest };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Grid data get with format
|
|
33
|
+
* @param data Data
|
|
34
|
+
* @param template Template
|
|
35
|
+
* @param keepSource Keep source data
|
|
36
|
+
* @returns Json data
|
|
37
|
+
*/
|
|
38
|
+
function GridDataGetData(data, template, keepSource) {
|
|
39
|
+
// Clear form empty value
|
|
40
|
+
if (data instanceof FormData) {
|
|
41
|
+
shared_1.DomUtils.clearFormData(data);
|
|
42
|
+
}
|
|
43
|
+
// Conditions
|
|
44
|
+
// Set keepSource to true to hold form data, even they are invisible from the conditions
|
|
45
|
+
const conditions = data == null
|
|
46
|
+
? {}
|
|
47
|
+
: shared_1.DomUtils.dataAs(data, template, keepSource);
|
|
48
|
+
return conditions;
|
|
49
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ScrollRestoration = ScrollRestoration;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const react_router_1 = require("react-router");
|
|
10
|
+
const useWindowScroll_1 = require("../uses/useWindowScroll");
|
|
11
|
+
const urls = {};
|
|
12
|
+
/**
|
|
13
|
+
* Scroll restoration
|
|
14
|
+
*/
|
|
15
|
+
function ScrollRestoration() {
|
|
16
|
+
// Location key
|
|
17
|
+
const { key } = (0, react_router_1.useLocation)();
|
|
18
|
+
// Mounted
|
|
19
|
+
const mounted = react_1.default.useRef(false);
|
|
20
|
+
// Detect scroll
|
|
21
|
+
const data = (0, useWindowScroll_1.useWindowScroll)();
|
|
22
|
+
if (mounted.current) {
|
|
23
|
+
urls[key] = data;
|
|
24
|
+
}
|
|
25
|
+
// Setup
|
|
26
|
+
react_1.default.useEffect(() => {
|
|
27
|
+
const pos = urls[key];
|
|
28
|
+
if (pos) {
|
|
29
|
+
window.scrollTo(pos.x, pos.y);
|
|
30
|
+
}
|
|
31
|
+
mounted.current = true;
|
|
32
|
+
return () => {
|
|
33
|
+
mounted.current = false;
|
|
34
|
+
};
|
|
35
|
+
}, [key]);
|
|
36
|
+
return (0, jsx_runtime_1.jsx)(react_1.default.Fragment, {});
|
|
37
|
+
}
|