@etsoo/materialui 1.5.30 → 1.5.32
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__/ReactAppTests.tsx +3 -3
- package/lib/cjs/DataTable.d.ts +2 -2
- package/lib/cjs/DataTable.js +1 -1
- package/lib/cjs/ListMultipler.d.ts +51 -0
- package/lib/cjs/ListMultipler.js +61 -0
- package/lib/cjs/MUUtils.d.ts +1 -1
- package/lib/cjs/app/IServiceApp.d.ts +7 -1
- package/lib/cjs/app/ServiceApp.d.ts +7 -1
- package/lib/cjs/app/ServiceApp.js +13 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/mjs/DataTable.d.ts +2 -2
- package/lib/mjs/DataTable.js +1 -1
- package/lib/mjs/ListMultipler.d.ts +51 -0
- package/lib/mjs/ListMultipler.js +55 -0
- package/lib/mjs/MUUtils.d.ts +1 -1
- package/lib/mjs/app/IServiceApp.d.ts +7 -1
- package/lib/mjs/app/ServiceApp.d.ts +7 -1
- package/lib/mjs/app/ServiceApp.js +13 -0
- package/lib/mjs/index.d.ts +1 -0
- package/lib/mjs/index.js +1 -0
- package/package.json +7 -7
- package/src/CultureDataTable.tsx +1 -1
- package/src/DataTable.tsx +7 -4
- package/src/ListMultipler.tsx +153 -0
- package/src/MUUtils.ts +1 -1
- package/src/app/IServiceApp.ts +13 -1
- package/src/app/ServiceApp.ts +19 -1
- package/src/index.ts +1 -0
- package/vite.config.mts +5 -0
|
@@ -72,10 +72,10 @@ const root = document.body;
|
|
|
72
72
|
const container: HTMLElement = document.createElement("div");
|
|
73
73
|
root.append(container);
|
|
74
74
|
|
|
75
|
-
// The state provider
|
|
76
|
-
const Provider = ReactApp.notifierProvider;
|
|
77
|
-
|
|
78
75
|
act(() => {
|
|
76
|
+
// The state provider
|
|
77
|
+
const Provider = ReactApp.notifierProvider;
|
|
78
|
+
|
|
79
79
|
// Concorrent renderer needs act block
|
|
80
80
|
const reactRoot = createRoot(container);
|
|
81
81
|
reactRoot.render(<Provider />);
|
package/lib/cjs/DataTable.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { GridRowId, GridValidRowModel } from "@mui/x-data-grid/models
|
|
2
|
-
import { DataGridProps } from "@mui/x-data-grid/
|
|
1
|
+
import { GridRowId, GridValidRowModel } from "@mui/x-data-grid/models";
|
|
2
|
+
import { DataGridProps } from "@mui/x-data-grid/internals";
|
|
3
3
|
/**
|
|
4
4
|
* Data table selected cell params
|
|
5
5
|
*/
|
package/lib/cjs/DataTable.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.DataTable = DataTable;
|
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
8
|
const react_1 = __importDefault(require("react"));
|
|
9
9
|
const ReactApp_1 = require("./app/ReactApp");
|
|
10
|
-
const DataGrid_1 = require("@mui/x-data-grid/DataGrid
|
|
10
|
+
const DataGrid_1 = require("@mui/x-data-grid/DataGrid");
|
|
11
11
|
/**
|
|
12
12
|
* Data table
|
|
13
13
|
* @param props Props
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { DataTypes, IdType } from "@etsoo/shared";
|
|
2
|
+
import { ListProps } from "@mui/material/List";
|
|
3
|
+
import { ListItemProps } from "@mui/material/ListItem";
|
|
4
|
+
import { ListItemTextProps } from "@mui/material/ListItemText";
|
|
5
|
+
type ListItemLabel<T extends object> = DataTypes.Keys<T, string | undefined> | ((item: T) => string | undefined);
|
|
6
|
+
/**
|
|
7
|
+
* List multipler component props
|
|
8
|
+
*/
|
|
9
|
+
export type ListMultiplerProps<T extends object> = ListProps & {
|
|
10
|
+
/**
|
|
11
|
+
* List data
|
|
12
|
+
*/
|
|
13
|
+
data: T[];
|
|
14
|
+
/**
|
|
15
|
+
* Id field name
|
|
16
|
+
*/
|
|
17
|
+
idField: DataTypes.Keys<T, IdType>;
|
|
18
|
+
/**
|
|
19
|
+
* Primary label field name or function
|
|
20
|
+
*/
|
|
21
|
+
primaryLabel: ListItemLabel<T>;
|
|
22
|
+
/**
|
|
23
|
+
* Secondary label field name or function
|
|
24
|
+
*/
|
|
25
|
+
secondaryLabel?: ListItemLabel<T>;
|
|
26
|
+
/**
|
|
27
|
+
* List item props
|
|
28
|
+
*/
|
|
29
|
+
listItemProps?: ListItemProps;
|
|
30
|
+
/**
|
|
31
|
+
* List item text props
|
|
32
|
+
*/
|
|
33
|
+
listItemTextProps?: Omit<ListItemTextProps, "primary" | "secondary">;
|
|
34
|
+
/**
|
|
35
|
+
* Input name
|
|
36
|
+
*/
|
|
37
|
+
name?: string;
|
|
38
|
+
/**
|
|
39
|
+
* On change event
|
|
40
|
+
* @param items The selected items
|
|
41
|
+
* @param ids The selected IDs
|
|
42
|
+
*/
|
|
43
|
+
onCheckItems?: (items: T[], ids: unknown[]) => void;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* List multipler component
|
|
47
|
+
* @param props Props
|
|
48
|
+
* @returns Component
|
|
49
|
+
*/
|
|
50
|
+
export declare function ListMultipler<T extends object>(props: ListMultiplerProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
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.ListMultipler = ListMultipler;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const Checkbox_1 = __importDefault(require("@mui/material/Checkbox"));
|
|
9
|
+
const List_1 = __importDefault(require("@mui/material/List"));
|
|
10
|
+
const ListItem_1 = __importDefault(require("@mui/material/ListItem"));
|
|
11
|
+
const ListItemButton_1 = __importDefault(require("@mui/material/ListItemButton"));
|
|
12
|
+
const ListItemIcon_1 = __importDefault(require("@mui/material/ListItemIcon"));
|
|
13
|
+
const ListItemText_1 = __importDefault(require("@mui/material/ListItemText"));
|
|
14
|
+
const react_1 = __importDefault(require("react"));
|
|
15
|
+
function GetListItemLabel(data, label) {
|
|
16
|
+
if (label == null)
|
|
17
|
+
return undefined;
|
|
18
|
+
if (typeof label === "function") {
|
|
19
|
+
return label(data);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
return data[label];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* List multipler component
|
|
27
|
+
* @param props Props
|
|
28
|
+
* @returns Component
|
|
29
|
+
*/
|
|
30
|
+
function ListMultipler(props) {
|
|
31
|
+
// Destruct
|
|
32
|
+
const { data, idField, primaryLabel, secondaryLabel, listItemProps, listItemTextProps, name, onCheckItems, ...rest } = props;
|
|
33
|
+
// Refs
|
|
34
|
+
const initialized = react_1.default.useRef(false);
|
|
35
|
+
react_1.default.useEffect(() => {
|
|
36
|
+
initialized.current = true;
|
|
37
|
+
}, []);
|
|
38
|
+
// State
|
|
39
|
+
const [checked, setChecked] = react_1.default.useState([]);
|
|
40
|
+
const ids = react_1.default.useMemo(() => {
|
|
41
|
+
const ids = checked.map((u) => u[idField]);
|
|
42
|
+
if (onCheckItems && initialized.current) {
|
|
43
|
+
onCheckItems(checked, ids);
|
|
44
|
+
}
|
|
45
|
+
return ids;
|
|
46
|
+
}, [checked]);
|
|
47
|
+
function handleToggle(id) {
|
|
48
|
+
if (ids.includes(id)) {
|
|
49
|
+
setChecked((prev) => prev.filter((u) => u[idField] !== id));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const item = data.find((u) => u[idField] === id);
|
|
53
|
+
if (item) {
|
|
54
|
+
setChecked((prev) => [...prev, item]);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const inputType = typeof ids[0] === "string" ? "text" : "number";
|
|
59
|
+
// Layout
|
|
60
|
+
return ((0, jsx_runtime_1.jsxs)(List_1.default, { ...rest, children: [name && ((0, jsx_runtime_1.jsx)("input", { type: inputType, style: { display: "none" }, name: name, value: ids.join(","), readOnly: true })), data.map((u) => ((0, jsx_runtime_1.jsx)(ListItem_1.default, { ...listItemProps, children: (0, jsx_runtime_1.jsxs)(ListItemButton_1.default, { dense: true, onClick: () => handleToggle(u[idField]), children: [(0, jsx_runtime_1.jsx)(ListItemIcon_1.default, { children: (0, jsx_runtime_1.jsx)(Checkbox_1.default, { edge: "start", disableRipple: true, checked: ids.includes(u[idField]) }) }), (0, jsx_runtime_1.jsx)(ListItemText_1.default, { primary: GetListItemLabel(u, primaryLabel), secondary: GetListItemLabel(u, secondaryLabel), ...listItemTextProps })] }) }, `${u[idField]}`)))] }));
|
|
61
|
+
}
|
package/lib/cjs/MUUtils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApiRefreshTokenDto, IApi, IApiPayload } from "@etsoo/appscript";
|
|
1
|
+
import { ApiRefreshTokenDto, IApi, IApiPayload, TokenAuthRQ } from "@etsoo/appscript";
|
|
2
2
|
import { ReactAppType } from "./ReactApp";
|
|
3
3
|
import { IServiceUser, ServiceUserToken } from "./IServiceUser";
|
|
4
4
|
import { IActionResult } from "@etsoo/shared";
|
|
@@ -14,6 +14,12 @@ export interface IServiceApp extends ReactAppType {
|
|
|
14
14
|
* Core system origin
|
|
15
15
|
*/
|
|
16
16
|
readonly coreOrigin: string;
|
|
17
|
+
/**
|
|
18
|
+
* Get token authorization request data
|
|
19
|
+
* @param api API, if not provided, use the core API
|
|
20
|
+
* @returns Result
|
|
21
|
+
*/
|
|
22
|
+
getTokenAuthRQ(api?: IApi): TokenAuthRQ;
|
|
17
23
|
/**
|
|
18
24
|
* Load core system UI
|
|
19
25
|
* @param tryLogin Try login or not
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApiRefreshTokenDto, AppLoginParams, AppTryLoginParams, ExternalEndpoint, IApi, IApiPayload } from "@etsoo/appscript";
|
|
1
|
+
import { ApiRefreshTokenDto, AppLoginParams, AppTryLoginParams, ExternalEndpoint, IApi, IApiPayload, TokenAuthRQ } from "@etsoo/appscript";
|
|
2
2
|
import { IServiceApp } from "./IServiceApp";
|
|
3
3
|
import { IServiceAppSettings } from "./IServiceAppSettings";
|
|
4
4
|
import { IServiceUser, ServiceUserToken } from "./IServiceUser";
|
|
@@ -31,6 +31,12 @@ export declare class ServiceApp<U extends IServiceUser = IServiceUser, S extends
|
|
|
31
31
|
* @param debug Debug mode
|
|
32
32
|
*/
|
|
33
33
|
constructor(settings: S, name: string, debug?: boolean);
|
|
34
|
+
/**
|
|
35
|
+
* Get token authorization request data
|
|
36
|
+
* @param api API, if not provided, use the core API
|
|
37
|
+
* @returns Result
|
|
38
|
+
*/
|
|
39
|
+
getTokenAuthRQ(api?: IApi): TokenAuthRQ;
|
|
34
40
|
/**
|
|
35
41
|
* Load core system UI
|
|
36
42
|
* @param tryLogin Try login or not
|
|
@@ -43,6 +43,19 @@ class ServiceApp extends ReactApp_1.ReactApp {
|
|
|
43
43
|
this.coreApi = this.createApi(this.coreName, coreEndpoint);
|
|
44
44
|
this.keepLogin = true;
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Get token authorization request data
|
|
48
|
+
* @param api API, if not provided, use the core API
|
|
49
|
+
* @returns Result
|
|
50
|
+
*/
|
|
51
|
+
getTokenAuthRQ(api) {
|
|
52
|
+
api ??= this.coreApi;
|
|
53
|
+
const auth = api.getAuthorization();
|
|
54
|
+
if (auth == null) {
|
|
55
|
+
throw new Error("Authorization is required.");
|
|
56
|
+
}
|
|
57
|
+
return { accessToken: auth.token, tokenScheme: auth.scheme };
|
|
58
|
+
}
|
|
46
59
|
/**
|
|
47
60
|
* Load core system UI
|
|
48
61
|
* @param tryLogin Try login or not
|
package/lib/cjs/index.d.ts
CHANGED
|
@@ -73,6 +73,7 @@ export * from "./LinkEx";
|
|
|
73
73
|
export * from "./ListChooser";
|
|
74
74
|
export * from "./ListItemRightIcon";
|
|
75
75
|
export * from "./ListMoreDisplay";
|
|
76
|
+
export * from "./ListMultipler";
|
|
76
77
|
export * from "./LoadingButton";
|
|
77
78
|
export * from "./MaskInput";
|
|
78
79
|
export * from "./MenuButton";
|
package/lib/cjs/index.js
CHANGED
|
@@ -89,6 +89,7 @@ __exportStar(require("./LinkEx"), exports);
|
|
|
89
89
|
__exportStar(require("./ListChooser"), exports);
|
|
90
90
|
__exportStar(require("./ListItemRightIcon"), exports);
|
|
91
91
|
__exportStar(require("./ListMoreDisplay"), exports);
|
|
92
|
+
__exportStar(require("./ListMultipler"), exports);
|
|
92
93
|
__exportStar(require("./LoadingButton"), exports);
|
|
93
94
|
__exportStar(require("./MaskInput"), exports);
|
|
94
95
|
__exportStar(require("./MenuButton"), exports);
|
package/lib/mjs/DataTable.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { GridRowId, GridValidRowModel } from "@mui/x-data-grid/models
|
|
2
|
-
import { DataGridProps } from "@mui/x-data-grid/
|
|
1
|
+
import { GridRowId, GridValidRowModel } from "@mui/x-data-grid/models";
|
|
2
|
+
import { DataGridProps } from "@mui/x-data-grid/internals";
|
|
3
3
|
/**
|
|
4
4
|
* Data table selected cell params
|
|
5
5
|
*/
|
package/lib/mjs/DataTable.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { useAppContext } from "./app/ReactApp";
|
|
4
|
-
import { DataGrid } from "@mui/x-data-grid/DataGrid
|
|
4
|
+
import { DataGrid } from "@mui/x-data-grid/DataGrid";
|
|
5
5
|
/**
|
|
6
6
|
* Data table
|
|
7
7
|
* @param props Props
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { DataTypes, IdType } from "@etsoo/shared";
|
|
2
|
+
import { ListProps } from "@mui/material/List";
|
|
3
|
+
import { ListItemProps } from "@mui/material/ListItem";
|
|
4
|
+
import { ListItemTextProps } from "@mui/material/ListItemText";
|
|
5
|
+
type ListItemLabel<T extends object> = DataTypes.Keys<T, string | undefined> | ((item: T) => string | undefined);
|
|
6
|
+
/**
|
|
7
|
+
* List multipler component props
|
|
8
|
+
*/
|
|
9
|
+
export type ListMultiplerProps<T extends object> = ListProps & {
|
|
10
|
+
/**
|
|
11
|
+
* List data
|
|
12
|
+
*/
|
|
13
|
+
data: T[];
|
|
14
|
+
/**
|
|
15
|
+
* Id field name
|
|
16
|
+
*/
|
|
17
|
+
idField: DataTypes.Keys<T, IdType>;
|
|
18
|
+
/**
|
|
19
|
+
* Primary label field name or function
|
|
20
|
+
*/
|
|
21
|
+
primaryLabel: ListItemLabel<T>;
|
|
22
|
+
/**
|
|
23
|
+
* Secondary label field name or function
|
|
24
|
+
*/
|
|
25
|
+
secondaryLabel?: ListItemLabel<T>;
|
|
26
|
+
/**
|
|
27
|
+
* List item props
|
|
28
|
+
*/
|
|
29
|
+
listItemProps?: ListItemProps;
|
|
30
|
+
/**
|
|
31
|
+
* List item text props
|
|
32
|
+
*/
|
|
33
|
+
listItemTextProps?: Omit<ListItemTextProps, "primary" | "secondary">;
|
|
34
|
+
/**
|
|
35
|
+
* Input name
|
|
36
|
+
*/
|
|
37
|
+
name?: string;
|
|
38
|
+
/**
|
|
39
|
+
* On change event
|
|
40
|
+
* @param items The selected items
|
|
41
|
+
* @param ids The selected IDs
|
|
42
|
+
*/
|
|
43
|
+
onCheckItems?: (items: T[], ids: unknown[]) => void;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* List multipler component
|
|
47
|
+
* @param props Props
|
|
48
|
+
* @returns Component
|
|
49
|
+
*/
|
|
50
|
+
export declare function ListMultipler<T extends object>(props: ListMultiplerProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Checkbox from "@mui/material/Checkbox";
|
|
3
|
+
import List from "@mui/material/List";
|
|
4
|
+
import ListItem from "@mui/material/ListItem";
|
|
5
|
+
import ListItemButton from "@mui/material/ListItemButton";
|
|
6
|
+
import ListItemIcon from "@mui/material/ListItemIcon";
|
|
7
|
+
import ListItemText from "@mui/material/ListItemText";
|
|
8
|
+
import React from "react";
|
|
9
|
+
function GetListItemLabel(data, label) {
|
|
10
|
+
if (label == null)
|
|
11
|
+
return undefined;
|
|
12
|
+
if (typeof label === "function") {
|
|
13
|
+
return label(data);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
return data[label];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* List multipler component
|
|
21
|
+
* @param props Props
|
|
22
|
+
* @returns Component
|
|
23
|
+
*/
|
|
24
|
+
export function ListMultipler(props) {
|
|
25
|
+
// Destruct
|
|
26
|
+
const { data, idField, primaryLabel, secondaryLabel, listItemProps, listItemTextProps, name, onCheckItems, ...rest } = props;
|
|
27
|
+
// Refs
|
|
28
|
+
const initialized = React.useRef(false);
|
|
29
|
+
React.useEffect(() => {
|
|
30
|
+
initialized.current = true;
|
|
31
|
+
}, []);
|
|
32
|
+
// State
|
|
33
|
+
const [checked, setChecked] = React.useState([]);
|
|
34
|
+
const ids = React.useMemo(() => {
|
|
35
|
+
const ids = checked.map((u) => u[idField]);
|
|
36
|
+
if (onCheckItems && initialized.current) {
|
|
37
|
+
onCheckItems(checked, ids);
|
|
38
|
+
}
|
|
39
|
+
return ids;
|
|
40
|
+
}, [checked]);
|
|
41
|
+
function handleToggle(id) {
|
|
42
|
+
if (ids.includes(id)) {
|
|
43
|
+
setChecked((prev) => prev.filter((u) => u[idField] !== id));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const item = data.find((u) => u[idField] === id);
|
|
47
|
+
if (item) {
|
|
48
|
+
setChecked((prev) => [...prev, item]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const inputType = typeof ids[0] === "string" ? "text" : "number";
|
|
53
|
+
// Layout
|
|
54
|
+
return (_jsxs(List, { ...rest, children: [name && (_jsx("input", { type: inputType, style: { display: "none" }, name: name, value: ids.join(","), readOnly: true })), data.map((u) => (_jsx(ListItem, { ...listItemProps, children: _jsxs(ListItemButton, { dense: true, onClick: () => handleToggle(u[idField]), children: [_jsx(ListItemIcon, { children: _jsx(Checkbox, { edge: "start", disableRipple: true, checked: ids.includes(u[idField]) }) }), _jsx(ListItemText, { primary: GetListItemLabel(u, primaryLabel), secondary: GetListItemLabel(u, secondaryLabel), ...listItemTextProps })] }) }, `${u[idField]}`)))] }));
|
|
55
|
+
}
|
package/lib/mjs/MUUtils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApiRefreshTokenDto, IApi, IApiPayload } from "@etsoo/appscript";
|
|
1
|
+
import { ApiRefreshTokenDto, IApi, IApiPayload, TokenAuthRQ } from "@etsoo/appscript";
|
|
2
2
|
import { ReactAppType } from "./ReactApp";
|
|
3
3
|
import { IServiceUser, ServiceUserToken } from "./IServiceUser";
|
|
4
4
|
import { IActionResult } from "@etsoo/shared";
|
|
@@ -14,6 +14,12 @@ export interface IServiceApp extends ReactAppType {
|
|
|
14
14
|
* Core system origin
|
|
15
15
|
*/
|
|
16
16
|
readonly coreOrigin: string;
|
|
17
|
+
/**
|
|
18
|
+
* Get token authorization request data
|
|
19
|
+
* @param api API, if not provided, use the core API
|
|
20
|
+
* @returns Result
|
|
21
|
+
*/
|
|
22
|
+
getTokenAuthRQ(api?: IApi): TokenAuthRQ;
|
|
17
23
|
/**
|
|
18
24
|
* Load core system UI
|
|
19
25
|
* @param tryLogin Try login or not
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApiRefreshTokenDto, AppLoginParams, AppTryLoginParams, ExternalEndpoint, IApi, IApiPayload } from "@etsoo/appscript";
|
|
1
|
+
import { ApiRefreshTokenDto, AppLoginParams, AppTryLoginParams, ExternalEndpoint, IApi, IApiPayload, TokenAuthRQ } from "@etsoo/appscript";
|
|
2
2
|
import { IServiceApp } from "./IServiceApp";
|
|
3
3
|
import { IServiceAppSettings } from "./IServiceAppSettings";
|
|
4
4
|
import { IServiceUser, ServiceUserToken } from "./IServiceUser";
|
|
@@ -31,6 +31,12 @@ export declare class ServiceApp<U extends IServiceUser = IServiceUser, S extends
|
|
|
31
31
|
* @param debug Debug mode
|
|
32
32
|
*/
|
|
33
33
|
constructor(settings: S, name: string, debug?: boolean);
|
|
34
|
+
/**
|
|
35
|
+
* Get token authorization request data
|
|
36
|
+
* @param api API, if not provided, use the core API
|
|
37
|
+
* @returns Result
|
|
38
|
+
*/
|
|
39
|
+
getTokenAuthRQ(api?: IApi): TokenAuthRQ;
|
|
34
40
|
/**
|
|
35
41
|
* Load core system UI
|
|
36
42
|
* @param tryLogin Try login or not
|
|
@@ -40,6 +40,19 @@ export class ServiceApp extends ReactApp {
|
|
|
40
40
|
this.coreApi = this.createApi(this.coreName, coreEndpoint);
|
|
41
41
|
this.keepLogin = true;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Get token authorization request data
|
|
45
|
+
* @param api API, if not provided, use the core API
|
|
46
|
+
* @returns Result
|
|
47
|
+
*/
|
|
48
|
+
getTokenAuthRQ(api) {
|
|
49
|
+
api ??= this.coreApi;
|
|
50
|
+
const auth = api.getAuthorization();
|
|
51
|
+
if (auth == null) {
|
|
52
|
+
throw new Error("Authorization is required.");
|
|
53
|
+
}
|
|
54
|
+
return { accessToken: auth.token, tokenScheme: auth.scheme };
|
|
55
|
+
}
|
|
43
56
|
/**
|
|
44
57
|
* Load core system UI
|
|
45
58
|
* @param tryLogin Try login or not
|
package/lib/mjs/index.d.ts
CHANGED
|
@@ -73,6 +73,7 @@ export * from "./LinkEx";
|
|
|
73
73
|
export * from "./ListChooser";
|
|
74
74
|
export * from "./ListItemRightIcon";
|
|
75
75
|
export * from "./ListMoreDisplay";
|
|
76
|
+
export * from "./ListMultipler";
|
|
76
77
|
export * from "./LoadingButton";
|
|
77
78
|
export * from "./MaskInput";
|
|
78
79
|
export * from "./MenuButton";
|
package/lib/mjs/index.js
CHANGED
|
@@ -73,6 +73,7 @@ export * from "./LinkEx";
|
|
|
73
73
|
export * from "./ListChooser";
|
|
74
74
|
export * from "./ListItemRightIcon";
|
|
75
75
|
export * from "./ListMoreDisplay";
|
|
76
|
+
export * from "./ListMultipler";
|
|
76
77
|
export * from "./LoadingButton";
|
|
77
78
|
export * from "./MaskInput";
|
|
78
79
|
export * from "./MenuButton";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/materialui",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.32",
|
|
4
4
|
"description": "TypeScript Material-UI Implementation",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/mjs/index.js",
|
|
@@ -40,14 +40,14 @@
|
|
|
40
40
|
"@dnd-kit/sortable": "^10.0.0",
|
|
41
41
|
"@emotion/react": "^11.14.0",
|
|
42
42
|
"@emotion/styled": "^11.14.0",
|
|
43
|
-
"@etsoo/appscript": "^1.6.
|
|
43
|
+
"@etsoo/appscript": "^1.6.26",
|
|
44
44
|
"@etsoo/notificationbase": "^1.1.60",
|
|
45
|
-
"@etsoo/react": "^1.8.
|
|
46
|
-
"@etsoo/shared": "^1.2.
|
|
45
|
+
"@etsoo/react": "^1.8.40",
|
|
46
|
+
"@etsoo/shared": "^1.2.69",
|
|
47
47
|
"@mui/icons-material": "^7.0.2",
|
|
48
48
|
"@mui/material": "^7.0.2",
|
|
49
|
-
"@mui/x-data-grid": "^
|
|
50
|
-
"chart.js": "^4.4.
|
|
49
|
+
"@mui/x-data-grid": "^8.0.0",
|
|
50
|
+
"chart.js": "^4.4.9",
|
|
51
51
|
"chartjs-plugin-datalabels": "^2.2.0",
|
|
52
52
|
"dompurify": "^3.2.5",
|
|
53
53
|
"eventemitter3": "^5.0.1",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"@types/react-dom": "^18.3.6",
|
|
82
82
|
"@types/react-input-mask": "^3.0.6",
|
|
83
83
|
"@types/react-window": "^1.8.8",
|
|
84
|
-
"@vitejs/plugin-react": "^4.
|
|
84
|
+
"@vitejs/plugin-react": "^4.4.1",
|
|
85
85
|
"jsdom": "^26.1.0",
|
|
86
86
|
"typescript": "^5.8.3",
|
|
87
87
|
"vitest": "^3.1.1"
|
package/src/CultureDataTable.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import { DataTable, DataTableProps } from "./DataTable";
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { ListType1 } from "@etsoo/shared";
|
|
4
4
|
import { useAppContext } from "./app/ReactApp";
|
|
5
|
-
import { GridRenderCellParams } from "@mui/x-data-grid/models/params
|
|
5
|
+
import { GridRenderCellParams } from "@mui/x-data-grid/models/params";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Culture table props
|
package/src/DataTable.tsx
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { useAppContext } from "./app/ReactApp";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import {
|
|
4
|
+
GridCellModesModel,
|
|
5
|
+
GridRowId,
|
|
6
|
+
GridValidRowModel
|
|
7
|
+
} from "@mui/x-data-grid/models";
|
|
8
|
+
import { DataGridProps } from "@mui/x-data-grid/internals";
|
|
9
|
+
import { DataGrid } from "@mui/x-data-grid/DataGrid";
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* Data table selected cell params
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { DataTypes, IdType } from "@etsoo/shared";
|
|
2
|
+
import Checkbox from "@mui/material/Checkbox";
|
|
3
|
+
import List, { ListProps } from "@mui/material/List";
|
|
4
|
+
import ListItem, { ListItemProps } from "@mui/material/ListItem";
|
|
5
|
+
import ListItemButton from "@mui/material/ListItemButton";
|
|
6
|
+
import ListItemIcon from "@mui/material/ListItemIcon";
|
|
7
|
+
import ListItemText, { ListItemTextProps } from "@mui/material/ListItemText";
|
|
8
|
+
import React from "react";
|
|
9
|
+
|
|
10
|
+
type ListItemLabel<T extends object> =
|
|
11
|
+
| DataTypes.Keys<T, string | undefined>
|
|
12
|
+
| ((item: T) => string | undefined);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* List multipler component props
|
|
16
|
+
*/
|
|
17
|
+
export type ListMultiplerProps<T extends object> = ListProps & {
|
|
18
|
+
/**
|
|
19
|
+
* List data
|
|
20
|
+
*/
|
|
21
|
+
data: T[];
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Id field name
|
|
25
|
+
*/
|
|
26
|
+
idField: DataTypes.Keys<T, IdType>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Primary label field name or function
|
|
30
|
+
*/
|
|
31
|
+
primaryLabel: ListItemLabel<T>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Secondary label field name or function
|
|
35
|
+
*/
|
|
36
|
+
secondaryLabel?: ListItemLabel<T>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* List item props
|
|
40
|
+
*/
|
|
41
|
+
listItemProps?: ListItemProps;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* List item text props
|
|
45
|
+
*/
|
|
46
|
+
listItemTextProps?: Omit<ListItemTextProps, "primary" | "secondary">;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Input name
|
|
50
|
+
*/
|
|
51
|
+
name?: string;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* On change event
|
|
55
|
+
* @param items The selected items
|
|
56
|
+
* @param ids The selected IDs
|
|
57
|
+
*/
|
|
58
|
+
onCheckItems?: (items: T[], ids: unknown[]) => void;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
function GetListItemLabel<T extends object>(data: T, label?: ListItemLabel<T>) {
|
|
62
|
+
if (label == null) return undefined;
|
|
63
|
+
if (typeof label === "function") {
|
|
64
|
+
return label(data);
|
|
65
|
+
} else {
|
|
66
|
+
return data[label] as string | undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* List multipler component
|
|
72
|
+
* @param props Props
|
|
73
|
+
* @returns Component
|
|
74
|
+
*/
|
|
75
|
+
export function ListMultipler<T extends object>(props: ListMultiplerProps<T>) {
|
|
76
|
+
// Destruct
|
|
77
|
+
const {
|
|
78
|
+
data,
|
|
79
|
+
idField,
|
|
80
|
+
primaryLabel,
|
|
81
|
+
secondaryLabel,
|
|
82
|
+
listItemProps,
|
|
83
|
+
listItemTextProps,
|
|
84
|
+
name,
|
|
85
|
+
onCheckItems,
|
|
86
|
+
...rest
|
|
87
|
+
} = props;
|
|
88
|
+
|
|
89
|
+
// Refs
|
|
90
|
+
const initialized = React.useRef(false);
|
|
91
|
+
React.useEffect(() => {
|
|
92
|
+
initialized.current = true;
|
|
93
|
+
}, []);
|
|
94
|
+
|
|
95
|
+
// State
|
|
96
|
+
const [checked, setChecked] = React.useState<T[]>([]);
|
|
97
|
+
|
|
98
|
+
const ids = React.useMemo(() => {
|
|
99
|
+
const ids = checked.map((u) => u[idField]);
|
|
100
|
+
|
|
101
|
+
if (onCheckItems && initialized.current) {
|
|
102
|
+
onCheckItems(checked, ids);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return ids;
|
|
106
|
+
}, [checked]);
|
|
107
|
+
|
|
108
|
+
function handleToggle(id: T[DataTypes.Keys<T, IdType>]) {
|
|
109
|
+
if (ids.includes(id)) {
|
|
110
|
+
setChecked((prev) => prev.filter((u) => u[idField] !== id));
|
|
111
|
+
} else {
|
|
112
|
+
const item = data.find((u) => u[idField] === id);
|
|
113
|
+
if (item) {
|
|
114
|
+
setChecked((prev) => [...prev, item]);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const inputType = typeof ids[0] === "string" ? "text" : "number";
|
|
120
|
+
|
|
121
|
+
// Layout
|
|
122
|
+
return (
|
|
123
|
+
<List {...rest}>
|
|
124
|
+
{name && (
|
|
125
|
+
<input
|
|
126
|
+
type={inputType}
|
|
127
|
+
style={{ display: "none" }}
|
|
128
|
+
name={name}
|
|
129
|
+
value={ids.join(",")}
|
|
130
|
+
readOnly
|
|
131
|
+
/>
|
|
132
|
+
)}
|
|
133
|
+
{data.map((u) => (
|
|
134
|
+
<ListItem key={`${u[idField]}`} {...listItemProps}>
|
|
135
|
+
<ListItemButton dense onClick={() => handleToggle(u[idField])}>
|
|
136
|
+
<ListItemIcon>
|
|
137
|
+
<Checkbox
|
|
138
|
+
edge="start"
|
|
139
|
+
disableRipple
|
|
140
|
+
checked={ids.includes(u[idField])}
|
|
141
|
+
/>
|
|
142
|
+
</ListItemIcon>
|
|
143
|
+
<ListItemText
|
|
144
|
+
primary={GetListItemLabel(u, primaryLabel)}
|
|
145
|
+
secondary={GetListItemLabel(u, secondaryLabel)}
|
|
146
|
+
{...listItemTextProps}
|
|
147
|
+
/>
|
|
148
|
+
</ListItemButton>
|
|
149
|
+
</ListItem>
|
|
150
|
+
))}
|
|
151
|
+
</List>
|
|
152
|
+
);
|
|
153
|
+
}
|
package/src/MUUtils.ts
CHANGED
package/src/app/IServiceApp.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ApiRefreshTokenDto,
|
|
3
|
+
IApi,
|
|
4
|
+
IApiPayload,
|
|
5
|
+
TokenAuthRQ
|
|
6
|
+
} from "@etsoo/appscript";
|
|
2
7
|
import { ReactAppType } from "./ReactApp";
|
|
3
8
|
import { IServiceUser, ServiceUserToken } from "./IServiceUser";
|
|
4
9
|
import { IActionResult } from "@etsoo/shared";
|
|
@@ -17,6 +22,13 @@ export interface IServiceApp extends ReactAppType {
|
|
|
17
22
|
*/
|
|
18
23
|
readonly coreOrigin: string;
|
|
19
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Get token authorization request data
|
|
27
|
+
* @param api API, if not provided, use the core API
|
|
28
|
+
* @returns Result
|
|
29
|
+
*/
|
|
30
|
+
getTokenAuthRQ(api?: IApi): TokenAuthRQ;
|
|
31
|
+
|
|
20
32
|
/**
|
|
21
33
|
* Load core system UI
|
|
22
34
|
* @param tryLogin Try login or not
|
package/src/app/ServiceApp.ts
CHANGED
|
@@ -6,7 +6,8 @@ import {
|
|
|
6
6
|
BridgeUtils,
|
|
7
7
|
ExternalEndpoint,
|
|
8
8
|
IApi,
|
|
9
|
-
IApiPayload
|
|
9
|
+
IApiPayload,
|
|
10
|
+
TokenAuthRQ
|
|
10
11
|
} from "@etsoo/appscript";
|
|
11
12
|
import { IServiceApp } from "./IServiceApp";
|
|
12
13
|
import { IServiceAppSettings } from "./IServiceAppSettings";
|
|
@@ -68,6 +69,23 @@ export class ServiceApp<
|
|
|
68
69
|
this.keepLogin = true;
|
|
69
70
|
}
|
|
70
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Get token authorization request data
|
|
74
|
+
* @param api API, if not provided, use the core API
|
|
75
|
+
* @returns Result
|
|
76
|
+
*/
|
|
77
|
+
getTokenAuthRQ(api?: IApi): TokenAuthRQ {
|
|
78
|
+
api ??= this.coreApi;
|
|
79
|
+
|
|
80
|
+
const auth = api.getAuthorization();
|
|
81
|
+
|
|
82
|
+
if (auth == null) {
|
|
83
|
+
throw new Error("Authorization is required.");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return { accessToken: auth.token, tokenScheme: auth.scheme };
|
|
87
|
+
}
|
|
88
|
+
|
|
71
89
|
/**
|
|
72
90
|
* Load core system UI
|
|
73
91
|
* @param tryLogin Try login or not
|
package/src/index.ts
CHANGED
|
@@ -79,6 +79,7 @@ export * from "./LinkEx";
|
|
|
79
79
|
export * from "./ListChooser";
|
|
80
80
|
export * from "./ListItemRightIcon";
|
|
81
81
|
export * from "./ListMoreDisplay";
|
|
82
|
+
export * from "./ListMultipler";
|
|
82
83
|
export * from "./LoadingButton";
|
|
83
84
|
export * from "./MaskInput";
|
|
84
85
|
export * from "./MenuButton";
|
package/vite.config.mts
CHANGED