@etsoo/materialui 1.4.73 → 1.4.75

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.
Files changed (110) hide show
  1. package/__tests__/ResponsePage.tsx +34 -31
  2. package/lib/cjs/AddresSelector.js +4 -2
  3. package/lib/cjs/AuditDisplay.js +11 -11
  4. package/lib/cjs/BridgeCloseButton.js +3 -1
  5. package/lib/cjs/ComboBox.js +3 -1
  6. package/lib/cjs/ComboBoxMultiple.js +3 -1
  7. package/lib/cjs/ComboBoxPro.js +4 -2
  8. package/lib/cjs/CultureDataTable.js +3 -1
  9. package/lib/cjs/DataSteps.js +3 -6
  10. package/lib/cjs/DataTable.js +3 -1
  11. package/lib/cjs/InputField.d.ts +3 -3
  12. package/lib/cjs/InputTipField.js +15 -8
  13. package/lib/cjs/ListMoreDisplay.js +3 -1
  14. package/lib/cjs/OptionBool.js +3 -1
  15. package/lib/cjs/QuickList.js +4 -2
  16. package/lib/cjs/SelectBool.js +4 -2
  17. package/lib/cjs/ShowDataComparison.js +2 -5
  18. package/lib/cjs/SwitchAnt.js +3 -1
  19. package/lib/cjs/TagList.js +3 -1
  20. package/lib/cjs/TagListPro.js +4 -2
  21. package/lib/cjs/TextFieldEx.d.ts +3 -3
  22. package/lib/cjs/TextFieldEx.js +3 -1
  23. package/lib/cjs/Tiplist.js +5 -3
  24. package/lib/cjs/TiplistPro.js +3 -1
  25. package/lib/cjs/UserAvatar.js +3 -1
  26. package/lib/cjs/app/CommonApp.d.ts +1 -2
  27. package/lib/cjs/app/IServiceApp.d.ts +1 -6
  28. package/lib/cjs/app/IServiceApp.js +0 -9
  29. package/lib/cjs/app/ReactApp.d.ts +18 -74
  30. package/lib/cjs/app/ReactApp.js +40 -82
  31. package/lib/cjs/app/ServiceApp.d.ts +1 -2
  32. package/lib/cjs/custom/CustomFieldWindow.js +3 -6
  33. package/lib/cjs/index.d.ts +0 -1
  34. package/lib/cjs/index.js +0 -1
  35. package/lib/cjs/pages/CommonPage.js +3 -1
  36. package/lib/cjs/pages/LeftDrawer.js +4 -2
  37. package/lib/cjs/pages/ViewPage.js +12 -12
  38. package/lib/mjs/AddresSelector.js +4 -2
  39. package/lib/mjs/AuditDisplay.js +11 -11
  40. package/lib/mjs/BridgeCloseButton.js +4 -2
  41. package/lib/mjs/ComboBox.js +4 -2
  42. package/lib/mjs/ComboBoxMultiple.js +4 -2
  43. package/lib/mjs/ComboBoxPro.js +4 -2
  44. package/lib/mjs/CultureDataTable.js +4 -2
  45. package/lib/mjs/DataSteps.js +3 -6
  46. package/lib/mjs/DataTable.js +4 -2
  47. package/lib/mjs/InputField.d.ts +3 -3
  48. package/lib/mjs/InputTipField.js +15 -8
  49. package/lib/mjs/ListMoreDisplay.js +4 -2
  50. package/lib/mjs/OptionBool.js +4 -2
  51. package/lib/mjs/QuickList.js +4 -2
  52. package/lib/mjs/SelectBool.js +4 -2
  53. package/lib/mjs/ShowDataComparison.js +3 -6
  54. package/lib/mjs/SwitchAnt.js +4 -2
  55. package/lib/mjs/TagList.js +4 -2
  56. package/lib/mjs/TagListPro.js +4 -2
  57. package/lib/mjs/TextFieldEx.d.ts +3 -3
  58. package/lib/mjs/TextFieldEx.js +4 -2
  59. package/lib/mjs/Tiplist.js +5 -3
  60. package/lib/mjs/TiplistPro.js +4 -2
  61. package/lib/mjs/UserAvatar.js +4 -2
  62. package/lib/mjs/app/CommonApp.d.ts +1 -2
  63. package/lib/mjs/app/IServiceApp.d.ts +1 -6
  64. package/lib/mjs/app/IServiceApp.js +1 -5
  65. package/lib/mjs/app/ReactApp.d.ts +18 -74
  66. package/lib/mjs/app/ReactApp.js +36 -83
  67. package/lib/mjs/app/ServiceApp.d.ts +1 -2
  68. package/lib/mjs/custom/CustomFieldWindow.js +3 -6
  69. package/lib/mjs/index.d.ts +0 -1
  70. package/lib/mjs/index.js +0 -1
  71. package/lib/mjs/pages/CommonPage.js +4 -2
  72. package/lib/mjs/pages/LeftDrawer.js +5 -3
  73. package/lib/mjs/pages/ViewPage.js +13 -13
  74. package/package.json +4 -4
  75. package/src/AddresSelector.tsx +5 -2
  76. package/src/AuditDisplay.tsx +14 -12
  77. package/src/BridgeCloseButton.tsx +5 -2
  78. package/src/ComboBox.tsx +5 -2
  79. package/src/ComboBoxMultiple.tsx +5 -2
  80. package/src/ComboBoxPro.tsx +5 -2
  81. package/src/CultureDataTable.tsx +6 -3
  82. package/src/DataSteps.tsx +3 -6
  83. package/src/DataTable.tsx +5 -2
  84. package/src/InputTipField.tsx +26 -17
  85. package/src/ListMoreDisplay.tsx +5 -3
  86. package/src/OptionBool.tsx +5 -3
  87. package/src/QuickList.tsx +5 -2
  88. package/src/SelectBool.tsx +5 -3
  89. package/src/ShowDataComparison.tsx +3 -6
  90. package/src/SwitchAnt.tsx +5 -2
  91. package/src/TagList.tsx +5 -2
  92. package/src/TagListPro.tsx +5 -2
  93. package/src/TextFieldEx.tsx +5 -3
  94. package/src/Tiplist.tsx +7 -4
  95. package/src/TiplistPro.tsx +5 -2
  96. package/src/UserAvatar.tsx +5 -3
  97. package/src/app/CommonApp.ts +2 -3
  98. package/src/app/IServiceApp.ts +1 -8
  99. package/src/app/ReactApp.ts +52 -151
  100. package/src/app/ServiceApp.ts +1 -3
  101. package/src/custom/CustomFieldWindow.tsx +3 -6
  102. package/src/index.ts +0 -1
  103. package/src/pages/CommonPage.tsx +5 -4
  104. package/src/pages/LeftDrawer.tsx +6 -3
  105. package/src/pages/ViewPage.tsx +17 -12
  106. package/lib/cjs/app/IServicePage.d.ts +0 -6
  107. package/lib/cjs/app/IServicePage.js +0 -2
  108. package/lib/mjs/app/IServicePage.d.ts +0 -6
  109. package/lib/mjs/app/IServicePage.js +0 -1
  110. package/src/app/IServicePage.ts +0 -6
@@ -2,41 +2,26 @@ import { AppTryLoginParams, CoreApp, FormatResultCustomCallback, IApp, IAppSetti
2
2
  import { INotifier, NotificationReturn } from "@etsoo/notificationbase";
3
3
  import { DataTypes, IActionResult } from "@etsoo/shared";
4
4
  import React from "react";
5
- import { CultureAction, CultureState, INotificationReact, InputDialogProps, IPageData, IStateProps, NotificationReactCallProps, PageAction, PageState, UserAction, UserState } from "@etsoo/react";
5
+ import { CultureAction, CultureState, INotificationReact, InputDialogProps, IStateProps, NotificationReactCallProps, UserAction, UserState } from "@etsoo/react";
6
6
  import { NavigateFunction, NavigateOptions } from "react-router";
7
7
  /**
8
8
  * React Application Type
9
9
  */
10
10
  export type ReactAppType = IApp & IReactAppBase;
11
- /**
12
- * React application data
13
- */
14
- export type ReactAppData<A extends ReactAppType> = {
15
- /**
16
- * Current application
17
- */
18
- app: A;
19
- };
20
11
  /**
21
12
  * React application context
22
13
  */
23
- export declare const ReactAppContext: React.Context<ReactAppData<ReactAppType> | null>;
14
+ export declare const ReactAppContext: React.Context<ReactAppType | null>;
24
15
  /**
25
- * Global application
16
+ * Get React application context hook
17
+ * @returns React application
26
18
  */
27
- export declare let globalApp: ReactAppType | null;
19
+ export declare function useAppContext(): ReactAppType | null;
28
20
  /**
29
- * React app state detector
30
- * Case 1: undefined, when refresh the whole page
31
- * Case 2: false, unauthorized
32
- * Case 3: true, authorized or considered as authorized (maynot, like token expiry)
33
- * Case 4: property or properties changed
34
- * @param props Props
35
- * @returns Component
21
+ * Get React application context hook
22
+ * @returns React application
36
23
  */
37
- export declare function ReactAppStateDetector(props: IStateProps): React.FunctionComponentElement<{
38
- children?: React.ReactNode | undefined;
39
- }>;
24
+ export declare function useRequiredAppContext(): IApp & IReactAppBase;
40
25
  /**
41
26
  * React implemented base
42
27
  */
@@ -45,10 +30,6 @@ export interface IReactAppBase {
45
30
  * Override Notifier as React specific
46
31
  */
47
32
  readonly notifier: INotifier<React.ReactNode, NotificationReactCallProps>;
48
- /**
49
- * User state
50
- */
51
- readonly userState: UserState<any>;
52
33
  /**
53
34
  * Is screen size down 'sm'
54
35
  */
@@ -68,46 +49,30 @@ export interface IReactAppBase {
68
49
  * @returns Props
69
50
  */
70
51
  getMoneyFormatProps(currency?: string): object;
71
- /**
72
- * Set page data
73
- * @param data Page data
74
- */
75
- setPageData(data: IPageData): void;
76
- /**
77
- * Set page title and subtitle
78
- * @param title Page title
79
- * @param subtitle Page subtitle
80
- */
81
- setPageTitle(title: string, subtitle?: string): void;
82
- /**
83
- * Set page title and data
84
- * @param title Page title
85
- */
86
- setPageTitle(title: string): void;
87
52
  /**
88
53
  * Show input dialog
89
54
  * @param props Props
90
55
  */
91
56
  showInputDialog({ title, message, callback, ...rest }: InputDialogProps): INotificationReact;
57
+ /**
58
+ * State detector component
59
+ * @param props Props
60
+ */
61
+ stateDetector(props: IStateProps): React.ReactNode;
92
62
  }
93
63
  /**
94
64
  * Core application interface
95
65
  */
96
- export interface IReactApp<S extends IAppSettings, D extends IUser, P extends IPageData> extends ICoreApp<D, S, React.ReactNode, NotificationReactCallProps>, IReactAppBase {
66
+ export interface IReactApp<S extends IAppSettings, D extends IUser> extends ICoreApp<D, S, React.ReactNode, NotificationReactCallProps>, Omit<IReactAppBase, "userState"> {
97
67
  /**
98
68
  * User state
99
69
  */
100
70
  readonly userState: UserState<D>;
101
- /**
102
- * Set page data
103
- * @param data Page data
104
- */
105
- setPageData(data: P): void;
106
71
  }
107
72
  /**
108
73
  * React application
109
74
  */
110
- export declare class ReactApp<S extends IAppSettings, D extends IUser, P extends IPageData> extends CoreApp<D, S, React.ReactNode, NotificationReactCallProps> implements IReactApp<S, D, P> {
75
+ export declare class ReactApp<S extends IAppSettings, D extends IUser> extends CoreApp<D, S, React.ReactNode, NotificationReactCallProps> implements IReactApp<S, D> {
111
76
  private static _notifierProvider;
112
77
  /**
113
78
  * Get notifier provider
@@ -118,10 +83,6 @@ export declare class ReactApp<S extends IAppSettings, D extends IUser, P extends
118
83
  * Culture state
119
84
  */
120
85
  readonly cultureState: CultureState;
121
- /**
122
- * Page state
123
- */
124
- readonly pageState: PageState<P>;
125
86
  /**
126
87
  * User state
127
88
  */
@@ -138,10 +99,6 @@ export declare class ReactApp<S extends IAppSettings, D extends IUser, P extends
138
99
  * Navigate function
139
100
  */
140
101
  navigateFunction?: NavigateFunction;
141
- /**
142
- * Page state dispatch
143
- */
144
- pageStateDispatch?: React.Dispatch<PageAction<P>>;
145
102
  /**
146
103
  * User state dispatch
147
104
  */
@@ -205,33 +162,20 @@ export declare class ReactApp<S extends IAppSettings, D extends IUser, P extends
205
162
  * @returns Result
206
163
  */
207
164
  protected tryLoginIgnoreResult(result: IActionResult): boolean;
208
- /**
209
- * Set page data
210
- * @param data Page data
211
- */
212
- setPageData(data: P): void;
213
- /**
214
- * Set page title and subtitle
215
- * @param title Page title
216
- * @param subtitle Page subtitle
217
- */
218
- setPageTitle(title: string, subtitle?: string): void;
219
165
  /**
220
166
  * Navigate to Url or delta
221
167
  * @param url Url or delta
222
168
  * @param options Options
223
169
  */
224
170
  navigate<T extends number | string | URL>(to: T, options?: T extends number ? never : NavigateOptions): void;
225
- /**
226
- * Set page title and data
227
- * @param key Page title resource key
228
- */
229
- setPageKey(key: string): void;
230
171
  /**
231
172
  * Show input dialog
232
173
  * @param props Props
233
174
  */
234
175
  showInputDialog({ title, message, callback, ...rest }: InputDialogProps): INotificationReact;
176
+ stateDetector(props: IStateProps): React.FunctionComponentElement<{
177
+ children?: React.ReactNode | undefined;
178
+ }>;
235
179
  /**
236
180
  * User login extended
237
181
  * @param user New user
@@ -5,51 +5,24 @@ import React from "react";
5
5
  import { NotifierMU } from "../NotifierMU";
6
6
  import { ProgressCount } from "../ProgressCount";
7
7
  import { Labels } from "./Labels";
8
- import { CultureState, PageActionType, PageState, UserActionType, UserState } from "@etsoo/react";
8
+ import { CultureState, UserActionType, useRequiredContext, UserState } from "@etsoo/react";
9
9
  /**
10
10
  * React application context
11
11
  */
12
12
  export const ReactAppContext = React.createContext(null);
13
13
  /**
14
- * Global application
14
+ * Get React application context hook
15
+ * @returns React application
15
16
  */
16
- export let globalApp;
17
+ export function useAppContext() {
18
+ return React.useContext(ReactAppContext);
19
+ }
17
20
  /**
18
- * React app state detector
19
- * Case 1: undefined, when refresh the whole page
20
- * Case 2: false, unauthorized
21
- * Case 3: true, authorized or considered as authorized (maynot, like token expiry)
22
- * Case 4: property or properties changed
23
- * @param props Props
24
- * @returns Component
21
+ * Get React application context hook
22
+ * @returns React application
25
23
  */
26
- export function ReactAppStateDetector(props) {
27
- // Destruct
28
- const { targetFields, update } = props;
29
- // Context
30
- const { state } = globalApp == null
31
- ? {}
32
- : React.useContext(globalApp.userState.context);
33
- // Ready
34
- React.useEffect(() => {
35
- // Match fields
36
- const changedFields = state.lastChangedFields;
37
- let matchedFields;
38
- if (targetFields == null || changedFields == null) {
39
- matchedFields = changedFields;
40
- }
41
- else {
42
- matchedFields = [];
43
- targetFields.forEach((targetField) => {
44
- if (changedFields.includes(targetField))
45
- matchedFields?.push(targetField);
46
- });
47
- }
48
- // Callback
49
- update(state.authorized, matchedFields);
50
- }, [state]);
51
- // return
52
- return React.createElement(React.Fragment);
24
+ export function useRequiredAppContext() {
25
+ return useRequiredContext(ReactAppContext);
53
26
  }
54
27
  /**
55
28
  * React application
@@ -71,10 +44,6 @@ export class ReactApp extends CoreApp {
71
44
  * Culture state
72
45
  */
73
46
  cultureState;
74
- /**
75
- * Page state
76
- */
77
- pageState;
78
47
  /**
79
48
  * User state
80
49
  */
@@ -91,10 +60,6 @@ export class ReactApp extends CoreApp {
91
60
  * Navigate function
92
61
  */
93
62
  navigateFunction;
94
- /**
95
- * Page state dispatch
96
- */
97
- pageStateDispatch;
98
63
  /**
99
64
  * User state dispatch
100
65
  */
@@ -113,8 +78,6 @@ export class ReactApp extends CoreApp {
113
78
  });
114
79
  }
115
80
  this.cultureState = new CultureState(settings.currentCulture);
116
- this.pageState = new PageState();
117
- globalApp = this;
118
81
  }
119
82
  /**
120
83
  * Override alert action result
@@ -280,35 +243,6 @@ export class ReactApp extends CoreApp {
280
243
  else
281
244
  return false;
282
245
  }
283
- /**
284
- * Set page data
285
- * @param data Page data
286
- */
287
- setPageData(data) {
288
- // Dispatch the change
289
- if (this.pageStateDispatch != null) {
290
- this.pageStateDispatch({
291
- type: PageActionType.Data,
292
- data
293
- });
294
- }
295
- }
296
- /**
297
- * Set page title and subtitle
298
- * @param title Page title
299
- * @param subtitle Page subtitle
300
- */
301
- setPageTitle(title, subtitle) {
302
- // Data
303
- const data = { title, subtitle };
304
- // Dispatch the change
305
- if (this.pageStateDispatch != null) {
306
- this.pageStateDispatch({
307
- type: PageActionType.Title,
308
- data
309
- });
310
- }
311
- }
312
246
  /**
313
247
  * Navigate to Url or delta
314
248
  * @param url Url or delta
@@ -322,13 +256,6 @@ export class ReactApp extends CoreApp {
322
256
  else
323
257
  this.navigateFunction(to, options);
324
258
  }
325
- /**
326
- * Set page title and data
327
- * @param key Page title resource key
328
- */
329
- setPageKey(key) {
330
- this.setPageTitle(this.get(key) ?? "");
331
- }
332
259
  /**
333
260
  * Show input dialog
334
261
  * @param props Props
@@ -336,6 +263,32 @@ export class ReactApp extends CoreApp {
336
263
  showInputDialog({ title, message, callback, ...rest }) {
337
264
  return this.notifier.prompt(message, callback, title, rest);
338
265
  }
266
+ stateDetector(props) {
267
+ // Destruct
268
+ const { targetFields, update } = props;
269
+ // Context
270
+ const { state } = React.useContext(this.userState.context);
271
+ // Ready
272
+ React.useEffect(() => {
273
+ // Match fields
274
+ const changedFields = state.lastChangedFields;
275
+ let matchedFields;
276
+ if (targetFields == null || changedFields == null) {
277
+ matchedFields = changedFields;
278
+ }
279
+ else {
280
+ matchedFields = [];
281
+ targetFields.forEach((targetField) => {
282
+ if (changedFields.includes(targetField))
283
+ matchedFields?.push(targetField);
284
+ });
285
+ }
286
+ // Callback
287
+ update(state.authorized, matchedFields);
288
+ }, [state]);
289
+ // return
290
+ return React.createElement(React.Fragment);
291
+ }
339
292
  /**
340
293
  * User login extended
341
294
  * @param user New user
@@ -1,7 +1,6 @@
1
1
  import { ApiRefreshTokenDto, AppLoginParams, AppTryLoginParams, ExternalEndpoint, IApi, IApiPayload } from "@etsoo/appscript";
2
2
  import { IServiceApp } from "./IServiceApp";
3
3
  import { IServiceAppSettings } from "./IServiceAppSettings";
4
- import { IServicePageData } from "./IServicePage";
5
4
  import { IServiceUser, ServiceUserToken } from "./IServiceUser";
6
5
  import { ReactApp } from "./ReactApp";
7
6
  import { IActionResult } from "@etsoo/shared";
@@ -11,7 +10,7 @@ import { IActionResult } from "@etsoo/shared";
11
10
  * Use the acess token to the service api, get a service access token
12
11
  * Use the new acess token and refresh token to login
13
12
  */
14
- export declare class ServiceApp<U extends IServiceUser = IServiceUser, P extends IServicePageData = IServicePageData, S extends IServiceAppSettings = IServiceAppSettings> extends ReactApp<S, U, P> implements IServiceApp {
13
+ export declare class ServiceApp<U extends IServiceUser = IServiceUser, S extends IServiceAppSettings = IServiceAppSettings> extends ReactApp<S, U> implements IServiceApp {
15
14
  /**
16
15
  * Core endpoint
17
16
  */
@@ -2,9 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Utils } from "@etsoo/shared";
3
3
  import { Grid2, Stack } from "@mui/material";
4
4
  import React from "react";
5
- import { globalApp } from "../app/ReactApp";
6
5
  import { MUGlobal } from "../MUGlobal";
7
6
  import { CustomFieldUtils } from "./CustomFieldUtils";
7
+ import { useRequiredAppContext } from "../app/ReactApp";
8
8
  function calculateKeys(data) {
9
9
  let count = 0;
10
10
  for (const key in data) {
@@ -40,11 +40,8 @@ function parseJsonData(jsonData) {
40
40
  * @returns Component
41
41
  */
42
42
  export function CustomFieldWindow(props) {
43
- // Validate app
44
- const app = globalApp;
45
- if (app == null) {
46
- throw new Error("No globalApp");
47
- }
43
+ // Global app
44
+ const app = useRequiredAppContext();
48
45
  const { children, label = app.get("jsonData"), gridProps, jsonData, inputName = "jsonData", inputRef, onUpdate } = props;
49
46
  const spacing = MUGlobal.half(MUGlobal.pagePaddings);
50
47
  const [count, setCount] = React.useState(0);
@@ -1,7 +1,6 @@
1
1
  export * from "./app/CommonApp";
2
2
  export * from "./app/IServiceApp";
3
3
  export * from "./app/IServiceAppSettings";
4
- export * from "./app/IServicePage";
5
4
  export * from "./app/IServiceUser";
6
5
  export * from "./app/ISmartERPUser";
7
6
  export * from "./app/Labels";
package/lib/mjs/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  export * from "./app/CommonApp";
2
2
  export * from "./app/IServiceApp";
3
3
  export * from "./app/IServiceAppSettings";
4
- export * from "./app/IServicePage";
5
4
  export * from "./app/IServiceUser";
6
5
  export * from "./app/ISmartERPUser";
7
6
  export * from "./app/Labels";
@@ -8,12 +8,14 @@ import { Container, Fab, useTheme } from "@mui/material";
8
8
  import RefreshIcon from "@mui/icons-material/Refresh";
9
9
  import { BackButton } from "../BackButton";
10
10
  import { Labels } from "../app/Labels";
11
- import { ReactAppStateDetector } from "../app/ReactApp";
11
+ import { useAppContext } from "../app/ReactApp";
12
12
  /**
13
13
  * Common page
14
14
  * @param props Props
15
15
  */
16
16
  export function CommonPage(props) {
17
+ // Global app
18
+ const app = useAppContext();
17
19
  // Destruct
18
20
  const { children, disableGutters = true, fabTop, fabButtons, fabColumnDirection, fabPanel, fabPaddingAdjust = 1.5, fabSize = "small", maxWidth = false, moreActions, onRefresh, onUpdate, onUpdateAll, paddings = MUGlobal.pagePaddings, scrollContainer, supportBack = false, targetFields, sx = {}, ...rest } = props;
19
21
  // Fab padding
@@ -51,7 +53,7 @@ export function CommonPage(props) {
51
53
  }
52
54
  }, [update]);
53
55
  // Return the UI
54
- return (_jsxs(React.Fragment, { children: [update && (_jsx(ReactAppStateDetector, { targetFields: targetFields, update: update })), _jsxs(Container, { disableGutters: disableGutters, maxWidth: maxWidth, sx: sx, id: "page-container", ...rest, children: [_jsxs(FabBox, { sx: {
56
+ return (_jsxs(React.Fragment, { children: [update && app?.stateDetector({ targetFields, update }), _jsxs(Container, { disableGutters: disableGutters, maxWidth: maxWidth, sx: sx, id: "page-container", ...rest, children: [_jsxs(FabBox, { sx: {
55
57
  zIndex: 1,
56
58
  ...(typeof fabTop === "function"
57
59
  ? fabTop(theme, fabPadding)
@@ -3,10 +3,12 @@ import { Avatar, Divider, Drawer, IconButton, List, Typography } from "@mui/mate
3
3
  import React from "react";
4
4
  import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
5
5
  import { DrawerHeader } from "./DrawerHeader";
6
- import { globalApp } from "../app/ReactApp";
6
+ import { useAppContext } from "../app/ReactApp";
7
7
  export function LeftDrawer(props) {
8
+ // Global app
9
+ const app = useAppContext();
8
10
  // Destruct
9
- const { mdUp, width, appName = globalApp?.get("appName"), logoUrl = "/logo192.png", onMinimize, open = mdUp, children } = props;
11
+ const { mdUp, width, appName = app?.get("appName"), logoUrl = "/logo192.png", onMinimize, open = mdUp, children } = props;
10
12
  // Menu open/close state
11
13
  const [openLocal, setOpen] = React.useState();
12
14
  const handleDrawerClose = () => {
@@ -27,5 +29,5 @@ export function LeftDrawer(props) {
27
29
  }
28
30
  }, anchor: "left", variant: mdUp ? "persistent" : "temporary", open: open, transitionDuration: 0, onClose: mdUp ? undefined : handleDrawerClose, ModalProps: {
29
31
  keepMounted: true // Better open performance on mobile.
30
- }, children: [_jsxs(DrawerHeader, { children: [_jsx("a", { href: "https://www.etsoo.com", title: globalApp?.get("etsoo") ?? "ETSOO", target: "_blank", rel: "noreferrer", children: _jsx(Avatar, { src: logoUrl, variant: "square", sx: { marginLeft: -0.5, marginRight: 1.5, marginBottom: 1 } }) }), _jsx(Typography, { noWrap: true, component: "div", title: appName, sx: { flexGrow: 2 }, children: appName }), _jsx(IconButton, { size: "small", onClick: handleDrawerClose, children: _jsx(ChevronLeftIcon, {}) })] }), _jsx(Divider, {}), _jsx(List, { onClick: mdUp ? undefined : handleDrawerClose, children: children })] }));
32
+ }, children: [_jsxs(DrawerHeader, { children: [_jsx("a", { href: "https://www.etsoo.com", title: app?.get("etsoo") ?? "ETSOO", target: "_blank", rel: "noreferrer", children: _jsx(Avatar, { src: logoUrl, variant: "square", sx: { marginLeft: -0.5, marginRight: 1.5, marginBottom: 1 } }) }), _jsx(Typography, { noWrap: true, component: "div", title: appName, sx: { flexGrow: 2 }, children: appName }), _jsx(IconButton, { size: "small", onClick: handleDrawerClose, children: _jsx(ChevronLeftIcon, {}) })] }), _jsx(Divider, {}), _jsx(List, { onClick: mdUp ? undefined : handleDrawerClose, children: children })] }));
31
33
  }
@@ -1,17 +1,17 @@
1
1
  import { createElement as _createElement } from "react";
2
2
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
3
3
  import { ScrollRestoration } from "@etsoo/react";
4
- import { DateUtils, Utils } from "@etsoo/shared";
4
+ import { Utils } from "@etsoo/shared";
5
5
  import { Grid2, LinearProgress, Stack, Typography } from "@mui/material";
6
6
  import React from "react";
7
7
  import { Labels } from "../app/Labels";
8
- import { globalApp } from "../app/ReactApp";
9
8
  import { GridDataFormat } from "../GridDataFormat";
10
9
  import { MUGlobal } from "../MUGlobal";
11
10
  import { PullToRefreshUI } from "../PullToRefreshUI";
12
11
  import { CommonPage } from "./CommonPage";
13
12
  import { MessageUtils } from "../messages/MessageUtils";
14
13
  import { OperationMessageContainer } from "../messages/OperationMessageContainer";
14
+ import { useRequiredAppContext } from "../app/ReactApp";
15
15
  /**
16
16
  * View page grid item
17
17
  * @param props Props
@@ -31,15 +31,13 @@ export function ViewPageGridItem(props) {
31
31
  // Layout
32
32
  return (_jsxs(Grid2, { ...gridProps, ...options, children: [label != null && (_jsxs(Typography, { variant: "caption", component: "div", children: [label, ":"] })), typeof data === "object" ? (data) : (_jsx(Typography, { variant: "subtitle2", children: data }))] }));
33
33
  }
34
- function formatItemData(fieldData) {
34
+ function formatItemData(app, fieldData) {
35
35
  if (fieldData == null)
36
36
  return undefined;
37
37
  if (typeof fieldData === "string")
38
38
  return fieldData;
39
39
  if (fieldData instanceof Date)
40
- return globalApp
41
- ? globalApp.formatDate(fieldData, "d")
42
- : DateUtils.format(fieldData, "d");
40
+ return app.formatDate(fieldData, "d");
43
41
  return `${fieldData}`;
44
42
  }
45
43
  function getResp(singleRow) {
@@ -58,13 +56,13 @@ function getResp(singleRow) {
58
56
  };
59
57
  return { size };
60
58
  }
61
- function getItemField(field, data) {
59
+ function getItemField(app, field, data) {
62
60
  // Item data and label
63
61
  let itemData, itemLabel, gridProps = {};
64
62
  if (Array.isArray(field)) {
65
63
  const [fieldData, fieldType, renderProps, singleRow = "small"] = field;
66
64
  itemData = GridDataFormat(data[fieldData], fieldType, renderProps);
67
- itemLabel = globalApp?.get(fieldData) ?? fieldData;
65
+ itemLabel = app.get(fieldData) ?? fieldData;
68
66
  gridProps = { ...getResp(singleRow) };
69
67
  }
70
68
  else if (typeof field === "object") {
@@ -78,7 +76,7 @@ function getItemField(field, data) {
78
76
  if (typeof fieldData === "function")
79
77
  itemData = fieldData(data);
80
78
  else if (dataType == null)
81
- itemData = formatItemData(data[fieldData]);
79
+ itemData = formatItemData(app, data[fieldData]);
82
80
  else
83
81
  itemData = GridDataFormat(data[fieldData], dataType, renderProps);
84
82
  // Field label
@@ -86,12 +84,12 @@ function getItemField(field, data) {
86
84
  typeof fieldLabel === "function"
87
85
  ? fieldLabel(data)
88
86
  : fieldLabel != null
89
- ? globalApp?.get(fieldLabel) ?? fieldLabel
87
+ ? app.get(fieldLabel) ?? fieldLabel
90
88
  : fieldLabel;
91
89
  }
92
90
  else {
93
- itemData = formatItemData(data[field]);
94
- itemLabel = globalApp?.get(field) ?? field;
91
+ itemData = formatItemData(app, data[field]);
92
+ itemLabel = app.get(field) ?? field;
95
93
  }
96
94
  return [itemData, itemLabel, gridProps];
97
95
  }
@@ -100,6 +98,8 @@ function getItemField(field, data) {
100
98
  * @param props Props
101
99
  */
102
100
  export function ViewPage(props) {
101
+ // Global app
102
+ const app = useRequiredAppContext();
103
103
  // Destruct
104
104
  const { actions, children, fields, loadData, paddings = MUGlobal.pagePaddings, spacing = MUGlobal.half(MUGlobal.pagePaddings), supportRefresh = true, fabColumnDirection = true, fabTop = true, supportBack = true, pullToRefresh = true, gridRef, operationMessageHandler, ...rest } = props;
105
105
  // Data
@@ -140,7 +140,7 @@ export function ViewPage(props) {
140
140
  // Most flexible way, do whatever you want
141
141
  return field(data, refresh);
142
142
  }
143
- const [itemData, itemLabel, gridProps] = getItemField(field, data);
143
+ const [itemData, itemLabel, gridProps] = getItemField(app, field, data);
144
144
  // Some callback function may return '' instead of undefined
145
145
  if (itemData == null || itemData === "")
146
146
  return undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.4.73",
3
+ "version": "1.4.75",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -40,9 +40,9 @@
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.5.88",
44
- "@etsoo/notificationbase": "^1.1.55",
45
- "@etsoo/react": "^1.8.24",
43
+ "@etsoo/appscript": "^1.5.90",
44
+ "@etsoo/notificationbase": "^1.1.56",
45
+ "@etsoo/react": "^1.8.26",
46
46
  "@etsoo/shared": "^1.2.58",
47
47
  "@mui/icons-material": "^6.3.1",
48
48
  "@mui/material": "^6.3.1",
@@ -7,11 +7,11 @@ import {
7
7
  } from "@etsoo/appscript";
8
8
  import { FormLabel, Grid2, GridSize } from "@mui/material";
9
9
  import React from "react";
10
- import { globalApp } from "./app/ReactApp";
11
10
  import { ComboBox } from "./ComboBox";
12
11
  import { Tiplist } from "./Tiplist";
13
12
  import { ResponsiveStyleValue } from "./ResponsiveStyleValue";
14
13
  import { RegionsRQ } from "./RegionsRQ";
14
+ import { useAppContext } from "./app/ReactApp";
15
15
 
16
16
  /**
17
17
  * Address field
@@ -166,13 +166,16 @@ export type AddressSelectorProps = {
166
166
  * @param props Props
167
167
  */
168
168
  export function AddressSelector(props: AddressSelectorProps) {
169
+ // Global app
170
+ const app = useAppContext();
171
+
169
172
  // Labels
170
173
  const {
171
174
  city: cityDefault = "City",
172
175
  district: districtDefault = "District",
173
176
  region: regionDefault = "Region",
174
177
  state: stateDefault = "State"
175
- } = globalApp?.getLabels("region", "state", "city", "district") ?? {};
178
+ } = app?.getLabels("region", "state", "city", "district") ?? {};
176
179
 
177
180
  // Destruct
178
181
  const {
@@ -1,10 +1,10 @@
1
1
  import { Utils } from "@etsoo/shared";
2
2
  import { Button, Divider, Theme, Typography, useTheme } from "@mui/material";
3
3
  import React, { CSSProperties } from "react";
4
- import { globalApp } from "./app/ReactApp";
5
4
  import { ListMoreDisplay, ListMoreDisplayProps } from "./ListMoreDisplay";
6
5
  import { ShowDataComparison } from "./ShowDataComparison";
7
6
  import { AuditLineDto } from "@etsoo/appscript";
7
+ import { useAppContext } from "./app/ReactApp";
8
8
 
9
9
  /**
10
10
  * Audit display props
@@ -32,17 +32,6 @@ export interface AuditDisplayProps
32
32
  itemRenderer?: (data: AuditLineDto, index: number) => React.ReactNode;
33
33
  }
34
34
 
35
- // Get label
36
- const getLabel = (key: string) => {
37
- return globalApp?.get(Utils.formatInitial(key)) ?? key;
38
- };
39
-
40
- // Format date
41
- const formatDate = (date: Date) => {
42
- if (globalApp) return globalApp.formatDate(date, "ds");
43
- return date.toUTCString();
44
- };
45
-
46
35
  /**
47
36
  * Audit display
48
37
  * @param props Props
@@ -52,6 +41,19 @@ export function AuditDisplay(props: AuditDisplayProps) {
52
41
  // Theme
53
42
  const theme = useTheme();
54
43
 
44
+ // Global app
45
+ const app = useAppContext();
46
+
47
+ // Get label
48
+ const getLabel = (key: string) => {
49
+ return app?.get(Utils.formatInitial(key)) ?? key;
50
+ };
51
+
52
+ // Format date
53
+ const formatDate = (date: Date) => {
54
+ return app?.formatDate(date, "ds") ?? date.toUTCString();
55
+ };
56
+
55
57
  // Title
56
58
  var title = getLabel("dataComparison");
57
59