@etsoo/materialui 1.5.29 → 1.5.31
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/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/html/HtmlDiv.d.ts +14 -1
- package/lib/cjs/html/HtmlDiv.js +53 -7
- package/lib/mjs/DataTable.d.ts +2 -2
- package/lib/mjs/DataTable.js +1 -1
- 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/html/HtmlDiv.d.ts +14 -1
- package/lib/mjs/html/HtmlDiv.js +53 -4
- package/package.json +7 -7
- package/src/CultureDataTable.tsx +1 -1
- package/src/DataTable.tsx +7 -4
- package/src/MUUtils.ts +1 -1
- package/src/app/IServiceApp.ts +13 -1
- package/src/app/ServiceApp.ts +19 -1
- package/src/html/HtmlDiv.tsx +76 -6
- package/vite.config.mts +5 -0
- package/src/global.d.ts +0 -5
|
@@ -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
|
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
|
|
@@ -3,7 +3,20 @@ import { HTMLAttributes } from "react";
|
|
|
3
3
|
* Custom HTML element properties
|
|
4
4
|
* 自定义 HTML 元素属性
|
|
5
5
|
*/
|
|
6
|
-
export type HtmlDivProps = HTMLAttributes<HTMLElement
|
|
6
|
+
export type HtmlDivProps = HTMLAttributes<HTMLElement> & {
|
|
7
|
+
/**
|
|
8
|
+
* Display style
|
|
9
|
+
* 显示样式
|
|
10
|
+
*/
|
|
11
|
+
displayStyle?: string;
|
|
12
|
+
};
|
|
13
|
+
declare global {
|
|
14
|
+
namespace JSX {
|
|
15
|
+
interface IntrinsicElements {
|
|
16
|
+
"html-div": React.HTMLAttributes<HTMLElement>;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
7
20
|
/**
|
|
8
21
|
* Custom HTML element that sanitizes and displays HTML content
|
|
9
22
|
* 自定义 HTML 元素,用于清理和显示 HTML 内容
|
package/lib/cjs/html/HtmlDiv.js
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.HtmlDiv = HtmlDiv;
|
|
7
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
5
|
const shared_1 = require("@etsoo/shared");
|
|
9
|
-
const dompurify_1 = __importDefault(require("dompurify"));
|
|
10
6
|
class HtmlDivElement extends HTMLElement {
|
|
7
|
+
static get observedAttributes() {
|
|
8
|
+
return ["displaystyle"];
|
|
9
|
+
}
|
|
10
|
+
wrapper = null;
|
|
11
|
+
observer = null;
|
|
12
|
+
_displayStyle = undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Display style
|
|
15
|
+
*/
|
|
16
|
+
get displayStyle() {
|
|
17
|
+
return this._displayStyle;
|
|
18
|
+
}
|
|
19
|
+
set displayStyle(style) {
|
|
20
|
+
this._displayStyle = style;
|
|
21
|
+
if (this.wrapper && style != null) {
|
|
22
|
+
this.wrapper.style.cssText = style;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
11
25
|
constructor() {
|
|
12
26
|
super();
|
|
13
27
|
}
|
|
@@ -16,17 +30,49 @@ class HtmlDivElement extends HTMLElement {
|
|
|
16
30
|
const shadow = this.attachShadow({ mode: "open" });
|
|
17
31
|
// Create a wrapper element to hold the sanitized HTML content
|
|
18
32
|
const wrapper = document.createElement("div");
|
|
33
|
+
wrapper.style.cssText = this.displayStyle ?? "";
|
|
34
|
+
shadow.appendChild(wrapper);
|
|
35
|
+
this.wrapper = wrapper;
|
|
36
|
+
this.setContent();
|
|
37
|
+
let miliseconds = Date.now();
|
|
38
|
+
this.observer = new MutationObserver(() => {
|
|
39
|
+
const m = Date.now();
|
|
40
|
+
if (m - miliseconds < 50)
|
|
41
|
+
return; // Ignore fast changes
|
|
42
|
+
miliseconds = m;
|
|
43
|
+
this.setContent();
|
|
44
|
+
});
|
|
45
|
+
this.observer.observe(this, {
|
|
46
|
+
childList: true,
|
|
47
|
+
subtree: true,
|
|
48
|
+
characterData: true
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
disconnectedCallback() {
|
|
52
|
+
if (this.observer) {
|
|
53
|
+
this.observer.disconnect();
|
|
54
|
+
this.observer = null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
attributeChangedCallback(name, _oldValue, newValue) {
|
|
58
|
+
if (name === "displaystyle" && typeof newValue === "string") {
|
|
59
|
+
this.displayStyle = newValue;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
setContent() {
|
|
63
|
+
const wrapper = this.wrapper;
|
|
64
|
+
if (!wrapper)
|
|
65
|
+
return;
|
|
19
66
|
const html = this.innerHTML;
|
|
20
67
|
if (shared_1.Utils.hasHtmlEntity(html) &&
|
|
21
68
|
!shared_1.Utils.hasHtmlTag(html) &&
|
|
22
69
|
this.textContent) {
|
|
23
|
-
wrapper.innerHTML =
|
|
70
|
+
wrapper.innerHTML = this.textContent;
|
|
24
71
|
}
|
|
25
72
|
else {
|
|
26
|
-
wrapper.innerHTML =
|
|
73
|
+
wrapper.innerHTML = html;
|
|
27
74
|
}
|
|
28
75
|
this.textContent = null; // Clear the textContent to avoid duplication
|
|
29
|
-
shadow.appendChild(wrapper);
|
|
30
76
|
}
|
|
31
77
|
}
|
|
32
78
|
// Define the custom element only once
|
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
|
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
|
|
@@ -3,7 +3,20 @@ import { HTMLAttributes } from "react";
|
|
|
3
3
|
* Custom HTML element properties
|
|
4
4
|
* 自定义 HTML 元素属性
|
|
5
5
|
*/
|
|
6
|
-
export type HtmlDivProps = HTMLAttributes<HTMLElement
|
|
6
|
+
export type HtmlDivProps = HTMLAttributes<HTMLElement> & {
|
|
7
|
+
/**
|
|
8
|
+
* Display style
|
|
9
|
+
* 显示样式
|
|
10
|
+
*/
|
|
11
|
+
displayStyle?: string;
|
|
12
|
+
};
|
|
13
|
+
declare global {
|
|
14
|
+
namespace JSX {
|
|
15
|
+
interface IntrinsicElements {
|
|
16
|
+
"html-div": React.HTMLAttributes<HTMLElement>;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
7
20
|
/**
|
|
8
21
|
* Custom HTML element that sanitizes and displays HTML content
|
|
9
22
|
* 自定义 HTML 元素,用于清理和显示 HTML 内容
|
package/lib/mjs/html/HtmlDiv.js
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Utils } from "@etsoo/shared";
|
|
3
|
-
import DOMPurify from "dompurify";
|
|
4
3
|
class HtmlDivElement extends HTMLElement {
|
|
4
|
+
static get observedAttributes() {
|
|
5
|
+
return ["displaystyle"];
|
|
6
|
+
}
|
|
7
|
+
wrapper = null;
|
|
8
|
+
observer = null;
|
|
9
|
+
_displayStyle = undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Display style
|
|
12
|
+
*/
|
|
13
|
+
get displayStyle() {
|
|
14
|
+
return this._displayStyle;
|
|
15
|
+
}
|
|
16
|
+
set displayStyle(style) {
|
|
17
|
+
this._displayStyle = style;
|
|
18
|
+
if (this.wrapper && style != null) {
|
|
19
|
+
this.wrapper.style.cssText = style;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
5
22
|
constructor() {
|
|
6
23
|
super();
|
|
7
24
|
}
|
|
@@ -10,17 +27,49 @@ class HtmlDivElement extends HTMLElement {
|
|
|
10
27
|
const shadow = this.attachShadow({ mode: "open" });
|
|
11
28
|
// Create a wrapper element to hold the sanitized HTML content
|
|
12
29
|
const wrapper = document.createElement("div");
|
|
30
|
+
wrapper.style.cssText = this.displayStyle ?? "";
|
|
31
|
+
shadow.appendChild(wrapper);
|
|
32
|
+
this.wrapper = wrapper;
|
|
33
|
+
this.setContent();
|
|
34
|
+
let miliseconds = Date.now();
|
|
35
|
+
this.observer = new MutationObserver(() => {
|
|
36
|
+
const m = Date.now();
|
|
37
|
+
if (m - miliseconds < 50)
|
|
38
|
+
return; // Ignore fast changes
|
|
39
|
+
miliseconds = m;
|
|
40
|
+
this.setContent();
|
|
41
|
+
});
|
|
42
|
+
this.observer.observe(this, {
|
|
43
|
+
childList: true,
|
|
44
|
+
subtree: true,
|
|
45
|
+
characterData: true
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
disconnectedCallback() {
|
|
49
|
+
if (this.observer) {
|
|
50
|
+
this.observer.disconnect();
|
|
51
|
+
this.observer = null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
attributeChangedCallback(name, _oldValue, newValue) {
|
|
55
|
+
if (name === "displaystyle" && typeof newValue === "string") {
|
|
56
|
+
this.displayStyle = newValue;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
setContent() {
|
|
60
|
+
const wrapper = this.wrapper;
|
|
61
|
+
if (!wrapper)
|
|
62
|
+
return;
|
|
13
63
|
const html = this.innerHTML;
|
|
14
64
|
if (Utils.hasHtmlEntity(html) &&
|
|
15
65
|
!Utils.hasHtmlTag(html) &&
|
|
16
66
|
this.textContent) {
|
|
17
|
-
wrapper.innerHTML =
|
|
67
|
+
wrapper.innerHTML = this.textContent;
|
|
18
68
|
}
|
|
19
69
|
else {
|
|
20
|
-
wrapper.innerHTML =
|
|
70
|
+
wrapper.innerHTML = html;
|
|
21
71
|
}
|
|
22
72
|
this.textContent = null; // Clear the textContent to avoid duplication
|
|
23
|
-
shadow.appendChild(wrapper);
|
|
24
73
|
}
|
|
25
74
|
}
|
|
26
75
|
// Define the custom element only once
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/materialui",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.31",
|
|
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.25",
|
|
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.0",
|
|
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
|
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/html/HtmlDiv.tsx
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
import { Utils } from "@etsoo/shared";
|
|
2
|
-
import DOMPurify from "dompurify";
|
|
3
2
|
import { HTMLAttributes } from "react";
|
|
4
3
|
|
|
5
4
|
class HtmlDivElement extends HTMLElement {
|
|
5
|
+
static get observedAttributes() {
|
|
6
|
+
return ["displaystyle"];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
private wrapper: HTMLDivElement | null = null;
|
|
10
|
+
private observer: MutationObserver | null = null;
|
|
11
|
+
|
|
12
|
+
private _displayStyle?: string = undefined;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Display style
|
|
16
|
+
*/
|
|
17
|
+
get displayStyle() {
|
|
18
|
+
return this._displayStyle;
|
|
19
|
+
}
|
|
20
|
+
set displayStyle(style: string | undefined) {
|
|
21
|
+
this._displayStyle = style;
|
|
22
|
+
if (this.wrapper && style != null) {
|
|
23
|
+
this.wrapper.style.cssText = style;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
6
27
|
constructor() {
|
|
7
28
|
super();
|
|
8
29
|
}
|
|
@@ -13,20 +34,55 @@ class HtmlDivElement extends HTMLElement {
|
|
|
13
34
|
|
|
14
35
|
// Create a wrapper element to hold the sanitized HTML content
|
|
15
36
|
const wrapper = document.createElement("div");
|
|
37
|
+
wrapper.style.cssText = this.displayStyle ?? "";
|
|
38
|
+
shadow.appendChild(wrapper);
|
|
39
|
+
|
|
40
|
+
this.wrapper = wrapper;
|
|
41
|
+
this.setContent();
|
|
42
|
+
|
|
43
|
+
let miliseconds = Date.now();
|
|
44
|
+
this.observer = new MutationObserver(() => {
|
|
45
|
+
const m = Date.now();
|
|
46
|
+
if (m - miliseconds < 50) return; // Ignore fast changes
|
|
47
|
+
miliseconds = m;
|
|
48
|
+
this.setContent();
|
|
49
|
+
});
|
|
50
|
+
this.observer.observe(this, {
|
|
51
|
+
childList: true,
|
|
52
|
+
subtree: true,
|
|
53
|
+
characterData: true
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
disconnectedCallback() {
|
|
58
|
+
if (this.observer) {
|
|
59
|
+
this.observer.disconnect();
|
|
60
|
+
this.observer = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
attributeChangedCallback(name: string, _oldValue: any, newValue: any) {
|
|
65
|
+
if (name === "displaystyle" && typeof newValue === "string") {
|
|
66
|
+
this.displayStyle = newValue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
setContent() {
|
|
71
|
+
const wrapper = this.wrapper;
|
|
72
|
+
if (!wrapper) return;
|
|
73
|
+
|
|
16
74
|
const html = this.innerHTML;
|
|
17
75
|
if (
|
|
18
76
|
Utils.hasHtmlEntity(html) &&
|
|
19
77
|
!Utils.hasHtmlTag(html) &&
|
|
20
78
|
this.textContent
|
|
21
79
|
) {
|
|
22
|
-
wrapper.innerHTML =
|
|
80
|
+
wrapper.innerHTML = this.textContent;
|
|
23
81
|
} else {
|
|
24
|
-
wrapper.innerHTML =
|
|
82
|
+
wrapper.innerHTML = html;
|
|
25
83
|
}
|
|
26
84
|
|
|
27
85
|
this.textContent = null; // Clear the textContent to avoid duplication
|
|
28
|
-
|
|
29
|
-
shadow.appendChild(wrapper);
|
|
30
86
|
}
|
|
31
87
|
}
|
|
32
88
|
|
|
@@ -39,7 +95,21 @@ if (!customElements.get("html-div")) {
|
|
|
39
95
|
* Custom HTML element properties
|
|
40
96
|
* 自定义 HTML 元素属性
|
|
41
97
|
*/
|
|
42
|
-
export type HtmlDivProps = HTMLAttributes<HTMLElement
|
|
98
|
+
export type HtmlDivProps = HTMLAttributes<HTMLElement> & {
|
|
99
|
+
/**
|
|
100
|
+
* Display style
|
|
101
|
+
* 显示样式
|
|
102
|
+
*/
|
|
103
|
+
displayStyle?: string;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
declare global {
|
|
107
|
+
namespace JSX {
|
|
108
|
+
interface IntrinsicElements {
|
|
109
|
+
"html-div": React.HTMLAttributes<HTMLElement>;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
43
113
|
|
|
44
114
|
/**
|
|
45
115
|
* Custom HTML element that sanitizes and displays HTML content
|
package/vite.config.mts
CHANGED