@etsoo/react 1.5.80 → 1.5.81

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 (257) hide show
  1. package/README.md +7 -2
  2. package/__tests__/ReactUtils.ts +6 -0
  3. package/lib/{mu → components}/DnDList.d.ts +1 -14
  4. package/lib/{mu → components}/DnDList.js +1 -24
  5. package/lib/components/GridMethodRef.d.ts +11 -0
  6. package/lib/{mu → components}/GridMethodRef.js +0 -0
  7. package/lib/components/ScrollerGrid.d.ts +3 -3
  8. package/lib/components/ScrollerList.d.ts +3 -3
  9. package/lib/index.d.ts +2 -74
  10. package/lib/index.js +2 -75
  11. package/lib/notifier/Notifier.d.ts +2 -3
  12. package/lib/uses/useWindowScroll.d.ts +10 -0
  13. package/lib/uses/useWindowScroll.js +46 -0
  14. package/lib/uses/useWindowSize.js +11 -5
  15. package/package.json +3 -15
  16. package/src/{mu → components}/DnDList.tsx +11 -34
  17. package/src/components/GridMethodRef.ts +12 -0
  18. package/src/components/ScrollerGrid.tsx +3 -3
  19. package/src/components/ScrollerList.tsx +5 -3
  20. package/src/index.ts +2 -78
  21. package/src/notifier/Notifier.ts +2 -3
  22. package/src/uses/useWindowScroll.ts +60 -0
  23. package/src/uses/useWindowSize.ts +14 -5
  24. package/__tests__/mu/ComboBox.tsx +0 -30
  25. package/__tests__/mu/MUGlobalTests.tsx +0 -58
  26. package/__tests__/mu/NotifierMUTests.tsx +0 -213
  27. package/__tests__/mu/SelectEx.tsx +0 -26
  28. package/lib/app/CommonApp.d.ts +0 -39
  29. package/lib/app/CommonApp.js +0 -149
  30. package/lib/app/IServiceAppSettings.d.ts +0 -11
  31. package/lib/app/IServiceAppSettings.js +0 -1
  32. package/lib/app/IServicePage.d.ts +0 -6
  33. package/lib/app/IServicePage.js +0 -1
  34. package/lib/app/IServiceUser.d.ts +0 -14
  35. package/lib/app/IServiceUser.js +0 -1
  36. package/lib/app/ISmartERPUser.d.ts +0 -14
  37. package/lib/app/ISmartERPUser.js +0 -1
  38. package/lib/app/Labels.d.ts +0 -65
  39. package/lib/app/Labels.js +0 -62
  40. package/lib/app/ReactApp.d.ts +0 -194
  41. package/lib/app/ReactApp.js +0 -298
  42. package/lib/app/ServiceApp.d.ts +0 -78
  43. package/lib/app/ServiceApp.js +0 -244
  44. package/lib/components/ShowDataComparison.d.ts +0 -20
  45. package/lib/components/ShowDataComparison.js +0 -60
  46. package/lib/mu/AuditDisplay.d.ts +0 -33
  47. package/lib/mu/AuditDisplay.js +0 -52
  48. package/lib/mu/AutocompleteExtendedProps.d.ts +0 -64
  49. package/lib/mu/AutocompleteExtendedProps.js +0 -1
  50. package/lib/mu/BackButton.d.ts +0 -13
  51. package/lib/mu/BackButton.js +0 -33
  52. package/lib/mu/BridgeCloseButton.d.ts +0 -23
  53. package/lib/mu/BridgeCloseButton.js +0 -32
  54. package/lib/mu/ButtonLink.d.ts +0 -17
  55. package/lib/mu/ButtonLink.js +0 -19
  56. package/lib/mu/ComboBox.d.ts +0 -38
  57. package/lib/mu/ComboBox.js +0 -108
  58. package/lib/mu/CountdownButton.d.ts +0 -23
  59. package/lib/mu/CountdownButton.js +0 -81
  60. package/lib/mu/CustomFabProps.d.ts +0 -27
  61. package/lib/mu/CustomFabProps.js +0 -1
  62. package/lib/mu/DataGridEx.d.ts +0 -96
  63. package/lib/mu/DataGridEx.js +0 -331
  64. package/lib/mu/DataGridRenderers.d.ts +0 -22
  65. package/lib/mu/DataGridRenderers.js +0 -99
  66. package/lib/mu/DialogButton.d.ts +0 -54
  67. package/lib/mu/DialogButton.js +0 -45
  68. package/lib/mu/DraggablePaperComponent.d.ts +0 -8
  69. package/lib/mu/DraggablePaperComponent.js +0 -12
  70. package/lib/mu/EmailInput.d.ts +0 -11
  71. package/lib/mu/EmailInput.js +0 -15
  72. package/lib/mu/FabBox.d.ts +0 -21
  73. package/lib/mu/FabBox.js +0 -31
  74. package/lib/mu/FlexBox.d.ts +0 -14
  75. package/lib/mu/FlexBox.js +0 -18
  76. package/lib/mu/GridDataFormat.d.ts +0 -10
  77. package/lib/mu/GridDataFormat.js +0 -43
  78. package/lib/mu/GridMethodRef.d.ts +0 -11
  79. package/lib/mu/IconButtonLink.d.ts +0 -17
  80. package/lib/mu/IconButtonLink.js +0 -16
  81. package/lib/mu/InputField.d.ts +0 -21
  82. package/lib/mu/InputField.js +0 -39
  83. package/lib/mu/ItemList.d.ts +0 -56
  84. package/lib/mu/ItemList.js +0 -69
  85. package/lib/mu/ListItemRightIcon.d.ts +0 -4
  86. package/lib/mu/ListItemRightIcon.js +0 -8
  87. package/lib/mu/ListMoreDisplay.d.ts +0 -35
  88. package/lib/mu/ListMoreDisplay.js +0 -99
  89. package/lib/mu/LoadingButton.d.ts +0 -16
  90. package/lib/mu/LoadingButton.js +0 -41
  91. package/lib/mu/MUGlobal.d.ts +0 -102
  92. package/lib/mu/MUGlobal.js +0 -184
  93. package/lib/mu/MaskInput.d.ts +0 -34
  94. package/lib/mu/MaskInput.js +0 -43
  95. package/lib/mu/MobileListItemRenderer.d.ts +0 -17
  96. package/lib/mu/MobileListItemRenderer.js +0 -35
  97. package/lib/mu/MoreFab.d.ts +0 -45
  98. package/lib/mu/MoreFab.js +0 -95
  99. package/lib/mu/NotifierMU.d.ts +0 -47
  100. package/lib/mu/NotifierMU.js +0 -387
  101. package/lib/mu/NotifierPromptProps.d.ts +0 -22
  102. package/lib/mu/NotifierPromptProps.js +0 -1
  103. package/lib/mu/OptionGroup.d.ts +0 -58
  104. package/lib/mu/OptionGroup.js +0 -81
  105. package/lib/mu/PList.d.ts +0 -15
  106. package/lib/mu/PList.js +0 -12
  107. package/lib/mu/ProgressCount.d.ts +0 -44
  108. package/lib/mu/ProgressCount.js +0 -79
  109. package/lib/mu/PullToRefreshUI.d.ts +0 -9
  110. package/lib/mu/PullToRefreshUI.js +0 -18
  111. package/lib/mu/RLink.d.ts +0 -14
  112. package/lib/mu/RLink.js +0 -37
  113. package/lib/mu/ResponsibleContainer.d.ts +0 -89
  114. package/lib/mu/ResponsibleContainer.js +0 -159
  115. package/lib/mu/ScrollTopFab.d.ts +0 -7
  116. package/lib/mu/ScrollTopFab.js +0 -25
  117. package/lib/mu/ScrollerListEx.d.ts +0 -81
  118. package/lib/mu/ScrollerListEx.js +0 -167
  119. package/lib/mu/SearchBar.d.ts +0 -29
  120. package/lib/mu/SearchBar.js +0 -262
  121. package/lib/mu/SearchField.d.ts +0 -21
  122. package/lib/mu/SearchField.js +0 -39
  123. package/lib/mu/SearchOptionGroup.d.ts +0 -9
  124. package/lib/mu/SearchOptionGroup.js +0 -14
  125. package/lib/mu/SelectBool.d.ts +0 -13
  126. package/lib/mu/SelectBool.js +0 -22
  127. package/lib/mu/SelectEx.d.ts +0 -50
  128. package/lib/mu/SelectEx.js +0 -156
  129. package/lib/mu/Switch.d.ts +0 -29
  130. package/lib/mu/Switch.js +0 -34
  131. package/lib/mu/SwitchAnt.d.ts +0 -25
  132. package/lib/mu/SwitchAnt.js +0 -40
  133. package/lib/mu/TabBox.d.ts +0 -54
  134. package/lib/mu/TabBox.js +0 -31
  135. package/lib/mu/TableEx.d.ts +0 -66
  136. package/lib/mu/TableEx.js +0 -271
  137. package/lib/mu/TextFieldEx.d.ts +0 -101
  138. package/lib/mu/TextFieldEx.js +0 -127
  139. package/lib/mu/Tiplist.d.ts +0 -18
  140. package/lib/mu/Tiplist.js +0 -158
  141. package/lib/mu/TooltipClick.d.ts +0 -15
  142. package/lib/mu/TooltipClick.js +0 -40
  143. package/lib/mu/UserAvatar.d.ts +0 -24
  144. package/lib/mu/UserAvatar.js +0 -25
  145. package/lib/mu/UserAvatarEditor.d.ts +0 -53
  146. package/lib/mu/UserAvatarEditor.js +0 -129
  147. package/lib/mu/pages/CommonPage.d.ts +0 -11
  148. package/lib/mu/pages/CommonPage.js +0 -60
  149. package/lib/mu/pages/CommonPageProps.d.ts +0 -60
  150. package/lib/mu/pages/CommonPageProps.js +0 -1
  151. package/lib/mu/pages/DataGridPage.d.ts +0 -9
  152. package/lib/mu/pages/DataGridPage.js +0 -81
  153. package/lib/mu/pages/DataGridPageProps.d.ts +0 -17
  154. package/lib/mu/pages/DataGridPageProps.js +0 -1
  155. package/lib/mu/pages/EditPage.d.ts +0 -33
  156. package/lib/mu/pages/EditPage.js +0 -29
  157. package/lib/mu/pages/FixedListPage.d.ts +0 -15
  158. package/lib/mu/pages/FixedListPage.js +0 -72
  159. package/lib/mu/pages/ListPage.d.ts +0 -9
  160. package/lib/mu/pages/ListPage.js +0 -51
  161. package/lib/mu/pages/ListPageProps.d.ts +0 -7
  162. package/lib/mu/pages/ListPageProps.js +0 -1
  163. package/lib/mu/pages/ResponsivePage.d.ts +0 -9
  164. package/lib/mu/pages/ResponsivePage.js +0 -45
  165. package/lib/mu/pages/ResponsivePageProps.d.ts +0 -39
  166. package/lib/mu/pages/ResponsivePageProps.js +0 -1
  167. package/lib/mu/pages/SearchPageProps.d.ts +0 -30
  168. package/lib/mu/pages/SearchPageProps.js +0 -1
  169. package/lib/mu/pages/TablePage.d.ts +0 -9
  170. package/lib/mu/pages/TablePage.js +0 -71
  171. package/lib/mu/pages/TablePageProps.d.ts +0 -7
  172. package/lib/mu/pages/TablePageProps.js +0 -1
  173. package/lib/mu/pages/ViewPage.d.ts +0 -66
  174. package/lib/mu/pages/ViewPage.js +0 -105
  175. package/lib/mu/texts/DateText.d.ts +0 -34
  176. package/lib/mu/texts/DateText.js +0 -25
  177. package/lib/mu/texts/MoneyText.d.ts +0 -21
  178. package/lib/mu/texts/MoneyText.js +0 -14
  179. package/lib/mu/texts/NumberText.d.ts +0 -25
  180. package/lib/mu/texts/NumberText.js +0 -14
  181. package/src/app/CommonApp.ts +0 -225
  182. package/src/app/IServiceAppSettings.ts +0 -13
  183. package/src/app/IServicePage.ts +0 -6
  184. package/src/app/IServiceUser.ts +0 -17
  185. package/src/app/ISmartERPUser.ts +0 -16
  186. package/src/app/Labels.ts +0 -77
  187. package/src/app/ReactApp.ts +0 -500
  188. package/src/app/ServiceApp.ts +0 -353
  189. package/src/components/ShowDataComparison.tsx +0 -108
  190. package/src/mu/AuditDisplay.tsx +0 -117
  191. package/src/mu/AutocompleteExtendedProps.ts +0 -83
  192. package/src/mu/BackButton.tsx +0 -55
  193. package/src/mu/BridgeCloseButton.tsx +0 -69
  194. package/src/mu/ButtonLink.tsx +0 -32
  195. package/src/mu/ComboBox.tsx +0 -251
  196. package/src/mu/CountdownButton.tsx +0 -119
  197. package/src/mu/CustomFabProps.ts +0 -32
  198. package/src/mu/DataGridEx.tsx +0 -712
  199. package/src/mu/DataGridRenderers.tsx +0 -140
  200. package/src/mu/DialogButton.tsx +0 -163
  201. package/src/mu/DraggablePaperComponent.tsx +0 -19
  202. package/src/mu/EmailInput.tsx +0 -24
  203. package/src/mu/FabBox.tsx +0 -51
  204. package/src/mu/FlexBox.tsx +0 -20
  205. package/src/mu/GridDataFormat.tsx +0 -77
  206. package/src/mu/GridMethodRef.ts +0 -12
  207. package/src/mu/IconButtonLink.tsx +0 -29
  208. package/src/mu/InputField.tsx +0 -82
  209. package/src/mu/ItemList.tsx +0 -204
  210. package/src/mu/ListItemRightIcon.tsx +0 -9
  211. package/src/mu/ListMoreDisplay.tsx +0 -205
  212. package/src/mu/LoadingButton.tsx +0 -75
  213. package/src/mu/MUGlobal.ts +0 -220
  214. package/src/mu/MaskInput.tsx +0 -107
  215. package/src/mu/MobileListItemRenderer.tsx +0 -79
  216. package/src/mu/MoreFab.tsx +0 -211
  217. package/src/mu/NotifierMU.tsx +0 -654
  218. package/src/mu/NotifierPromptProps.ts +0 -26
  219. package/src/mu/OptionGroup.tsx +0 -223
  220. package/src/mu/PList.tsx +0 -27
  221. package/src/mu/ProgressCount.tsx +0 -166
  222. package/src/mu/PullToRefreshUI.tsx +0 -21
  223. package/src/mu/RLink.tsx +0 -64
  224. package/src/mu/ResponsibleContainer.tsx +0 -394
  225. package/src/mu/ScrollTopFab.tsx +0 -34
  226. package/src/mu/ScrollerListEx.tsx +0 -387
  227. package/src/mu/SearchBar.tsx +0 -398
  228. package/src/mu/SearchField.tsx +0 -82
  229. package/src/mu/SearchOptionGroup.tsx +0 -31
  230. package/src/mu/SelectBool.tsx +0 -33
  231. package/src/mu/SelectEx.tsx +0 -290
  232. package/src/mu/Switch.tsx +0 -94
  233. package/src/mu/SwitchAnt.tsx +0 -95
  234. package/src/mu/TabBox.tsx +0 -118
  235. package/src/mu/TableEx.tsx +0 -560
  236. package/src/mu/TextFieldEx.tsx +0 -250
  237. package/src/mu/Tiplist.tsx +0 -304
  238. package/src/mu/TooltipClick.tsx +0 -84
  239. package/src/mu/UserAvatar.tsx +0 -64
  240. package/src/mu/UserAvatarEditor.tsx +0 -287
  241. package/src/mu/pages/CommonPage.tsx +0 -128
  242. package/src/mu/pages/CommonPageProps.ts +0 -71
  243. package/src/mu/pages/DataGridPage.tsx +0 -137
  244. package/src/mu/pages/DataGridPageProps.ts +0 -24
  245. package/src/mu/pages/EditPage.tsx +0 -114
  246. package/src/mu/pages/FixedListPage.tsx +0 -135
  247. package/src/mu/pages/ListPage.tsx +0 -87
  248. package/src/mu/pages/ListPageProps.ts +0 -12
  249. package/src/mu/pages/ResponsivePage.tsx +0 -68
  250. package/src/mu/pages/ResponsivePageProps.ts +0 -57
  251. package/src/mu/pages/SearchPageProps.ts +0 -39
  252. package/src/mu/pages/TablePage.tsx +0 -120
  253. package/src/mu/pages/TablePageProps.ts +0 -12
  254. package/src/mu/pages/ViewPage.tsx +0 -285
  255. package/src/mu/texts/DateText.tsx +0 -74
  256. package/src/mu/texts/MoneyText.tsx +0 -49
  257. package/src/mu/texts/NumberText.tsx +0 -40
@@ -1,204 +0,0 @@
1
- import React from 'react';
2
- import {
3
- Dialog,
4
- DialogTitle,
5
- List,
6
- ListItemText,
7
- DialogContent,
8
- Button,
9
- ListItemButton
10
- } from '@mui/material';
11
- import {
12
- DataTypes,
13
- IdDefaultType,
14
- LabelDefaultType,
15
- ListType
16
- } from '@etsoo/shared';
17
-
18
- /**
19
- * Item list properties
20
- */
21
- export interface ItemListProps<
22
- T extends object,
23
- D extends DataTypes.Keys<T>,
24
- L extends DataTypes.Keys<T, string>
25
- > {
26
- /**
27
- * Style class name
28
- */
29
- className?: string;
30
-
31
- /**
32
- * Id field name
33
- */
34
- idField?: D;
35
-
36
- /**
37
- * Label field name or callback
38
- */
39
- labelField?: L | ((item: T) => string);
40
-
41
- /**
42
- * Button icon
43
- */
44
- icon?: React.ReactNode;
45
-
46
- /**
47
- * Button color
48
- */
49
- color?: 'inherit' | 'primary' | 'secondary';
50
-
51
- /**
52
- * Close event
53
- */
54
- onClose?(item: T, changed: boolean): void;
55
-
56
- /**
57
- * Current selected language
58
- */
59
- selectedValue?: T[D];
60
-
61
- /**
62
- * Button size
63
- */
64
- size?: 'small' | 'medium' | 'large';
65
-
66
- /**
67
- * Title
68
- */
69
- title?: string;
70
-
71
- /**
72
- * Items
73
- */
74
- items: T[];
75
-
76
- /**
77
- * Button variant
78
- */
79
- variant?: 'text' | 'outlined' | 'contained';
80
- }
81
-
82
- /**
83
- * Item list component
84
- * @param props Properties
85
- */
86
- export function ItemList<
87
- T extends object = ListType,
88
- D extends DataTypes.Keys<T> = IdDefaultType<T>,
89
- L extends DataTypes.Keys<T, string> = LabelDefaultType<T>
90
- >(props: ItemListProps<T, D, L>) {
91
- // properties destructure
92
- const {
93
- className,
94
- color = 'primary',
95
- items,
96
- idField = 'id' as D,
97
- labelField = 'label' as L,
98
- icon,
99
- onClose,
100
- selectedValue,
101
- size = 'medium',
102
- title,
103
- variant = 'outlined'
104
- } = props;
105
-
106
- // Get label
107
- const getLabel = (item: T): string => {
108
- if (typeof labelField === 'function') {
109
- return labelField(item);
110
- } else {
111
- return DataTypes.convert(item[labelField], 'string') ?? '';
112
- }
113
- };
114
-
115
- // Dialog open or not state
116
- const [open, setOpen] = React.useState(false);
117
-
118
- // Default state
119
- const defaultItem =
120
- items.find((item) => item[idField] === selectedValue) ?? items[0];
121
-
122
- // Current item
123
- const [currentItem, setCurrentItem] = React.useState(defaultItem);
124
-
125
- // Click handler
126
- const clickHandler = () => {
127
- // More than one language
128
- if (items.length < 2) {
129
- return;
130
- }
131
-
132
- // Open the dialog
133
- setOpen(true);
134
- };
135
-
136
- // Close handler
137
- const closeHandler = () => {
138
- if (!open) return;
139
-
140
- // Close the dialog
141
- setOpen(false);
142
-
143
- // Emit close event
144
- if (onClose) {
145
- onClose(currentItem, false);
146
- }
147
- };
148
-
149
- // Close item handler
150
- const closeItemHandler = (item: any) => {
151
- // Update the current item
152
- setCurrentItem(item);
153
-
154
- // Close the dialog
155
- setOpen(false);
156
-
157
- // Emit close event
158
- if (onClose) {
159
- onClose(item, true);
160
- }
161
- };
162
-
163
- return (
164
- <>
165
- <Button
166
- className={className}
167
- variant={variant}
168
- startIcon={icon}
169
- color={color}
170
- size={size}
171
- onClick={clickHandler}
172
- >
173
- {getLabel(currentItem)}
174
- </Button>
175
- <Dialog
176
- aria-labelledby="dialog-title"
177
- open={open}
178
- onClose={closeHandler}
179
- >
180
- <DialogTitle sx={{ minWidth: '200px' }} id="dialog-title">
181
- {title || ''}
182
- </DialogTitle>
183
- <DialogContent>
184
- <List>
185
- {items.map((item) => {
186
- const id = item[idField];
187
- return (
188
- <ListItemButton
189
- key={id as unknown as React.Key}
190
- disabled={id === currentItem[idField]}
191
- onClick={() => closeItemHandler(item)}
192
- >
193
- <ListItemText>
194
- {getLabel(item)}
195
- </ListItemText>
196
- </ListItemButton>
197
- );
198
- })}
199
- </List>
200
- </DialogContent>
201
- </Dialog>
202
- </>
203
- );
204
- }
@@ -1,9 +0,0 @@
1
- import { ListItemIcon, styled } from '@mui/material';
2
-
3
- /**
4
- * List item right icon component
5
- */
6
- export const ListItemRightIcon = styled(ListItemIcon)(({ theme }) => ({
7
- minWidth: '20px!important',
8
- paddingLeft: theme.spacing(2)
9
- }));
@@ -1,205 +0,0 @@
1
- import { DataTypes } from '@etsoo/shared';
2
- import {
3
- Card,
4
- CardActions,
5
- CardContent,
6
- CardHeader,
7
- CardProps,
8
- CircularProgress
9
- } from '@mui/material';
10
- import React from 'react';
11
- import { globalApp } from '../app/ReactApp';
12
- import {
13
- GridData,
14
- GridDataGet,
15
- GridLoadDataProps,
16
- GridLoader,
17
- GridLoaderStates
18
- } from '../components/GridLoader';
19
- import { LoadingButton } from './LoadingButton';
20
-
21
- /**
22
- * ListMoreDisplay props
23
- */
24
- export interface ListMoreDisplayProps<
25
- T extends object,
26
- F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
27
- > extends Omit<CardProps, 'children'>,
28
- GridLoader<T> {
29
- /**
30
- * Children to display the list
31
- */
32
- children: (data: T, index: number) => React.ReactNode;
33
-
34
- /**
35
- * Search field template
36
- */
37
- fieldTemplate?: F;
38
-
39
- /**
40
- * Header renderer
41
- */
42
- headerRenderer?: (reset: (data?: GridData) => void) => React.ReactNode;
43
-
44
- /**
45
- * Header title
46
- */
47
- headerTitle?: React.ReactNode;
48
-
49
- /**
50
- * More button label
51
- */
52
- moreLabel?: string;
53
- }
54
-
55
- type states<T> = {
56
- items?: T[];
57
- completed: boolean;
58
- };
59
-
60
- /**
61
- * ListMoreDisplay
62
- * @param props Props
63
- * @returns Component
64
- */
65
- export function ListMoreDisplay<
66
- T extends object,
67
- F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
68
- >(props: ListMoreDisplayProps<T, F>) {
69
- // Destruct
70
- const {
71
- children,
72
- defaultOrderBy,
73
- headerRenderer,
74
- autoLoad = headerRenderer == null,
75
- headerTitle,
76
- loadBatchSize,
77
- loadData,
78
- moreLabel = typeof globalApp === 'undefined'
79
- ? undefined
80
- : globalApp.get('more') + '...',
81
- fieldTemplate,
82
- threshold,
83
- ...rest
84
- } = props;
85
-
86
- // Refs
87
- const refs = React.useRef<GridLoaderStates<T>>({
88
- autoLoad,
89
- currentPage: 0,
90
- hasNextPage: true,
91
- isNextPageLoading: false,
92
- orderBy: defaultOrderBy,
93
- batchSize: 10,
94
- loadedItems: 0,
95
- selectedItems: []
96
- });
97
- const ref = refs.current;
98
-
99
- // States
100
- const [states, setStates] = React.useReducer(
101
- (currentStates: states<T>, newStates: Partial<states<T>>) => {
102
- return { ...currentStates, ...newStates };
103
- },
104
- { completed: false }
105
- );
106
-
107
- // Load data
108
- const loadDataLocal = async (reset: boolean = false) => {
109
- // Prevent multiple loadings
110
- if (!ref.hasNextPage || ref.isNextPageLoading) return;
111
-
112
- // Update state
113
- ref.isNextPageLoading = true;
114
-
115
- // Parameters
116
- const { currentPage, batchSize, orderBy, orderByAsc, data } = ref;
117
-
118
- const loadProps: GridLoadDataProps = {
119
- currentPage,
120
- batchSize,
121
- orderBy,
122
- orderByAsc,
123
- data
124
- };
125
-
126
- const mergedData = GridDataGet(loadProps, fieldTemplate);
127
-
128
- const items = await loadData(mergedData);
129
- if (items == null || ref.isMounted === false) {
130
- return;
131
- }
132
- ref.isMounted = true;
133
-
134
- const newItems = items.length;
135
- const hasNextPage = newItems >= batchSize;
136
- ref.lastLoadedItems = newItems;
137
- ref.isNextPageLoading = false;
138
- ref.hasNextPage = hasNextPage;
139
-
140
- // Next page
141
- ref.currentPage = currentPage + 1;
142
-
143
- // Update rows
144
- if (states.items == null || reset)
145
- setStates({ items, completed: !hasNextPage });
146
- else
147
- setStates({
148
- items: [...states.items, ...items],
149
- completed: !hasNextPage
150
- });
151
- };
152
-
153
- const reset = (data?: GridData) => {
154
- // Update the form data
155
- ref.data = data;
156
-
157
- // Reset page number
158
- ref.isNextPageLoading = false;
159
- ref.currentPage = 0;
160
- ref.hasNextPage = true;
161
-
162
- // Load data
163
- loadDataLocal(true);
164
- };
165
-
166
- React.useEffect(() => {
167
- if (autoLoad) loadDataLocal();
168
- }, [autoLoad]);
169
-
170
- React.useEffect(() => {
171
- return () => {
172
- ref.isMounted = false;
173
- };
174
- }, []);
175
-
176
- return (
177
- <React.Fragment>
178
- {headerRenderer && headerRenderer(reset)}
179
- <Card {...rest}>
180
- <CardHeader title={headerTitle}></CardHeader>
181
- <CardContent
182
- sx={{
183
- paddingTop: 0,
184
- paddingBottom: states.completed ? 0 : 'inherit'
185
- }}
186
- >
187
- {states.items == null ? (
188
- <CircularProgress size={20} />
189
- ) : (
190
- states.items.map((item, index) => children(item, index))
191
- )}
192
- </CardContent>
193
- {!states.completed && (
194
- <CardActions sx={{ justifyContent: 'flex-end' }}>
195
- <LoadingButton
196
- onClick={async () => await loadDataLocal()}
197
- >
198
- {moreLabel}
199
- </LoadingButton>
200
- </CardActions>
201
- )}
202
- </Card>
203
- </React.Fragment>
204
- );
205
- }
@@ -1,75 +0,0 @@
1
- import {
2
- Button,
3
- ButtonProps,
4
- CircularProgress,
5
- CircularProgressProps
6
- } from '@mui/material';
7
- import React from 'react';
8
-
9
- /**
10
- * Loading button props
11
- */
12
- export type LoadingButtonProps = ButtonProps & {
13
- /**
14
- * Loading icon props
15
- */
16
- loadingIconProps?: CircularProgressProps;
17
- };
18
-
19
- /**
20
- * Loading button
21
- * @param props Props
22
- */
23
- export function LoadingButton(props: LoadingButtonProps) {
24
- // Destruct
25
- const { endIcon, loadingIconProps = {}, onClick, ...rest } = props;
26
-
27
- // Default size
28
- loadingIconProps.size ??= 12;
29
-
30
- // State
31
- // https://stackoverflow.com/questions/55265255/react-usestate-hook-event-handler-using-initial-state
32
- const [loading, setLoading] = React.useState(false);
33
-
34
- // Icon
35
- const localEndIcon = loading ? (
36
- <CircularProgress {...loadingIconProps} />
37
- ) : (
38
- endIcon
39
- );
40
-
41
- // Check if the component is mounted
42
- const isMounted = React.useRef(true);
43
-
44
- React.useEffect(() => {
45
- return () => {
46
- isMounted.current = false;
47
- };
48
- }, []);
49
-
50
- // Layout
51
- return (
52
- <Button
53
- disabled={loading}
54
- endIcon={localEndIcon}
55
- onClick={async (event) => {
56
- if (onClick) {
57
- // Update state
58
- setLoading(true);
59
-
60
- // https://stackoverflow.com/questions/38508420/how-to-know-if-a-function-is-async
61
- // const AsyncFunction = (async () => {}).constructor;
62
- // onClick instanceof AsyncFunction
63
- await onClick(event);
64
-
65
- // Warning: Can't perform a React state update on an unmounted component
66
- // It's necessary to check the component is mounted now
67
- if (isMounted.current) {
68
- setLoading(false);
69
- }
70
- }
71
- }}
72
- {...rest}
73
- />
74
- );
75
- }
@@ -1,220 +0,0 @@
1
- import { NumberUtils } from '@etsoo/shared';
2
- import { Breakpoint, ListItemButtonProps, Theme } from '@mui/material';
3
- import { RLink } from './RLink';
4
-
5
- /**
6
- * Mouse event handler with data
7
- */
8
- export type MouseEventWithDataHandler<T> = (
9
- event: React.MouseEvent<HTMLDivElement>,
10
- data: T
11
- ) => void;
12
-
13
- /**
14
- * MUGlobal for global configurations
15
- */
16
- export class MUGlobal {
17
- /**
18
- * Search field shrink
19
- */
20
- static searchFieldShrink: boolean = true;
21
-
22
- /**
23
- * Search field size
24
- */
25
- static searchFieldSize: 'small' | 'medium' = 'small';
26
-
27
- /**
28
- * Search field variant
29
- */
30
- static searchFieldVariant: 'standard' | 'filled' | 'outlined' = 'outlined';
31
-
32
- /**
33
- * Input field shrink
34
- */
35
- static inputFieldShrink: boolean = true;
36
-
37
- /**
38
- * Input field size
39
- */
40
- static inputFieldSize: 'small' | 'medium' = 'medium';
41
-
42
- /**
43
- * Input field variant
44
- */
45
- static inputFieldVariant: 'standard' | 'filled' | 'outlined' = 'outlined';
46
-
47
- /**
48
- * TextField variant
49
- */
50
- static textFieldVariant: 'standard' | 'filled' | 'outlined' = 'filled';
51
-
52
- /**
53
- * Page default paddings
54
- */
55
- static pagePaddings = { xs: 2, sm: 3 };
56
-
57
- /**
58
- * Get menu item props
59
- * @param path Current path
60
- * @param href Item's href
61
- * @returns Props
62
- */
63
- static getMenuItem(path: string, href: string) {
64
- let selected = false;
65
-
66
- if (path === href) {
67
- // Exact match, most common case
68
- selected = true;
69
- } else if (href.endsWith('*')) {
70
- href = href.slice(0, -1);
71
- selected = path.startsWith(href);
72
- } else if (href.endsWith('/all')) {
73
- selected = path.startsWith(href.slice(0, -3));
74
- }
75
-
76
- return {
77
- component: RLink,
78
- selected,
79
- href,
80
- sx: {
81
- ...(selected && {
82
- '.MuiListItemIcon-root': {
83
- color: (theme) => theme.palette.primary.main
84
- }
85
- })
86
- }
87
- } as ListItemButtonProps;
88
- }
89
-
90
- /**
91
- * Update object number properties with half of it
92
- * @param input Input object
93
- * @returns Updated object
94
- */
95
- static half(input: object) {
96
- const newObj = { ...input };
97
- Object.entries(newObj).forEach(([key, value]) => {
98
- if (typeof value === 'number') {
99
- Reflect.set(newObj, key, value / 2.0);
100
- }
101
- });
102
- return newObj;
103
- }
104
-
105
- /**
106
- * Reverse object number properties, like 5 to -5
107
- * @param input Input object
108
- * @returns Updated object
109
- */
110
- static reverse(input: object) {
111
- const newObj = { ...input };
112
- Object.entries(newObj).forEach(([key, value]) => {
113
- if (typeof value === 'number') {
114
- Reflect.set(newObj, key, -value);
115
- }
116
- });
117
- return newObj;
118
- }
119
-
120
- /**
121
- * Update object number properties with adjustment
122
- * @param input Input object
123
- * @param adjust Adjust value or new size object
124
- * @param field Specific field
125
- * @returns Updated object
126
- */
127
- static increase(input: object, adjust: number | object, field?: string) {
128
- const newObj = { ...input };
129
- Object.entries(newObj).forEach(([key, value]) => {
130
- if (typeof value === 'number') {
131
- if (field == null || field === key) {
132
- const adjustValue =
133
- typeof adjust === 'number'
134
- ? adjust
135
- : Reflect.get(adjust, key);
136
- if (adjustValue == null || typeof adjustValue !== 'number')
137
- return;
138
-
139
- Reflect.set(newObj, key, value + adjustValue);
140
- }
141
- }
142
- });
143
- return newObj;
144
- }
145
-
146
- /**
147
- * Adjust size with theme update
148
- * @param size Base size
149
- * @param adjust Adjustment
150
- * @param updateFunc Theme update function
151
- * @returns Updated object
152
- */
153
- static adjustWithTheme(
154
- size: number,
155
- adjust: object,
156
- updateFunc: (value: number) => string
157
- ) {
158
- const newObj = { ...adjust };
159
- Object.entries(newObj).forEach(([key, value]) => {
160
- if (typeof value === 'number') {
161
- const newValue = NumberUtils.parseWithUnit(updateFunc(value));
162
- if (newValue != null) {
163
- Reflect.set(
164
- newObj,
165
- key,
166
- `${size - newValue[0]}${newValue[1]}`
167
- );
168
- }
169
- }
170
- });
171
- return newObj;
172
- }
173
-
174
- /**
175
- * Break points defined
176
- */
177
- static breakpoints = ['xs', 'sm', 'md', 'lg', 'xl'] as const;
178
-
179
- /**
180
- * Get multple medias theme space
181
- * Responsive values and Breakpoints as an object
182
- * xs = theme.breakpoints.up('xs')
183
- * https://mui.com/system/basics/
184
- * @param spaces Spaces
185
- * @param theme Theme
186
- * @returns Result
187
- */
188
- static getSpace(spaces: object, theme: Theme) {
189
- const start = this.breakpoints.length - 1;
190
- for (let i = start; i >= 0; i--) {
191
- const key = this.breakpoints[i];
192
- const value = Reflect.get(spaces, key);
193
- if (typeof value === 'number') {
194
- const mediaRaw = theme.breakpoints.up(key as Breakpoint);
195
- const mediaQuery = mediaRaw.substring(mediaRaw.indexOf('('));
196
- if (window.matchMedia(mediaQuery).matches) {
197
- return parseInt(theme.spacing(value), 10);
198
- }
199
- }
200
- }
201
-
202
- return 0;
203
- }
204
-
205
- /**
206
- * Update object number properties with theme
207
- * @param input Input object
208
- * @param updateFunc Theme update function
209
- * @returns Updated object
210
- */
211
- static updateWithTheme(input: {}, updateFunc: (value: number) => string) {
212
- const newObj = { ...input };
213
- Object.entries(newObj).forEach(([key, value]) => {
214
- if (typeof value === 'number') {
215
- Reflect.set(newObj, key, updateFunc(value));
216
- }
217
- });
218
- return newObj;
219
- }
220
- }