@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,126 @@
1
+ import {
2
+ GridDataGet,
3
+ GridLoadDataProps,
4
+ useCombinedRefs,
5
+ useDimensions
6
+ } from '@etsoo/react';
7
+ import { DataTypes, IdDefaultType } from '@etsoo/shared';
8
+ import { Box, Stack } from '@mui/material';
9
+ import React from 'react';
10
+ import { MUGlobal } from '../MUGlobal';
11
+ import { SearchBar } from '../SearchBar';
12
+ import { TableEx, TableExMethodRef, TableExMinWidth } from '../TableEx';
13
+ import { CommonPage, CommonPageScrollContainer } from './CommonPage';
14
+ import { TablePageProps } from './TablePageProps';
15
+
16
+ /**
17
+ * Table page
18
+ * @param props Props
19
+ * @returns Component
20
+ */
21
+ export function TablePage<
22
+ T extends object,
23
+ F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate,
24
+ D extends DataTypes.Keys<T> = IdDefaultType<T>
25
+ >(props: TablePageProps<T, F, D>) {
26
+ // Destruct
27
+ const {
28
+ columns,
29
+ fields,
30
+ fieldTemplate,
31
+ loadData,
32
+ mRef,
33
+ sizeReadyMiliseconds = 0,
34
+ pageProps = {},
35
+ ...rest
36
+ } = props;
37
+
38
+ pageProps.paddings ??= MUGlobal.pagePaddings;
39
+
40
+ // States
41
+ const [states] = React.useState<{
42
+ data?: FormData;
43
+ ref?: TableExMethodRef<T>;
44
+ }>({});
45
+
46
+ const refs = useCombinedRefs(
47
+ mRef,
48
+ (ref: TableExMethodRef<T> | null | undefined) => {
49
+ if (ref == null) return;
50
+
51
+ const first = states.ref == null;
52
+
53
+ states.ref = ref;
54
+
55
+ if (first) reset();
56
+ }
57
+ );
58
+
59
+ const reset = () => {
60
+ if (states.data == null || states.ref == null) return;
61
+ states.ref.reset({ data: states.data });
62
+ };
63
+
64
+ // On submit callback
65
+ const onSubmit = (data: FormData, _reset: boolean) => {
66
+ states.data = data;
67
+ reset();
68
+ };
69
+
70
+ const localLoadData = (props: GridLoadDataProps) => {
71
+ const data = GridDataGet(props, fieldTemplate);
72
+ return loadData(data);
73
+ };
74
+
75
+ // Total width
76
+ const totalWidth = React.useMemo(
77
+ () =>
78
+ columns.reduce((previousValue, { width, minWidth }) => {
79
+ return previousValue + (width ?? minWidth ?? TableExMinWidth);
80
+ }, 0),
81
+ [columns]
82
+ );
83
+
84
+ // Watch container
85
+ const { dimensions } = useDimensions(1, undefined, sizeReadyMiliseconds);
86
+ const rect = dimensions[0][2];
87
+ const list = React.useMemo(() => {
88
+ if (rect != null && rect.height > 50 && rect.width >= totalWidth) {
89
+ let maxHeight =
90
+ document.documentElement.clientHeight -
91
+ (rect.top + rect.height + 1);
92
+
93
+ const style = window.getComputedStyle(dimensions[0][1]!);
94
+ const paddingBottom = parseFloat(style.paddingBottom);
95
+ if (!isNaN(paddingBottom)) maxHeight -= paddingBottom;
96
+
97
+ return (
98
+ <TableEx<T, D>
99
+ autoLoad={false}
100
+ columns={columns}
101
+ loadData={localLoadData}
102
+ maxHeight={maxHeight}
103
+ mRef={refs}
104
+ {...rest}
105
+ />
106
+ );
107
+ }
108
+ }, [rect]);
109
+
110
+ // Layout
111
+ return (
112
+ <CommonPage {...pageProps} scrollContainer={CommonPageScrollContainer}>
113
+ <Stack>
114
+ <Box
115
+ ref={dimensions[0][0]}
116
+ sx={{
117
+ paddingBottom: pageProps.paddings
118
+ }}
119
+ >
120
+ <SearchBar fields={fields} onSubmit={onSubmit} />
121
+ </Box>
122
+ {list}
123
+ </Stack>
124
+ </CommonPage>
125
+ );
126
+ }
@@ -0,0 +1,12 @@
1
+ import { DataTypes } from '@etsoo/shared';
2
+ import { TableExProps } from '../TableEx';
3
+ import { SearchPageProps } from './SearchPageProps';
4
+
5
+ /**
6
+ * Table page props
7
+ */
8
+ export type TablePageProps<
9
+ T extends object,
10
+ F extends DataTypes.BasicTemplate,
11
+ D extends DataTypes.Keys<T>
12
+ > = SearchPageProps<T, F> & Omit<TableExProps<T, D>, 'loadData'>;
@@ -0,0 +1,282 @@
1
+ import { GridColumnRenderProps, GridDataType } from '@etsoo/react';
2
+ import { DataTypes, Utils } from '@etsoo/shared';
3
+ import {
4
+ Grid,
5
+ GridProps,
6
+ LinearProgress,
7
+ Stack,
8
+ Typography
9
+ } from '@mui/material';
10
+ import React from 'react';
11
+ import { Labels } from '../app/Labels';
12
+ import { globalApp } from '../app/ReactApp';
13
+ import { GridDataFormat } from '../GridDataFormat';
14
+ import { MUGlobal } from '../MUGlobal';
15
+ import { PullToRefreshUI } from '../PullToRefreshUI';
16
+ import { CommonPage } from './CommonPage';
17
+ import { CommonPageProps } from './CommonPageProps';
18
+
19
+ /**
20
+ * View page display field
21
+ */
22
+ export interface ViewPageField<T extends object> extends GridProps {
23
+ /**
24
+ * Data field
25
+ */
26
+ data: (string & keyof T) | ((item: T) => React.ReactNode);
27
+
28
+ /**
29
+ * Data type
30
+ */
31
+ dataType?: GridDataType;
32
+
33
+ /**
34
+ * Label field
35
+ */
36
+ label?: string | (() => React.ReactNode);
37
+
38
+ /**
39
+ * Display as single row
40
+ */
41
+ singleRow?: boolean;
42
+
43
+ /**
44
+ * Render props
45
+ */
46
+ renderProps?: GridColumnRenderProps;
47
+ }
48
+
49
+ type ViewPageFieldType<T extends object> =
50
+ | (string & keyof T)
51
+ | [string & keyof T, GridDataType, GridColumnRenderProps?]
52
+ | ViewPageField<T>;
53
+
54
+ /**
55
+ * View page props
56
+ */
57
+ export interface ViewPageProps<T extends DataTypes.StringRecord>
58
+ extends Omit<CommonPageProps, 'children'> {
59
+ /**
60
+ * Actions
61
+ */
62
+ actions?:
63
+ | React.ReactNode
64
+ | ((data: T, refresh: () => PromiseLike<void>) => React.ReactNode);
65
+
66
+ /**
67
+ * Children
68
+ */
69
+ children?:
70
+ | React.ReactNode
71
+ | ((data: T, refresh: () => PromiseLike<void>) => React.ReactNode);
72
+
73
+ /**
74
+ * Fields to display
75
+ */
76
+ fields: ViewPageFieldType<T>[];
77
+
78
+ /**
79
+ * Load data
80
+ */
81
+ loadData: () => PromiseLike<T | undefined>;
82
+
83
+ /**
84
+ * Pull to refresh data
85
+ */
86
+ pullToRefresh?: boolean;
87
+
88
+ /**
89
+ * Support refresh
90
+ */
91
+ supportRefresh?: boolean;
92
+ }
93
+
94
+ function formatItemData(fieldData: unknown): string | undefined {
95
+ if (fieldData == null) return undefined;
96
+ if (typeof fieldData === 'string') return fieldData;
97
+ if (fieldData instanceof Date) return globalApp.formatDate(fieldData, 'd');
98
+ return `${fieldData}`;
99
+ }
100
+
101
+ function getItemField<T extends object>(
102
+ field: ViewPageFieldType<T>,
103
+ data: T
104
+ ): [React.ReactNode, React.ReactNode, GridProps] {
105
+ // Item data and label
106
+ let itemData: React.ReactNode,
107
+ itemLabel: React.ReactNode,
108
+ gridProps: GridProps = {};
109
+
110
+ let xs = 6;
111
+
112
+ if (Array.isArray(field)) {
113
+ const [fieldData, fieldType, renderProps] = field;
114
+ itemData = GridDataFormat(data[fieldData], fieldType, renderProps);
115
+ itemLabel = globalApp.get<string>(fieldData) ?? fieldData;
116
+ } else if (typeof field === 'object') {
117
+ // Destruct
118
+ const {
119
+ data: fieldData,
120
+ dataType,
121
+ label: fieldLabel,
122
+ renderProps,
123
+ singleRow,
124
+ ...rest
125
+ } = field;
126
+
127
+ gridProps = {
128
+ ...rest,
129
+ ...(singleRow && { xs: 12, sm: 12, md: 12, lg: 12, xl: 12 })
130
+ };
131
+
132
+ if (singleRow === false) xs = 12;
133
+
134
+ // Field data
135
+ if (typeof fieldData === 'function') itemData = fieldData(data);
136
+ else if (dataType == null) itemData = formatItemData(data[fieldData]);
137
+ else itemData = GridDataFormat(data[fieldData], dataType, renderProps);
138
+
139
+ // Field label
140
+ itemLabel =
141
+ typeof fieldLabel === 'function'
142
+ ? fieldLabel()
143
+ : globalApp.get<string>(
144
+ fieldLabel ??
145
+ (typeof fieldData === 'string' ? fieldData : 'noData')
146
+ ) ?? fieldLabel;
147
+ } else {
148
+ itemData = formatItemData(data[field]);
149
+ itemLabel = globalApp.get<string>(field) ?? field;
150
+ }
151
+
152
+ return [
153
+ itemData,
154
+ itemLabel,
155
+ { xs, sm: 6, md: 6, lg: 4, xl: 3, ...gridProps }
156
+ ];
157
+ }
158
+
159
+ /**
160
+ * View page
161
+ * @param props Props
162
+ */
163
+ export function ViewPage<T extends DataTypes.StringRecord>(
164
+ props: ViewPageProps<T>
165
+ ) {
166
+ // Destruct
167
+ const {
168
+ actions,
169
+ children,
170
+ fields,
171
+ loadData,
172
+ paddings = MUGlobal.pagePaddings,
173
+ supportRefresh = true,
174
+ fabColumnDirection = true,
175
+ supportBack = true,
176
+ pullToRefresh = true,
177
+ ...rest
178
+ } = props;
179
+
180
+ // Data
181
+ const [data, setData] = React.useState<T>();
182
+
183
+ // Labels
184
+ const labels = Labels.CommonPage;
185
+
186
+ // Container
187
+ const pullContainer = '#page-container';
188
+
189
+ // Load data
190
+ const refresh = async () => {
191
+ const result = await loadData();
192
+ if (result == null) return;
193
+ setData(result);
194
+ };
195
+
196
+ return (
197
+ <CommonPage
198
+ paddings={paddings}
199
+ onRefresh={supportRefresh ? refresh : undefined}
200
+ onUpdate={supportRefresh ? undefined : refresh}
201
+ {...rest}
202
+ scrollContainer={globalThis}
203
+ fabColumnDirection={fabColumnDirection}
204
+ supportBack={supportBack}
205
+ >
206
+ {data == null ? (
207
+ <LinearProgress />
208
+ ) : (
209
+ <React.Fragment>
210
+ <Grid
211
+ container
212
+ justifyContent="left"
213
+ spacing={paddings}
214
+ className="ET-ViewPage"
215
+ sx={{
216
+ '.MuiTypography-subtitle2': {
217
+ fontWeight: 'bold'
218
+ }
219
+ }}
220
+ >
221
+ {fields.map((field, index) => {
222
+ // Get data
223
+ const [itemData, itemLabel, gridProps] =
224
+ getItemField(field, data);
225
+
226
+ // Some callback function may return '' instead of undefined
227
+ if (itemData == null || itemData === '')
228
+ return undefined;
229
+
230
+ // Layout
231
+ return (
232
+ <Grid item {...gridProps} key={index}>
233
+ <Typography
234
+ variant="caption"
235
+ component="div"
236
+ >
237
+ {itemLabel}:
238
+ </Typography>
239
+ <Typography variant="subtitle2">
240
+ {itemData}
241
+ </Typography>
242
+ </Grid>
243
+ );
244
+ })}
245
+ </Grid>
246
+ {actions != null && (
247
+ <Stack
248
+ className="ET-ViewPage-Actions"
249
+ direction="row"
250
+ width="100%"
251
+ flexWrap="wrap"
252
+ justifyContent="flex-end"
253
+ paddingTop={paddings}
254
+ paddingBottom={paddings}
255
+ gap={paddings}
256
+ >
257
+ {Utils.getResult(actions, data, refresh)}
258
+ </Stack>
259
+ )}
260
+ {Utils.getResult(children, data, refresh)}
261
+ {pullToRefresh && (
262
+ <PullToRefreshUI
263
+ mainElement={pullContainer}
264
+ triggerElement={pullContainer}
265
+ instructionsPullToRefresh={labels.pullToRefresh}
266
+ instructionsReleaseToRefresh={
267
+ labels.releaseToRefresh
268
+ }
269
+ instructionsRefreshing={labels.refreshing}
270
+ onRefresh={refresh}
271
+ shouldPullToRefresh={() => {
272
+ const container =
273
+ document.querySelector(pullContainer);
274
+ return !container?.scrollTop;
275
+ }}
276
+ />
277
+ )}
278
+ </React.Fragment>
279
+ )}
280
+ </CommonPage>
281
+ );
282
+ }
@@ -0,0 +1,74 @@
1
+ import { DateUtils } from '@etsoo/shared';
2
+ import { Typography, TypographyProps } from '@mui/material';
3
+ import React from 'react';
4
+
5
+ /**
6
+ * Date text props
7
+ */
8
+ export interface DateTextProps extends TypographyProps {
9
+ /**
10
+ * Locale
11
+ */
12
+ locale?: string;
13
+
14
+ /**
15
+ * Near days to show in error color
16
+ */
17
+ nearDays?: number;
18
+
19
+ /**
20
+ * Options
21
+ */
22
+ options?: DateUtils.FormatOptions;
23
+
24
+ /**
25
+ * Time zone
26
+ */
27
+ timeZone?: string;
28
+
29
+ /**
30
+ * Value to display
31
+ */
32
+ value?: Date | string;
33
+ }
34
+
35
+ /**
36
+ * Date text
37
+ * @param props Props
38
+ * @returns Component
39
+ */
40
+ export function DateText(props: DateTextProps) {
41
+ // Destruct
42
+ const {
43
+ nearDays,
44
+ locale = 'lookup',
45
+ options,
46
+ timeZone,
47
+ value,
48
+ ...rest
49
+ } = props;
50
+
51
+ // Format date
52
+ const date = DateUtils.parse(value);
53
+
54
+ // Formatted value
55
+ const localValue =
56
+ date == null
57
+ ? undefined
58
+ : DateUtils.format(value, locale, options, timeZone);
59
+
60
+ if (
61
+ nearDays != null &&
62
+ date != null &&
63
+ Math.abs(new Date().substract(date).totalDays) <= nearDays
64
+ ) {
65
+ rest.color = (theme) => theme.palette.error.main;
66
+ }
67
+
68
+ // Layout
69
+ return (
70
+ <Typography component="span" fontSize="inherit" {...rest}>
71
+ {localValue}
72
+ </Typography>
73
+ );
74
+ }
@@ -0,0 +1,49 @@
1
+ import { NumberUtils } from '@etsoo/shared';
2
+ import { Typography } from '@mui/material';
3
+ import React from 'react';
4
+ import { NumberTextProps } from './NumberText';
5
+
6
+ /**
7
+ * Money text props
8
+ */
9
+ export interface MoneyTextProps extends NumberTextProps {
10
+ /**
11
+ * Currency, USD for US dollar
12
+ */
13
+ currency?: string;
14
+
15
+ /**
16
+ * Is integer number
17
+ */
18
+ isInteger?: boolean;
19
+ }
20
+
21
+ /**
22
+ * Money text
23
+ * @param props Props
24
+ * @returns Component
25
+ */
26
+ export function MoneyText(props: MoneyTextProps) {
27
+ // Destruct
28
+ const {
29
+ currency,
30
+ isInteger = false,
31
+ locale,
32
+ options = {},
33
+ value,
34
+ ...rest
35
+ } = props;
36
+
37
+ // Layout
38
+ return (
39
+ <Typography component="span" fontSize="inherit" {...rest}>
40
+ {NumberUtils.formatMoney(
41
+ value,
42
+ currency,
43
+ locale,
44
+ isInteger,
45
+ options
46
+ )}
47
+ </Typography>
48
+ );
49
+ }
@@ -0,0 +1,40 @@
1
+ import { NumberUtils } from '@etsoo/shared';
2
+ import { Typography, TypographyProps } from '@mui/material';
3
+ import React from 'react';
4
+
5
+ /**
6
+ * Number text props
7
+ */
8
+ export interface NumberTextProps extends TypographyProps {
9
+ /**
10
+ * Locale
11
+ */
12
+ locale?: string | string[];
13
+
14
+ /**
15
+ * Options
16
+ */
17
+ options?: Intl.NumberFormatOptions;
18
+
19
+ /**
20
+ * Value
21
+ */
22
+ value?: number | bigint;
23
+ }
24
+
25
+ /**
26
+ * Number text
27
+ * @param props Props
28
+ * @returns Component
29
+ */
30
+ export function NumberText(props: NumberTextProps) {
31
+ // Destruct
32
+ const { locale, options = {}, value, ...rest } = props;
33
+
34
+ // Layout
35
+ return (
36
+ <Typography component="span" fontSize="inherit" {...rest}>
37
+ {NumberUtils.format(value, locale, options)}
38
+ </Typography>
39
+ );
40
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ /* Visit https://aka.ms/tsconfig.json to read more about this file */
4
+ "target": "ES2019",
5
+ "module": "ESNext",
6
+ "allowJs": true,
7
+ "moduleResolution": "node",
8
+ "isolatedModules": true,
9
+ "outDir": "./lib",
10
+ "noEmit": false,
11
+ "declaration": true,
12
+ "strict": true,
13
+ "esModuleInterop": true,
14
+ "skipLibCheck": true,
15
+ "jsx": "react",
16
+ "forceConsistentCasingInFileNames": true
17
+ },
18
+ "include": ["src"]
19
+ }