@etsoo/materialui 1.0.1

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 (250) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.json +38 -0
  3. package/.gitattributes +2 -0
  4. package/.github/workflows/main.yml +48 -0
  5. package/.prettierignore +5 -0
  6. package/.prettierrc +6 -0
  7. package/LICENSE +21 -0
  8. package/README.md +16 -0
  9. package/__tests__/ComboBox.tsx +30 -0
  10. package/__tests__/MUGlobalTests.tsx +58 -0
  11. package/__tests__/NotifierMUTests.tsx +217 -0
  12. package/__tests__/SelectEx.tsx +26 -0
  13. package/__tests__/tsconfig.json +19 -0
  14. package/babel.config.json +11 -0
  15. package/lib/AuditDisplay.d.ts +33 -0
  16. package/lib/AuditDisplay.js +52 -0
  17. package/lib/AutocompleteExtendedProps.d.ts +64 -0
  18. package/lib/AutocompleteExtendedProps.js +1 -0
  19. package/lib/BackButton.d.ts +13 -0
  20. package/lib/BackButton.js +33 -0
  21. package/lib/BridgeCloseButton.d.ts +23 -0
  22. package/lib/BridgeCloseButton.js +32 -0
  23. package/lib/ButtonLink.d.ts +17 -0
  24. package/lib/ButtonLink.js +19 -0
  25. package/lib/ComboBox.d.ts +38 -0
  26. package/lib/ComboBox.js +108 -0
  27. package/lib/CountdownButton.d.ts +23 -0
  28. package/lib/CountdownButton.js +81 -0
  29. package/lib/CustomFabProps.d.ts +27 -0
  30. package/lib/CustomFabProps.js +1 -0
  31. package/lib/DataGridEx.d.ts +94 -0
  32. package/lib/DataGridEx.js +329 -0
  33. package/lib/DataGridRenderers.d.ts +22 -0
  34. package/lib/DataGridRenderers.js +99 -0
  35. package/lib/DialogButton.d.ts +54 -0
  36. package/lib/DialogButton.js +45 -0
  37. package/lib/DnDList.d.ts +87 -0
  38. package/lib/DnDList.js +153 -0
  39. package/lib/DraggablePaperComponent.d.ts +8 -0
  40. package/lib/DraggablePaperComponent.js +12 -0
  41. package/lib/EmailInput.d.ts +11 -0
  42. package/lib/EmailInput.js +15 -0
  43. package/lib/FabBox.d.ts +21 -0
  44. package/lib/FabBox.js +31 -0
  45. package/lib/FlexBox.d.ts +14 -0
  46. package/lib/FlexBox.js +18 -0
  47. package/lib/GridDataFormat.d.ts +10 -0
  48. package/lib/GridDataFormat.js +43 -0
  49. package/lib/IconButtonLink.d.ts +17 -0
  50. package/lib/IconButtonLink.js +16 -0
  51. package/lib/InputField.d.ts +21 -0
  52. package/lib/InputField.js +39 -0
  53. package/lib/ItemList.d.ts +56 -0
  54. package/lib/ItemList.js +69 -0
  55. package/lib/ListItemRightIcon.d.ts +4 -0
  56. package/lib/ListItemRightIcon.js +8 -0
  57. package/lib/ListMoreDisplay.d.ts +35 -0
  58. package/lib/ListMoreDisplay.js +99 -0
  59. package/lib/LoadingButton.d.ts +16 -0
  60. package/lib/LoadingButton.js +41 -0
  61. package/lib/MUGlobal.d.ts +102 -0
  62. package/lib/MUGlobal.js +184 -0
  63. package/lib/MaskInput.d.ts +34 -0
  64. package/lib/MaskInput.js +43 -0
  65. package/lib/MobileListItemRenderer.d.ts +17 -0
  66. package/lib/MobileListItemRenderer.js +35 -0
  67. package/lib/MoreFab.d.ts +45 -0
  68. package/lib/MoreFab.js +95 -0
  69. package/lib/NotifierMU.d.ts +47 -0
  70. package/lib/NotifierMU.js +387 -0
  71. package/lib/NotifierPromptProps.d.ts +22 -0
  72. package/lib/NotifierPromptProps.js +1 -0
  73. package/lib/OptionGroup.d.ts +58 -0
  74. package/lib/OptionGroup.js +81 -0
  75. package/lib/PList.d.ts +15 -0
  76. package/lib/PList.js +12 -0
  77. package/lib/ProgressCount.d.ts +44 -0
  78. package/lib/ProgressCount.js +79 -0
  79. package/lib/PullToRefreshUI.d.ts +9 -0
  80. package/lib/PullToRefreshUI.js +18 -0
  81. package/lib/RLink.d.ts +14 -0
  82. package/lib/RLink.js +37 -0
  83. package/lib/ResponsibleContainer.d.ts +87 -0
  84. package/lib/ResponsibleContainer.js +156 -0
  85. package/lib/ScrollTopFab.d.ts +7 -0
  86. package/lib/ScrollTopFab.js +25 -0
  87. package/lib/ScrollerListEx.d.ts +81 -0
  88. package/lib/ScrollerListEx.js +167 -0
  89. package/lib/SearchBar.d.ts +29 -0
  90. package/lib/SearchBar.js +260 -0
  91. package/lib/SearchField.d.ts +21 -0
  92. package/lib/SearchField.js +39 -0
  93. package/lib/SearchOptionGroup.d.ts +9 -0
  94. package/lib/SearchOptionGroup.js +14 -0
  95. package/lib/SelectBool.d.ts +13 -0
  96. package/lib/SelectBool.js +22 -0
  97. package/lib/SelectEx.d.ts +50 -0
  98. package/lib/SelectEx.js +156 -0
  99. package/lib/ShowDataComparison.d.ts +20 -0
  100. package/lib/ShowDataComparison.js +58 -0
  101. package/lib/Switch.d.ts +29 -0
  102. package/lib/Switch.js +34 -0
  103. package/lib/SwitchAnt.d.ts +25 -0
  104. package/lib/SwitchAnt.js +40 -0
  105. package/lib/TabBox.d.ts +54 -0
  106. package/lib/TabBox.js +31 -0
  107. package/lib/TableEx.d.ts +65 -0
  108. package/lib/TableEx.js +270 -0
  109. package/lib/TextFieldEx.d.ts +101 -0
  110. package/lib/TextFieldEx.js +126 -0
  111. package/lib/Tiplist.d.ts +18 -0
  112. package/lib/Tiplist.js +157 -0
  113. package/lib/TooltipClick.d.ts +15 -0
  114. package/lib/TooltipClick.js +40 -0
  115. package/lib/UserAvatar.d.ts +24 -0
  116. package/lib/UserAvatar.js +25 -0
  117. package/lib/UserAvatarEditor.d.ts +53 -0
  118. package/lib/UserAvatarEditor.js +129 -0
  119. package/lib/app/CommonApp.d.ts +38 -0
  120. package/lib/app/CommonApp.js +149 -0
  121. package/lib/app/IServiceAppSettings.d.ts +11 -0
  122. package/lib/app/IServiceAppSettings.js +1 -0
  123. package/lib/app/IServicePage.d.ts +6 -0
  124. package/lib/app/IServicePage.js +1 -0
  125. package/lib/app/IServiceUser.d.ts +14 -0
  126. package/lib/app/IServiceUser.js +1 -0
  127. package/lib/app/ISmartERPUser.d.ts +14 -0
  128. package/lib/app/ISmartERPUser.js +1 -0
  129. package/lib/app/Labels.d.ts +65 -0
  130. package/lib/app/Labels.js +62 -0
  131. package/lib/app/ReactApp.d.ts +195 -0
  132. package/lib/app/ReactApp.js +296 -0
  133. package/lib/app/ServiceApp.d.ts +78 -0
  134. package/lib/app/ServiceApp.js +244 -0
  135. package/lib/index.d.ts +74 -0
  136. package/lib/index.js +74 -0
  137. package/lib/pages/CommonPage.d.ts +11 -0
  138. package/lib/pages/CommonPage.js +60 -0
  139. package/lib/pages/CommonPageProps.d.ts +59 -0
  140. package/lib/pages/CommonPageProps.js +1 -0
  141. package/lib/pages/DataGridPage.d.ts +9 -0
  142. package/lib/pages/DataGridPage.js +79 -0
  143. package/lib/pages/DataGridPageProps.d.ts +17 -0
  144. package/lib/pages/DataGridPageProps.js +1 -0
  145. package/lib/pages/EditPage.d.ts +33 -0
  146. package/lib/pages/EditPage.js +29 -0
  147. package/lib/pages/FixedListPage.d.ts +15 -0
  148. package/lib/pages/FixedListPage.js +70 -0
  149. package/lib/pages/ListPage.d.ts +9 -0
  150. package/lib/pages/ListPage.js +50 -0
  151. package/lib/pages/ListPageProps.d.ts +7 -0
  152. package/lib/pages/ListPageProps.js +1 -0
  153. package/lib/pages/ResponsivePage.d.ts +9 -0
  154. package/lib/pages/ResponsivePage.js +45 -0
  155. package/lib/pages/ResponsivePageProps.d.ts +39 -0
  156. package/lib/pages/ResponsivePageProps.js +1 -0
  157. package/lib/pages/SearchPageProps.d.ts +30 -0
  158. package/lib/pages/SearchPageProps.js +1 -0
  159. package/lib/pages/TablePage.d.ts +9 -0
  160. package/lib/pages/TablePage.js +69 -0
  161. package/lib/pages/TablePageProps.d.ts +7 -0
  162. package/lib/pages/TablePageProps.js +1 -0
  163. package/lib/pages/ViewPage.d.ts +66 -0
  164. package/lib/pages/ViewPage.js +105 -0
  165. package/lib/texts/DateText.d.ts +34 -0
  166. package/lib/texts/DateText.js +25 -0
  167. package/lib/texts/MoneyText.d.ts +21 -0
  168. package/lib/texts/MoneyText.js +14 -0
  169. package/lib/texts/NumberText.d.ts +25 -0
  170. package/lib/texts/NumberText.js +14 -0
  171. package/package.json +97 -0
  172. package/src/AuditDisplay.tsx +114 -0
  173. package/src/AutocompleteExtendedProps.ts +83 -0
  174. package/src/BackButton.tsx +55 -0
  175. package/src/BridgeCloseButton.tsx +69 -0
  176. package/src/ButtonLink.tsx +32 -0
  177. package/src/ComboBox.tsx +251 -0
  178. package/src/CountdownButton.tsx +119 -0
  179. package/src/CustomFabProps.ts +32 -0
  180. package/src/DataGridEx.tsx +713 -0
  181. package/src/DataGridRenderers.tsx +140 -0
  182. package/src/DialogButton.tsx +163 -0
  183. package/src/DnDList.tsx +344 -0
  184. package/src/DraggablePaperComponent.tsx +19 -0
  185. package/src/EmailInput.tsx +24 -0
  186. package/src/FabBox.tsx +51 -0
  187. package/src/FlexBox.tsx +20 -0
  188. package/src/GridDataFormat.tsx +77 -0
  189. package/src/IconButtonLink.tsx +29 -0
  190. package/src/InputField.tsx +82 -0
  191. package/src/ItemList.tsx +204 -0
  192. package/src/ListItemRightIcon.tsx +9 -0
  193. package/src/ListMoreDisplay.tsx +205 -0
  194. package/src/LoadingButton.tsx +75 -0
  195. package/src/MUGlobal.ts +220 -0
  196. package/src/MaskInput.tsx +107 -0
  197. package/src/MobileListItemRenderer.tsx +79 -0
  198. package/src/MoreFab.tsx +211 -0
  199. package/src/NotifierMU.tsx +654 -0
  200. package/src/NotifierPromptProps.ts +24 -0
  201. package/src/OptionGroup.tsx +223 -0
  202. package/src/PList.tsx +27 -0
  203. package/src/ProgressCount.tsx +166 -0
  204. package/src/PullToRefreshUI.tsx +21 -0
  205. package/src/RLink.tsx +64 -0
  206. package/src/ResponsibleContainer.tsx +394 -0
  207. package/src/ScrollTopFab.tsx +34 -0
  208. package/src/ScrollerListEx.tsx +387 -0
  209. package/src/SearchBar.tsx +396 -0
  210. package/src/SearchField.tsx +82 -0
  211. package/src/SearchOptionGroup.tsx +31 -0
  212. package/src/SelectBool.tsx +33 -0
  213. package/src/SelectEx.tsx +290 -0
  214. package/src/ShowDataComparison.tsx +106 -0
  215. package/src/Switch.tsx +94 -0
  216. package/src/SwitchAnt.tsx +95 -0
  217. package/src/TabBox.tsx +118 -0
  218. package/src/TableEx.tsx +558 -0
  219. package/src/TextFieldEx.tsx +249 -0
  220. package/src/Tiplist.tsx +303 -0
  221. package/src/TooltipClick.tsx +84 -0
  222. package/src/UserAvatar.tsx +64 -0
  223. package/src/UserAvatarEditor.tsx +287 -0
  224. package/src/app/CommonApp.ts +223 -0
  225. package/src/app/IServiceAppSettings.ts +13 -0
  226. package/src/app/IServicePage.ts +6 -0
  227. package/src/app/IServiceUser.ts +17 -0
  228. package/src/app/ISmartERPUser.ts +16 -0
  229. package/src/app/Labels.ts +77 -0
  230. package/src/app/ReactApp.ts +504 -0
  231. package/src/app/ServiceApp.ts +352 -0
  232. package/src/index.ts +77 -0
  233. package/src/pages/CommonPage.tsx +128 -0
  234. package/src/pages/CommonPageProps.ts +70 -0
  235. package/src/pages/DataGridPage.tsx +140 -0
  236. package/src/pages/DataGridPageProps.ts +24 -0
  237. package/src/pages/EditPage.tsx +114 -0
  238. package/src/pages/FixedListPage.tsx +141 -0
  239. package/src/pages/ListPage.tsx +90 -0
  240. package/src/pages/ListPageProps.ts +12 -0
  241. package/src/pages/ResponsivePage.tsx +68 -0
  242. package/src/pages/ResponsivePageProps.ts +57 -0
  243. package/src/pages/SearchPageProps.ts +39 -0
  244. package/src/pages/TablePage.tsx +126 -0
  245. package/src/pages/TablePageProps.ts +12 -0
  246. package/src/pages/ViewPage.tsx +282 -0
  247. package/src/texts/DateText.tsx +74 -0
  248. package/src/texts/MoneyText.tsx +49 -0
  249. package/src/texts/NumberText.tsx +40 -0
  250. package/tsconfig.json +19 -0
@@ -0,0 +1,504 @@
1
+ import {
2
+ BridgeUtils,
3
+ CoreApp,
4
+ createClient,
5
+ IActionResult,
6
+ IApp,
7
+ IAppSettings,
8
+ ICoreApp,
9
+ IUser
10
+ } from '@etsoo/appscript';
11
+ import {
12
+ NotificationMessageType,
13
+ NotificationRenderProps,
14
+ NotificationReturn
15
+ } from '@etsoo/notificationbase';
16
+ import { DataTypes, WindowStorage } from '@etsoo/shared';
17
+ import React from 'react';
18
+ import { NotifierMU } from '../NotifierMU';
19
+ import { ProgressCount } from '../ProgressCount';
20
+ import { Labels } from './Labels';
21
+ import { createBrowserHistory, createMemoryHistory, History } from 'history';
22
+ import {
23
+ CultureAction,
24
+ CultureState,
25
+ INotificationReact,
26
+ InputDialogProps,
27
+ IPageData,
28
+ IStateProps,
29
+ NotificationReactCallProps,
30
+ PageAction,
31
+ PageActionType,
32
+ PageState,
33
+ UserAction,
34
+ UserActionType,
35
+ UserCalls,
36
+ UserState
37
+ } from '@etsoo/react';
38
+
39
+ /**
40
+ * Global application
41
+ */
42
+ export let globalApp: IApp & IReactAppBase;
43
+
44
+ /**
45
+ * React app state detector
46
+ * Case 1: undefined, when refresh the whole page
47
+ * Case 2: false, unauthorized
48
+ * Case 3: true, authorized or considered as authorized (maynot, like token expiry)
49
+ * Case 4: property or properties changed
50
+ * @param props Props
51
+ * @returns Component
52
+ */
53
+ export function ReactAppStateDetector(props: IStateProps) {
54
+ // Destruct
55
+ const { targetFields, update } = props;
56
+
57
+ // Context
58
+ const { state } =
59
+ globalApp == null
60
+ ? ({} as UserCalls<IUser>)
61
+ : React.useContext(globalApp.userState.context);
62
+
63
+ // Ready
64
+ React.useEffect(() => {
65
+ // Match fields
66
+ const changedFields = state.lastChangedFields;
67
+ let matchedFields: string[] | undefined;
68
+ if (targetFields == null || changedFields == null) {
69
+ matchedFields = changedFields;
70
+ } else {
71
+ matchedFields = [];
72
+ targetFields.forEach((targetField) => {
73
+ if (changedFields.includes(targetField))
74
+ matchedFields?.push(targetField);
75
+ });
76
+ }
77
+
78
+ // Callback
79
+ update(state.authorized, matchedFields);
80
+ }, [state]);
81
+
82
+ // return
83
+ return React.createElement(React.Fragment);
84
+ }
85
+
86
+ /**
87
+ * React implemented base
88
+ */
89
+ export interface IReactAppBase {
90
+ /**
91
+ * User state
92
+ */
93
+ readonly userState: UserState<any>;
94
+
95
+ /**
96
+ * Router history
97
+ */
98
+ readonly history: History;
99
+
100
+ /**
101
+ * Set page data
102
+ * @param data Page data
103
+ */
104
+ setPageData(data: IPageData): void;
105
+
106
+ /**
107
+ * Set page title and data
108
+ * @param key Page title resource key
109
+ */
110
+ setPageKey(key: string): void;
111
+
112
+ /**
113
+ * Set page title and data
114
+ * @param title Page title
115
+ */
116
+ setPageTitle(title: string): void;
117
+ }
118
+
119
+ /**
120
+ * Core application interface
121
+ */
122
+ export interface IReactApp<
123
+ S extends IAppSettings,
124
+ D extends IUser,
125
+ P extends IPageData
126
+ > extends ICoreApp<D, S, React.ReactNode, NotificationReactCallProps>,
127
+ IReactAppBase {
128
+ /**
129
+ * User state
130
+ */
131
+ readonly userState: UserState<D>;
132
+
133
+ /**
134
+ * Set page data
135
+ * @param data Page data
136
+ */
137
+ setPageData(data: P): void;
138
+ }
139
+
140
+ /**
141
+ * React application
142
+ */
143
+ export class ReactApp<
144
+ S extends IAppSettings,
145
+ D extends IUser,
146
+ P extends IPageData
147
+ >
148
+ extends CoreApp<D, S, React.ReactNode, NotificationReactCallProps>
149
+ implements IReactApp<S, D, P>
150
+ {
151
+ private static _notifierProvider: React.FunctionComponent<NotificationRenderProps>;
152
+
153
+ /**
154
+ * Get notifier provider
155
+ */
156
+ static get notifierProvider() {
157
+ return this._notifierProvider;
158
+ }
159
+
160
+ private static createApi(settings: IAppSettings) {
161
+ // API
162
+ // Support to replace {hostname} with current hostname
163
+ const api = createClient();
164
+ api.baseUrl = settings.endpoint;
165
+ return api;
166
+ }
167
+
168
+ private static createNotifier() {
169
+ // Notifier
170
+ ReactApp._notifierProvider = NotifierMU.setup();
171
+
172
+ return NotifierMU.instance;
173
+ }
174
+
175
+ /**
176
+ * Culture state
177
+ */
178
+ readonly cultureState: CultureState;
179
+
180
+ /**
181
+ * Router history
182
+ */
183
+ readonly history: History;
184
+
185
+ /**
186
+ * Page state
187
+ */
188
+ readonly pageState: PageState<P>;
189
+
190
+ /**
191
+ * User state
192
+ */
193
+ readonly userState = new UserState<D>();
194
+
195
+ /**
196
+ * Is screen size down 'sm'
197
+ */
198
+ smDown?: boolean;
199
+
200
+ /**
201
+ * Is screen size up 'md'
202
+ */
203
+ mdUp?: boolean;
204
+
205
+ /**
206
+ * Page state dispatch
207
+ */
208
+ pageStateDispatch?: React.Dispatch<PageAction<P>>;
209
+
210
+ /**
211
+ * User state dispatch
212
+ */
213
+ userStateDispatch?: React.Dispatch<UserAction<D>>;
214
+
215
+ /**
216
+ * Constructor
217
+ * @param settings Settings
218
+ * @param name Application name
219
+ */
220
+ constructor(settings: S, name: string) {
221
+ super(
222
+ settings,
223
+ ReactApp.createApi(settings),
224
+ ReactApp.createNotifier(),
225
+ new WindowStorage(),
226
+ name
227
+ );
228
+
229
+ if (BridgeUtils.host) {
230
+ const startUrl = BridgeUtils.host.getStartUrl();
231
+ this.history = createMemoryHistory({
232
+ initialEntries: startUrl == null ? undefined : [startUrl]
233
+ });
234
+
235
+ BridgeUtils.host.onUpdate((app, version) => {
236
+ this.notifier.message(
237
+ NotificationMessageType.Success,
238
+ this.get('updateTip') + `(${[app, version].join(', ')})`,
239
+ this.get('updateReady')
240
+ );
241
+ });
242
+ } else {
243
+ this.history = createBrowserHistory();
244
+ }
245
+
246
+ this.cultureState = new CultureState(settings.currentCulture);
247
+ this.pageState = new PageState<P>();
248
+
249
+ globalApp = this;
250
+ }
251
+
252
+ /**
253
+ * Override alert action result
254
+ * @param result Action result
255
+ * @param callback Callback
256
+ */
257
+ override alertResult(
258
+ result: IActionResult,
259
+ callback?: NotificationReturn<void>
260
+ ) {
261
+ const message = this.formatResult(result);
262
+ if (message.endsWith(')')) {
263
+ const startPos = message.lastIndexOf('(');
264
+ if (startPos > 0) {
265
+ const main = message.substring(0, startPos).trim();
266
+ const tip = message.substring(startPos);
267
+
268
+ const titleNode = React.createElement(
269
+ React.Fragment,
270
+ null,
271
+ main,
272
+ React.createElement('br'),
273
+ React.createElement(
274
+ 'span',
275
+ { style: { fontSize: '9px' } },
276
+ tip
277
+ )
278
+ );
279
+ this.notifier.alert(titleNode, callback);
280
+ return;
281
+ }
282
+ }
283
+ this.notifier.alert(message, callback);
284
+ }
285
+
286
+ /**
287
+ * Change culture
288
+ * @param culture New culture definition
289
+ */
290
+ override changeCulture(culture: DataTypes.CultureDefinition) {
291
+ // Super call to update cultrue
292
+ super.changeCulture(culture);
293
+
294
+ // Update component labels
295
+ Labels.setLabels(culture.resources, {
296
+ notificationMU: {
297
+ alertTitle: 'warning',
298
+ alertOK: 'ok',
299
+ confirmTitle: 'confirm',
300
+ confirmYes: 'ok',
301
+ confirmNo: 'cancel',
302
+ promptTitle: 'prompt',
303
+ promptCancel: 'cancel',
304
+ promptOK: 'ok'
305
+ }
306
+ });
307
+
308
+ // Notify host
309
+ BridgeUtils.host?.changeCulture(culture.name);
310
+
311
+ // Document title
312
+ document.title = this.get(this.name) ?? this.name;
313
+ }
314
+
315
+ /**
316
+ * Change culture extended
317
+ * @param dispatch Dispatch method
318
+ * @param culture New culture definition
319
+ */
320
+ changeCultureEx(
321
+ dispatch: React.Dispatch<CultureAction>,
322
+ culture: DataTypes.CultureDefinition
323
+ ): void {
324
+ // Same?
325
+ if (culture.name === this.culture) return;
326
+
327
+ // Dispatch action
328
+ dispatch(culture);
329
+
330
+ // Super call
331
+ this.changeCulture(culture);
332
+ }
333
+
334
+ /**
335
+ * Get date format props
336
+ * @returns Props
337
+ */
338
+ getDateFormatProps() {
339
+ return { culture: this.culture, timeZone: this.getTimeZone() };
340
+ }
341
+
342
+ /**
343
+ * Get money format props
344
+ * @param currency Currency, if undefined, default currency applied
345
+ * @returns Props
346
+ */
347
+ getMoneyFormatProps(currency?: string) {
348
+ return { culture: this.culture, currency: currency ?? this.currency };
349
+ }
350
+
351
+ /**
352
+ * Fresh countdown UI
353
+ * @param callback Callback
354
+ */
355
+ freshCountdownUI(callback?: () => PromiseLike<unknown>) {
356
+ // Labels
357
+ const labels = this.getLabels('cancel', 'tokenExpiry');
358
+
359
+ // Progress
360
+ const progress = React.createElement(ProgressCount, {
361
+ seconds: 30,
362
+ valueUnit: 's',
363
+ onComplete: () => {
364
+ // Stop the progress
365
+ return false;
366
+ }
367
+ });
368
+
369
+ // Popup
370
+ this.notifier.alert(
371
+ labels.tokenExpiry,
372
+ async () => {
373
+ if (callback) await callback();
374
+ else await this.tryLogin();
375
+ },
376
+ undefined,
377
+ {
378
+ okLabel: labels.cancel,
379
+ primaryButton: { fullWidth: true, autoFocus: false },
380
+ inputs: progress
381
+ }
382
+ );
383
+ }
384
+
385
+ /**
386
+ * Redirect to the Url
387
+ * @param url Url
388
+ */
389
+ override redirectTo(url: string) {
390
+ this.history.push(url);
391
+ }
392
+
393
+ /**
394
+ * Set page data
395
+ * @param data Page data
396
+ */
397
+ setPageData(data: P): void {
398
+ // Dispatch the change
399
+ if (this.pageStateDispatch != null) {
400
+ this.pageStateDispatch({
401
+ type: PageActionType.Data,
402
+ data
403
+ });
404
+ }
405
+ }
406
+
407
+ /**
408
+ * Set page title and data
409
+ * @param title Page title
410
+ */
411
+ setPageTitle(title: string): void {
412
+ // Data
413
+ const data = { title } as P;
414
+
415
+ // Dispatch the change
416
+ if (this.pageStateDispatch != null) {
417
+ this.pageStateDispatch({
418
+ type: PageActionType.Title,
419
+ data
420
+ });
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Set page title and data
426
+ * @param key Page title resource key
427
+ */
428
+ setPageKey(key: string): void {
429
+ this.setPageTitle(this.get<string>(key) ?? '');
430
+ }
431
+
432
+ /**
433
+ * Show input dialog
434
+ * @param props Props
435
+ */
436
+ showInputDialog({
437
+ title,
438
+ message,
439
+ callback,
440
+ ...rest
441
+ }: InputDialogProps): INotificationReact {
442
+ return this.notifier.prompt<HTMLFormElement | undefined>(
443
+ message,
444
+ callback,
445
+ title,
446
+ rest
447
+ );
448
+ }
449
+
450
+ /**
451
+ * User login extended
452
+ * @param user New user
453
+ * @param refreshToken Refresh token
454
+ * @param keep Keep in local storage or not
455
+ * @param dispatch User state dispatch
456
+ */
457
+ override userLogin(
458
+ user: D,
459
+ refreshToken: string,
460
+ keep?: boolean,
461
+ dispatch?: boolean
462
+ ): void {
463
+ // Super call, set token
464
+ super.userLogin(user, refreshToken, keep);
465
+
466
+ // Dispatch action
467
+ if (this.userStateDispatch != null && dispatch !== false)
468
+ this.userStateDispatch({
469
+ type: UserActionType.Login,
470
+ user
471
+ });
472
+ }
473
+
474
+ /**
475
+ * User logout
476
+ * @param clearToken Clear refresh token or not
477
+ */
478
+ override userLogout(clearToken: boolean = true): void {
479
+ // Super call
480
+ super.userLogout(clearToken);
481
+
482
+ // Dispatch action
483
+ if (this.userStateDispatch != null)
484
+ this.userStateDispatch({
485
+ type: UserActionType.Logout
486
+ });
487
+ }
488
+
489
+ /**
490
+ * User unauthorized
491
+ */
492
+ override userUnauthorized() {
493
+ // Super call
494
+ super.userUnauthorized();
495
+
496
+ if (this.userStateDispatch != null) {
497
+ // There is delay during state update
498
+ // Not a good idea to try login multiple times with API calls
499
+ this.userStateDispatch({
500
+ type: UserActionType.Unauthorized
501
+ });
502
+ }
503
+ }
504
+ }