@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,352 @@
1
+ import {
2
+ BridgeUtils,
3
+ createClient,
4
+ IActionResult,
5
+ IApi,
6
+ IApiPayload,
7
+ RefreshTokenProps,
8
+ RefreshTokenResult
9
+ } from '@etsoo/appscript';
10
+ import { CoreConstants, RefreshTokenRQ } from '@etsoo/react';
11
+ import { DomUtils } from '@etsoo/shared';
12
+ import { IServiceAppSettings } from './IServiceAppSettings';
13
+ import { IServicePageData } from './IServicePage';
14
+ import { IServiceUser, ServiceLoginResult } from './IServiceUser';
15
+ import { ISmartERPUser } from './ISmartERPUser';
16
+ import { ReactApp } from './ReactApp';
17
+
18
+ /**
19
+ * Core Service App
20
+ * Service login to core system, get the refesh token and access token
21
+ * Use the acess token to the service api, get a service access token
22
+ * Use the new acess token and refresh token to login
23
+ */
24
+ export class ServiceApp<
25
+ U extends IServiceUser = IServiceUser,
26
+ P extends IServicePageData = IServicePageData,
27
+ S extends IServiceAppSettings = IServiceAppSettings
28
+ > extends ReactApp<S, ISmartERPUser, P> {
29
+ /**
30
+ * Service API
31
+ */
32
+ readonly serviceApi: IApi;
33
+
34
+ private _serviceUser?: U;
35
+ /**
36
+ * Service user
37
+ */
38
+ get serviceUser() {
39
+ return this._serviceUser;
40
+ }
41
+ protected set serviceUser(value: U | undefined) {
42
+ this._serviceUser = value;
43
+ }
44
+
45
+ /**
46
+ * Service passphrase
47
+ */
48
+ protected servicePassphrase: string = '';
49
+
50
+ /**
51
+ * Constructor
52
+ * @param settings Settings
53
+ * @param name Application name
54
+ */
55
+ constructor(settings: S, name: string) {
56
+ super(settings, name);
57
+
58
+ // Check
59
+ if (settings.serviceId == null || settings.serviceEndpoint == null) {
60
+ throw new Error('No service settings');
61
+ }
62
+
63
+ // Service API
64
+ const api = createClient();
65
+ api.baseUrl = settings.serviceEndpoint;
66
+
67
+ this.setApi(api);
68
+ this.serviceApi = api;
69
+ }
70
+
71
+ /**
72
+ * Load SmartERP core
73
+ */
74
+ loadSmartERP() {
75
+ if (BridgeUtils.host == null) {
76
+ window.location.href = this.settings.webUrl;
77
+ } else {
78
+ BridgeUtils.host.loadApp('core');
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Go to the login page
84
+ * @param tryLogin Try to login again
85
+ */
86
+ override toLoginPage(tryLogin?: boolean) {
87
+ const parameters = `?serviceId=${this.settings.serviceId}&${
88
+ DomUtils.CultureField
89
+ }=${this.culture}${tryLogin ? '' : '&tryLogin=false'}`;
90
+
91
+ if (BridgeUtils.host == null) {
92
+ const coreUrl = this.settings.webUrl;
93
+ window.location.href = coreUrl + parameters;
94
+ } else {
95
+ BridgeUtils.host.loadApp('core', parameters);
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Refresh token
101
+ * @param props Props
102
+ */
103
+ override async refreshToken<D extends object = RefreshTokenRQ>(
104
+ props?: RefreshTokenProps<D>
105
+ ) {
106
+ // Destruct
107
+ const {
108
+ callback,
109
+ data,
110
+ relogin = false,
111
+ showLoading = false
112
+ } = props ?? {};
113
+
114
+ // Token
115
+ const token = this.getCacheToken();
116
+ if (token == null || token === '') {
117
+ if (callback) callback(false);
118
+ return false;
119
+ }
120
+
121
+ // Reqest data
122
+ // Merge additional data passed
123
+ const rq: RefreshTokenRQ = {
124
+ deviceId: this.deviceId,
125
+ timezone: this.getTimeZone(),
126
+ ...data
127
+ };
128
+
129
+ // Login result type
130
+ type LoginResult = IActionResult<U>;
131
+
132
+ // Payload
133
+ const payload: IApiPayload<LoginResult, any> = {
134
+ showLoading,
135
+ config: { headers: { [CoreConstants.TokenHeaderRefresh]: token } },
136
+ onError: (error) => {
137
+ if (callback) callback(error);
138
+
139
+ // Prevent further processing
140
+ return false;
141
+ }
142
+ };
143
+
144
+ // Success callback
145
+ const success = async (
146
+ result: LoginResult,
147
+ failCallback?: (result: RefreshTokenResult) => void
148
+ ) => {
149
+ // Token
150
+ const refreshToken = this.getResponseToken(payload.response);
151
+ if (refreshToken == null || result.data == null) {
152
+ if (failCallback) failCallback(this.get('noData')!);
153
+ return false;
154
+ }
155
+
156
+ // User data
157
+ const userData = result.data;
158
+
159
+ // Use core system access token to service api to exchange service access token
160
+ const serviceResult = await this.serviceApi.put<
161
+ ServiceLoginResult<U>
162
+ >(
163
+ 'Auth/ExchangeToken',
164
+ {
165
+ token: this.encryptEnhanced(
166
+ userData.token,
167
+ this.settings.serviceId.toString()
168
+ )
169
+ },
170
+ {
171
+ showLoading,
172
+ onError: (error) => {
173
+ if (failCallback) failCallback(error);
174
+
175
+ // Prevent further processing
176
+ return false;
177
+ }
178
+ }
179
+ );
180
+
181
+ if (serviceResult == null) return false;
182
+
183
+ if (!serviceResult.ok) {
184
+ if (failCallback) failCallback(serviceResult);
185
+ return false;
186
+ }
187
+
188
+ if (serviceResult.data == null) {
189
+ if (failCallback) failCallback(this.get('noData')!);
190
+ return false;
191
+ }
192
+
193
+ // Login
194
+ this.userLoginEx(userData, refreshToken, serviceResult.data);
195
+
196
+ // Success callback
197
+ if (failCallback) failCallback(true);
198
+
199
+ return true;
200
+ };
201
+
202
+ // Call API
203
+ const result = await this.api.put<LoginResult>(
204
+ 'Auth/RefreshToken',
205
+ rq,
206
+ payload
207
+ );
208
+ if (result == null) return false;
209
+
210
+ if (!result.ok) {
211
+ if (result.type === 'TokenExpired' && relogin) {
212
+ // Try login
213
+ // Dialog to receive password
214
+ var labels = this.getLabels('reloginTip', 'login');
215
+ this.notifier.prompt(
216
+ labels.reloginTip,
217
+ async (pwd) => {
218
+ if (pwd == null) {
219
+ this.toLoginPage();
220
+ return;
221
+ }
222
+
223
+ // Set password for the action
224
+ rq.pwd = this.encrypt(this.hash(pwd));
225
+
226
+ // Submit again
227
+ const result = await this.api.put<LoginResult>(
228
+ 'Auth/RefreshToken',
229
+ rq,
230
+ payload
231
+ );
232
+
233
+ if (result == null) return;
234
+
235
+ if (result.ok) {
236
+ await success(
237
+ result,
238
+ (loginResult: RefreshTokenResult) => {
239
+ if (loginResult === true) {
240
+ if (callback) callback(true);
241
+ return;
242
+ }
243
+
244
+ const message =
245
+ this.formatRefreshTokenResult(
246
+ loginResult
247
+ );
248
+ if (message) this.notifier.alert(message);
249
+ }
250
+ );
251
+ return;
252
+ }
253
+
254
+ // Popup message
255
+ this.alertResult(result);
256
+ return false;
257
+ },
258
+ labels.login,
259
+ { type: 'password' }
260
+ );
261
+
262
+ // Fake truth to avoid reloading
263
+ return true;
264
+ }
265
+
266
+ if (callback) callback(result);
267
+ return false;
268
+ }
269
+
270
+ return await success(result, callback);
271
+ }
272
+
273
+ /**
274
+ * Service decrypt message
275
+ * @param messageEncrypted Encrypted message
276
+ * @param passphrase Secret passphrase
277
+ * @returns Pure text
278
+ */
279
+ serviceDecrypt(messageEncrypted: string, passphrase?: string) {
280
+ return this.decrypt(
281
+ messageEncrypted,
282
+ passphrase ?? this.servicePassphrase
283
+ );
284
+ }
285
+
286
+ /**
287
+ * Service encrypt message
288
+ * @param message Message
289
+ * @param passphrase Secret passphrase
290
+ * @param iterations Iterations, 1000 times, 1 - 99
291
+ * @returns Result
292
+ */
293
+ serviceEncrypt(message: string, passphrase?: string, iterations?: number) {
294
+ return this.encrypt(
295
+ message,
296
+ passphrase ?? this.servicePassphrase,
297
+ iterations
298
+ );
299
+ }
300
+
301
+ /**
302
+ * Try login
303
+ * @param data Additional data
304
+ * @param showLoading Show loading bar or not
305
+ * @returns Result
306
+ */
307
+ override async tryLogin<D extends object = {}>(
308
+ data?: D,
309
+ showLoading?: boolean
310
+ ) {
311
+ // Reset user state
312
+ const result = await super.tryLogin(data, showLoading);
313
+ if (!result) return false;
314
+
315
+ // Refresh token
316
+ return await this.refreshToken({
317
+ callback: (result) => this.doRefreshTokenResult(result),
318
+ data,
319
+ showLoading,
320
+ relogin: true
321
+ });
322
+ }
323
+
324
+ /**
325
+ * User login extended
326
+ * @param user Core system user
327
+ * @param refreshToken Refresh token
328
+ * @param serviceUser Service user
329
+ */
330
+ userLoginEx(
331
+ user: ISmartERPUser,
332
+ refreshToken: string,
333
+ serviceUser: U
334
+ ): void {
335
+ // Service user login
336
+ this.servicePassphrase =
337
+ this.decrypt(
338
+ serviceUser.serviceDeviceId,
339
+ this.settings.serviceId.toString()
340
+ ) ?? '';
341
+
342
+ // Service user
343
+ this.serviceUser = serviceUser;
344
+
345
+ // Service API token
346
+ this.serviceApi.authorize(this.settings.authScheme, serviceUser.token);
347
+
348
+ // Keep = true, means service could hold the refresh token for long access
349
+ // Trigger Context change and serviceUser is ready then
350
+ super.userLogin(user, refreshToken, true);
351
+ }
352
+ }
package/src/index.ts ADDED
@@ -0,0 +1,77 @@
1
+ export * from './app/CommonApp';
2
+ export * from './app/IServiceAppSettings';
3
+ export * from './app/IServicePage';
4
+ export * from './app/IServiceUser';
5
+ export * from './app/ISmartERPUser';
6
+ export * from './app/Labels';
7
+ export * from './app/ReactApp';
8
+ export * from './app/ServiceApp';
9
+
10
+ export * from './pages/CommonPage';
11
+ export * from './pages/CommonPageProps';
12
+ export * from './pages/DataGridPage';
13
+ export * from './pages/DataGridPageProps';
14
+ export * from './pages/EditPage';
15
+ export * from './pages/FixedListPage';
16
+ export * from './pages/ListPage';
17
+ export * from './pages/ListPageProps';
18
+ export * from './pages/ResponsivePage';
19
+ export * from './pages/ResponsivePageProps';
20
+ export * from './pages/SearchPageProps';
21
+ export * from './pages/TablePage';
22
+ export * from './pages/ViewPage';
23
+
24
+ export * from './texts/DateText';
25
+ export * from './texts/MoneyText';
26
+ export * from './texts/NumberText';
27
+
28
+ export * from './AuditDisplay';
29
+ export * from './BackButton';
30
+ export * from './BridgeCloseButton';
31
+ export * from './ButtonLink';
32
+ export * from './ComboBox';
33
+ export * from './CountdownButton';
34
+ export * from './CustomFabProps';
35
+ export * from './DataGridEx';
36
+ export * from './DataGridRenderers';
37
+ export * from './DialogButton';
38
+ export * from './DnDList';
39
+ export * from './DraggablePaperComponent';
40
+ export * from './EmailInput';
41
+ export * from './FabBox';
42
+ export * from './FlexBox';
43
+ export * from './GridDataFormat';
44
+ export * from './IconButtonLink';
45
+ export * from './InputField';
46
+ export * from './ItemList';
47
+ export * from './ListItemRightIcon';
48
+ export * from './ListMoreDisplay';
49
+ export * from './LoadingButton';
50
+ export * from './MaskInput';
51
+ export * from './MobileListItemRenderer';
52
+ export * from './MoreFab';
53
+ export * from './MUGlobal';
54
+ export * from './NotifierMU';
55
+ export * from './OptionGroup';
56
+ export * from './PList';
57
+ export * from './ProgressCount';
58
+ export * from './PullToRefreshUI';
59
+ export * from './ResponsibleContainer';
60
+ export * from './RLink';
61
+ export * from './ScrollerListEx';
62
+ export * from './ScrollTopFab';
63
+ export * from './SearchBar';
64
+ export * from './SearchField';
65
+ export * from './SearchOptionGroup';
66
+ export * from './SelectBool';
67
+ export * from './SelectEx';
68
+ export * from './ShowDataComparison';
69
+ export * from './Switch';
70
+ export * from './SwitchAnt';
71
+ export * from './TabBox';
72
+ export * from './TableEx';
73
+ export * from './TextFieldEx';
74
+ export * from './Tiplist';
75
+ export * from './TooltipClick';
76
+ export * from './UserAvatar';
77
+ export * from './UserAvatarEditor';
@@ -0,0 +1,128 @@
1
+ import React from 'react';
2
+ import { FabBox } from '../FabBox';
3
+ import { ScrollTopFab } from '../ScrollTopFab';
4
+ import { MUGlobal } from '../MUGlobal';
5
+ import { CommonPageProps } from './CommonPageProps';
6
+ import { MoreFab } from '../MoreFab';
7
+ import { Container, Fab } from '@mui/material';
8
+ import RefreshIcon from '@mui/icons-material/Refresh';
9
+ import { BackButton } from '../BackButton';
10
+ import { Labels } from '../app/Labels';
11
+ import { ReactAppStateDetector } from '../app/ReactApp';
12
+
13
+ /**
14
+ * Default scroll container
15
+ */
16
+ export const CommonPageScrollContainer = global;
17
+
18
+ /**
19
+ * Common page
20
+ * @param props Props
21
+ */
22
+ export function CommonPage(props: CommonPageProps) {
23
+ // Destruct
24
+ const {
25
+ children,
26
+ disableGutters = true,
27
+ fabButtons,
28
+ fabColumnDirection,
29
+ fabPaddingAdjust = 1.5,
30
+ fabSize = 'small',
31
+ maxWidth = false,
32
+ moreActions,
33
+ onRefresh,
34
+ onUpdate,
35
+ onUpdateAll,
36
+ paddings = MUGlobal.pagePaddings,
37
+ scrollContainer,
38
+ supportBack = false,
39
+ targetFields,
40
+ sx = {},
41
+ ...rest
42
+ } = props;
43
+
44
+ // Fab padding
45
+ const fabPadding = MUGlobal.increase(
46
+ MUGlobal.pagePaddings,
47
+ fabPaddingAdjust
48
+ );
49
+
50
+ if (typeof sx === 'object' && sx != null && !Reflect.has(sx, 'padding')) {
51
+ // Set default padding
52
+ Reflect.set(sx, 'padding', paddings);
53
+ }
54
+
55
+ // Labels
56
+ const labels = Labels.CommonPage;
57
+
58
+ // Update
59
+ const update = onUpdateAll
60
+ ? onUpdateAll
61
+ : onUpdate
62
+ ? (authorized?: boolean) => {
63
+ if (authorized == null || authorized) onUpdate();
64
+ }
65
+ : onRefresh
66
+ ? (authorized?: boolean) => {
67
+ if (authorized) onRefresh();
68
+ }
69
+ : undefined;
70
+
71
+ // Return the UI
72
+ return (
73
+ <React.Fragment>
74
+ {update && (
75
+ <ReactAppStateDetector
76
+ targetFields={targetFields}
77
+ update={update}
78
+ />
79
+ )}
80
+ <Container
81
+ disableGutters={disableGutters}
82
+ maxWidth={maxWidth}
83
+ sx={sx}
84
+ id="page-container"
85
+ {...rest}
86
+ >
87
+ <FabBox
88
+ sx={{
89
+ zIndex: 1,
90
+ bottom: (theme) =>
91
+ MUGlobal.updateWithTheme(fabPadding, theme.spacing),
92
+ right: (theme) =>
93
+ MUGlobal.updateWithTheme(fabPadding, theme.spacing)
94
+ }}
95
+ columnDirection={fabColumnDirection}
96
+ >
97
+ {scrollContainer && (
98
+ <ScrollTopFab
99
+ size={fabSize}
100
+ target={scrollContainer}
101
+ title={labels.scrollTop}
102
+ />
103
+ )}
104
+ {fabButtons}
105
+ {onRefresh != null && (
106
+ <Fab
107
+ title={labels.refresh}
108
+ size={fabSize}
109
+ onClick={onRefresh}
110
+ sx={{ display: { xs: 'none', md: 'inherit' } }}
111
+ >
112
+ <RefreshIcon />
113
+ </Fab>
114
+ )}
115
+ <MoreFab
116
+ size={fabSize}
117
+ title={labels.more}
118
+ actions={moreActions}
119
+ />
120
+ {supportBack && (
121
+ <BackButton title={labels.back} size={fabSize} />
122
+ )}
123
+ </FabBox>
124
+ {children}
125
+ </Container>
126
+ </React.Fragment>
127
+ );
128
+ }
@@ -0,0 +1,70 @@
1
+ import { UserKey } from '@etsoo/appscript';
2
+ import { IStateUpdate, ListItemReact } from '@etsoo/react';
3
+ import { ContainerProps } from '@mui/material';
4
+ import { CustomFabSize } from '../CustomFabProps';
5
+
6
+ /**
7
+ * Common page props
8
+ * Default container id is 'pageContainer'
9
+ */
10
+ export interface CommonPageProps extends Omit<ContainerProps, 'id'> {
11
+ /**
12
+ * Fab buttons
13
+ */
14
+ fabButtons?: React.ReactNode;
15
+
16
+ /**
17
+ * Fab size
18
+ */
19
+ fabSize?: CustomFabSize;
20
+
21
+ /**
22
+ * Fab flex column direction, undefined to hide it
23
+ */
24
+ fabColumnDirection?: boolean;
25
+
26
+ /**
27
+ * Fab padding adjust
28
+ */
29
+ fabPaddingAdjust?: number;
30
+
31
+ /**
32
+ * More actions
33
+ */
34
+ moreActions?: ListItemReact[];
35
+
36
+ /**
37
+ * On refresh callback, only when authorized = true
38
+ */
39
+ onRefresh?: () => void | PromiseLike<void>;
40
+
41
+ /**
42
+ * On page update, when authorized = null or true case, may uses onRefresh
43
+ */
44
+ onUpdate?: () => void | PromiseLike<void>;
45
+
46
+ /**
47
+ * On page update, all cases with authorized
48
+ */
49
+ onUpdateAll?: IStateUpdate;
50
+
51
+ /**
52
+ * Paddings
53
+ */
54
+ paddings?: Record<string, string | number>;
55
+
56
+ /**
57
+ * Scroll container
58
+ */
59
+ scrollContainer?: HTMLElement | object;
60
+
61
+ /**
62
+ * Support back click
63
+ */
64
+ supportBack?: boolean;
65
+
66
+ /**
67
+ * State last changed fields
68
+ */
69
+ targetFields?: UserKey[];
70
+ }