@etsoo/materialui 1.1.39 → 1.1.42

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 (42) hide show
  1. package/lib/AuditDisplay.d.ts +5 -5
  2. package/lib/AuditDisplay.js +17 -19
  3. package/lib/BridgeCloseButton.d.ts +2 -2
  4. package/lib/BridgeCloseButton.js +7 -8
  5. package/lib/DataSteps.d.ts +4 -4
  6. package/lib/DataSteps.js +17 -14
  7. package/lib/DataTable.d.ts +33 -0
  8. package/lib/DataTable.js +56 -0
  9. package/lib/ListMoreDisplay.d.ts +5 -5
  10. package/lib/ListMoreDisplay.js +8 -10
  11. package/lib/OptionBool.js +2 -1
  12. package/lib/SelectBool.js +2 -1
  13. package/lib/ShowDataComparison.d.ts +1 -1
  14. package/lib/ShowDataComparison.js +27 -20
  15. package/lib/SwitchAnt.d.ts +3 -3
  16. package/lib/SwitchAnt.js +11 -8
  17. package/lib/SwitchField.d.ts +45 -0
  18. package/lib/SwitchField.js +33 -0
  19. package/lib/Tiplist.js +4 -4
  20. package/lib/UserAvatar.js +7 -8
  21. package/lib/app/ReactApp.d.ts +7 -7
  22. package/lib/app/ReactApp.js +26 -26
  23. package/lib/index.d.ts +2 -0
  24. package/lib/index.js +2 -0
  25. package/lib/pages/ViewPage.d.ts +7 -7
  26. package/lib/pages/ViewPage.js +30 -29
  27. package/package.json +3 -2
  28. package/src/AuditDisplay.tsx +92 -99
  29. package/src/BridgeCloseButton.tsx +48 -50
  30. package/src/DataSteps.tsx +188 -185
  31. package/src/DataTable.tsx +124 -0
  32. package/src/ListMoreDisplay.tsx +184 -188
  33. package/src/OptionBool.tsx +1 -1
  34. package/src/SelectBool.tsx +1 -1
  35. package/src/ShowDataComparison.tsx +88 -76
  36. package/src/SwitchAnt.tsx +82 -78
  37. package/src/SwitchField.tsx +133 -0
  38. package/src/Tiplist.tsx +5 -4
  39. package/src/UserAvatar.tsx +43 -45
  40. package/src/app/ReactApp.ts +485 -489
  41. package/src/index.ts +2 -0
  42. package/src/pages/ViewPage.tsx +272 -277
@@ -1,65 +1,65 @@
1
- import { DataTypes } from '@etsoo/shared';
1
+ import { DataTypes } from "@etsoo/shared";
2
2
  import {
3
- Card,
4
- CardActions,
5
- CardContent,
6
- CardHeader,
7
- CardProps,
8
- CircularProgress
9
- } from '@mui/material';
10
- import React from 'react';
3
+ Card,
4
+ CardActions,
5
+ CardContent,
6
+ CardHeader,
7
+ CardProps,
8
+ CircularProgress
9
+ } from "@mui/material";
10
+ import React from "react";
11
11
  import {
12
- GridData,
13
- GridDataGet,
14
- GridLoadDataProps,
15
- GridLoader,
16
- GridLoaderStates
17
- } from '@etsoo/react';
18
- import { LoadingButton } from './LoadingButton';
19
- import { globalApp } from './app/ReactApp';
12
+ GridData,
13
+ GridDataGet,
14
+ GridLoadDataProps,
15
+ GridLoader,
16
+ GridLoaderStates
17
+ } from "@etsoo/react";
18
+ import { LoadingButton } from "./LoadingButton";
19
+ import { globalApp } from "./app/ReactApp";
20
20
 
21
21
  /**
22
22
  * ListMoreDisplay props
23
23
  */
24
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
- * Batch size to load
31
- */
32
- batchSize?: number;
33
-
34
- /**
35
- * Children to display the list
36
- */
37
- children: (data: T, index: number) => React.ReactNode;
38
-
39
- /**
40
- * Search field template
41
- */
42
- fieldTemplate?: F;
43
-
44
- /**
45
- * Header renderer
46
- */
47
- headerRenderer?: (reset: (data?: GridData) => void) => React.ReactNode;
48
-
49
- /**
50
- * Header title
51
- */
52
- headerTitle?: React.ReactNode;
53
-
54
- /**
55
- * More button label
56
- */
57
- moreLabel?: string;
25
+ T extends object,
26
+ F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
27
+ > extends Omit<CardProps, "children">,
28
+ GridLoader<T> {
29
+ /**
30
+ * Batch size to load
31
+ */
32
+ batchSize?: number;
33
+
34
+ /**
35
+ * Children to display the list
36
+ */
37
+ children: (data: T, index: number) => React.ReactNode;
38
+
39
+ /**
40
+ * Search field template
41
+ */
42
+ fieldTemplate?: F;
43
+
44
+ /**
45
+ * Header renderer
46
+ */
47
+ headerRenderer?: (reset: (data?: GridData) => void) => React.ReactNode;
48
+
49
+ /**
50
+ * Header title
51
+ */
52
+ headerTitle?: React.ReactNode;
53
+
54
+ /**
55
+ * More button label
56
+ */
57
+ moreLabel?: string;
58
58
  }
59
59
 
60
60
  type states<T> = {
61
- items?: T[];
62
- completed: boolean;
61
+ items?: T[];
62
+ completed: boolean;
63
63
  };
64
64
 
65
65
  /**
@@ -68,146 +68,142 @@ type states<T> = {
68
68
  * @returns Component
69
69
  */
70
70
  export function ListMoreDisplay<
71
- T extends object,
72
- F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
71
+ T extends object,
72
+ F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
73
73
  >(props: ListMoreDisplayProps<T, F>) {
74
- // Destruct
75
- const {
76
- batchSize = 6,
77
- children,
78
- defaultOrderBy,
79
- headerRenderer,
80
- autoLoad = headerRenderer == null,
81
- headerTitle,
82
- loadBatchSize,
83
- loadData,
84
- moreLabel = typeof globalApp === 'undefined'
85
- ? undefined
86
- : globalApp.get('more') + '...',
87
- fieldTemplate,
88
- threshold,
89
- ...rest
90
- } = props;
91
-
92
- // Refs
93
- const refs = React.useRef<GridLoaderStates<T>>({
94
- autoLoad,
95
- currentPage: 0,
96
- hasNextPage: true,
97
- isNextPageLoading: false,
98
- orderBy: defaultOrderBy,
99
- batchSize,
100
- loadedItems: 0,
101
- selectedItems: [],
102
- idCache: {}
103
- });
104
- const ref = refs.current;
105
-
106
- // States
107
- const [states, setStates] = React.useReducer(
108
- (currentStates: states<T>, newStates: Partial<states<T>>) => {
109
- return { ...currentStates, ...newStates };
110
- },
111
- { completed: false }
112
- );
113
-
114
- // Load data
115
- const loadDataLocal = async (reset: boolean = false) => {
116
- // Prevent multiple loadings
117
- if (!ref.hasNextPage || ref.isNextPageLoading) return;
118
-
119
- // Update state
120
- ref.isNextPageLoading = true;
121
-
122
- // Parameters
123
- const { currentPage, batchSize, orderBy, orderByAsc, data } = ref;
124
-
125
- const loadProps: GridLoadDataProps = {
126
- currentPage,
127
- batchSize,
128
- orderBy,
129
- orderByAsc,
130
- data
131
- };
132
-
133
- const mergedData = GridDataGet(loadProps, fieldTemplate);
134
-
135
- const items = await loadData(mergedData);
136
- if (items == null || ref.isMounted === false) {
137
- return;
138
- }
139
- ref.isMounted = true;
140
-
141
- const newItems = items.length;
142
- const hasNextPage = newItems >= batchSize;
143
- ref.lastLoadedItems = newItems;
144
- ref.isNextPageLoading = false;
145
- ref.hasNextPage = hasNextPage;
146
-
147
- // Next page
148
- ref.currentPage = currentPage + 1;
149
-
150
- // Update rows
151
- if (states.items == null || reset) {
152
- setStates({ items, completed: !hasNextPage });
153
- } else {
154
- setStates({
155
- items: [...states.items, ...items],
156
- completed: !hasNextPage
157
- });
158
- }
74
+ // Destruct
75
+ const {
76
+ batchSize = 6,
77
+ children,
78
+ defaultOrderBy,
79
+ headerRenderer,
80
+ autoLoad = headerRenderer == null,
81
+ headerTitle,
82
+ loadBatchSize,
83
+ loadData,
84
+ moreLabel = globalApp ? globalApp.get("more") + "..." : undefined,
85
+ fieldTemplate,
86
+ threshold,
87
+ ...rest
88
+ } = props;
89
+
90
+ // Refs
91
+ const refs = React.useRef<GridLoaderStates<T>>({
92
+ autoLoad,
93
+ currentPage: 0,
94
+ hasNextPage: true,
95
+ isNextPageLoading: false,
96
+ orderBy: defaultOrderBy,
97
+ batchSize,
98
+ loadedItems: 0,
99
+ selectedItems: [],
100
+ idCache: {}
101
+ });
102
+ const ref = refs.current;
103
+
104
+ // States
105
+ const [states, setStates] = React.useReducer(
106
+ (currentStates: states<T>, newStates: Partial<states<T>>) => {
107
+ return { ...currentStates, ...newStates };
108
+ },
109
+ { completed: false }
110
+ );
111
+
112
+ // Load data
113
+ const loadDataLocal = async (reset: boolean = false) => {
114
+ // Prevent multiple loadings
115
+ if (!ref.hasNextPage || ref.isNextPageLoading) return;
116
+
117
+ // Update state
118
+ ref.isNextPageLoading = true;
119
+
120
+ // Parameters
121
+ const { currentPage, batchSize, orderBy, orderByAsc, data } = ref;
122
+
123
+ const loadProps: GridLoadDataProps = {
124
+ currentPage,
125
+ batchSize,
126
+ orderBy,
127
+ orderByAsc,
128
+ data
159
129
  };
160
130
 
161
- const reset = (data?: GridData) => {
162
- // Update the form data
163
- ref.data = data;
131
+ const mergedData = GridDataGet(loadProps, fieldTemplate);
132
+
133
+ const items = await loadData(mergedData);
134
+ if (items == null || ref.isMounted === false) {
135
+ return;
136
+ }
137
+ ref.isMounted = true;
138
+
139
+ const newItems = items.length;
140
+ const hasNextPage = newItems >= batchSize;
141
+ ref.lastLoadedItems = newItems;
142
+ ref.isNextPageLoading = false;
143
+ ref.hasNextPage = hasNextPage;
144
+
145
+ // Next page
146
+ ref.currentPage = currentPage + 1;
147
+
148
+ // Update rows
149
+ if (states.items == null || reset) {
150
+ setStates({ items, completed: !hasNextPage });
151
+ } else {
152
+ setStates({
153
+ items: [...states.items, ...items],
154
+ completed: !hasNextPage
155
+ });
156
+ }
157
+ };
158
+
159
+ const reset = (data?: GridData) => {
160
+ // Update the form data
161
+ ref.data = data;
162
+
163
+ // Reset page number
164
+ ref.isNextPageLoading = false;
165
+ ref.currentPage = 0;
166
+ ref.hasNextPage = true;
164
167
 
165
- // Reset page number
166
- ref.isNextPageLoading = false;
167
- ref.currentPage = 0;
168
- ref.hasNextPage = true;
168
+ // Load data
169
+ loadDataLocal(true);
170
+ };
169
171
 
170
- // Load data
171
- loadDataLocal(true);
172
- };
172
+ React.useEffect(() => {
173
+ if (autoLoad) loadDataLocal();
174
+ }, [autoLoad]);
173
175
 
174
- React.useEffect(() => {
175
- if (autoLoad) loadDataLocal();
176
- }, [autoLoad]);
177
-
178
- React.useEffect(() => {
179
- return () => {
180
- ref.isMounted = false;
181
- };
182
- }, []);
183
-
184
- return (
185
- <React.Fragment>
186
- {headerRenderer && headerRenderer(reset)}
187
- <Card {...rest}>
188
- <CardHeader title={headerTitle}></CardHeader>
189
- <CardContent
190
- sx={{
191
- paddingTop: 0,
192
- paddingBottom: states.completed ? 0 : 'inherit'
193
- }}
194
- >
195
- {states.items == null ? (
196
- <CircularProgress size={20} />
197
- ) : (
198
- states.items.map((item, index) => children(item, index))
199
- )}
200
- </CardContent>
201
- {!states.completed && (
202
- <CardActions sx={{ justifyContent: 'flex-end' }}>
203
- <LoadingButton
204
- onClick={async () => await loadDataLocal()}
205
- >
206
- {moreLabel}
207
- </LoadingButton>
208
- </CardActions>
209
- )}
210
- </Card>
211
- </React.Fragment>
212
- );
176
+ React.useEffect(() => {
177
+ return () => {
178
+ ref.isMounted = false;
179
+ };
180
+ }, []);
181
+
182
+ return (
183
+ <React.Fragment>
184
+ {headerRenderer && headerRenderer(reset)}
185
+ <Card {...rest}>
186
+ <CardHeader title={headerTitle}></CardHeader>
187
+ <CardContent
188
+ sx={{
189
+ paddingTop: 0,
190
+ paddingBottom: states.completed ? 0 : "inherit"
191
+ }}
192
+ >
193
+ {states.items == null ? (
194
+ <CircularProgress size={20} />
195
+ ) : (
196
+ states.items.map((item, index) => children(item, index))
197
+ )}
198
+ </CardContent>
199
+ {!states.completed && (
200
+ <CardActions sx={{ justifyContent: "flex-end" }}>
201
+ <LoadingButton onClick={async () => await loadDataLocal()}>
202
+ {moreLabel}
203
+ </LoadingButton>
204
+ </CardActions>
205
+ )}
206
+ </Card>
207
+ </React.Fragment>
208
+ );
213
209
  }
@@ -18,7 +18,7 @@ export type OptionBoolProps = Omit<
18
18
  */
19
19
  export function OptionBool(props: OptionBoolProps) {
20
20
  // Options
21
- const options = globalApp.getBools();
21
+ const options = globalApp?.getBools() ?? [];
22
22
 
23
23
  // Layout
24
24
  return (
@@ -21,7 +21,7 @@ export function SelectBool(props: SelectBoolProps) {
21
21
  const { search = true, autoAddBlankItem = search, ...rest } = props;
22
22
 
23
23
  // Options
24
- const options = globalApp.getBools();
24
+ const options = globalApp?.getBools() ?? [];
25
25
 
26
26
  if (autoAddBlankItem) Utils.addBlankItem(options);
27
27
 
@@ -1,15 +1,15 @@
1
- import { AuditLineChangesDto, IApp } from '@etsoo/appscript';
2
- import { NotificationMessageType } from '@etsoo/notificationbase';
3
- import { Utils } from '@etsoo/shared';
1
+ import { AuditLineChangesDto, IApp } from "@etsoo/appscript";
2
+ import { NotificationMessageType } from "@etsoo/notificationbase";
3
+ import { Utils } from "@etsoo/shared";
4
4
  import {
5
- Table,
6
- TableBody,
7
- TableCell,
8
- TableHead,
9
- TableRow
10
- } from '@mui/material';
11
- import React from 'react';
12
- import { globalApp } from './app/ReactApp';
5
+ Table,
6
+ TableBody,
7
+ TableCell,
8
+ TableHead,
9
+ TableRow
10
+ } from "@mui/material";
11
+ import React from "react";
12
+ import { globalApp } from "./app/ReactApp";
13
13
 
14
14
  /**
15
15
  * Check obj is instance of AuditLineChangesDto
@@ -17,20 +17,20 @@ import { globalApp } from './app/ReactApp';
17
17
  * @returns Result
18
18
  */
19
19
  export function IsAuditLineUpdateData(obj: any): obj is AuditLineChangesDto {
20
- return (
21
- typeof obj === 'object' &&
22
- 'oldData' in obj &&
23
- typeof obj.oldData === 'object' &&
24
- 'newData' in obj &&
25
- typeof obj.newData === 'object'
26
- );
20
+ return (
21
+ typeof obj === "object" &&
22
+ "oldData" in obj &&
23
+ typeof obj.oldData === "object" &&
24
+ "newData" in obj &&
25
+ typeof obj.newData === "object"
26
+ );
27
27
  }
28
28
 
29
29
  // Format value
30
30
  const formatValue = (value: unknown, app: IApp) => {
31
- if (value == null) return '';
32
- if (value instanceof Date) return app.formatDate(value, 'ds');
33
- return `${value}`;
31
+ if (value == null) return "";
32
+ if (value instanceof Date) return app.formatDate(value, "ds");
33
+ return `${value}`;
34
34
  };
35
35
 
36
36
  /**
@@ -41,65 +41,77 @@ const formatValue = (value: unknown, app: IApp) => {
41
41
  * @param equalCheck Equal check for properties
42
42
  */
43
43
  export const ShowDataComparison = (
44
- data: AuditLineChangesDto,
45
- modelTitle?: string,
46
- getLabel?: (field: string) => string,
47
- equalCheck: boolean = true
44
+ data: AuditLineChangesDto,
45
+ modelTitle?: string,
46
+ getLabel?: (field: string) => string,
47
+ equalCheck: boolean = true
48
48
  ) => {
49
- modelTitle ??= globalApp.get<string>('dataComparison');
50
- getLabel ??= (key) => {
51
- return globalApp.get(Utils.formatInitial(key)) ?? key;
52
- };
49
+ // Validate app
50
+ const app = globalApp;
51
+ if (app == null) {
52
+ throw new Error("No globalApp");
53
+ }
53
54
 
54
- const keys = new Set([
55
- ...Object.keys(data.oldData),
56
- ...Object.keys(data.newData)
57
- ]);
55
+ // Labels
56
+ const { dataComparison, field, newValue, oldValue } = app.getLabels(
57
+ "dataComparison",
58
+ "field",
59
+ "newValue",
60
+ "oldValue"
61
+ );
58
62
 
59
- let rows = Array.from(keys).map((field) => ({
60
- field,
61
- oldValue: data.oldData[field],
62
- newValue: data.newData[field]
63
- }));
63
+ modelTitle ??= dataComparison;
64
+ getLabel ??= (key) => {
65
+ return app.get(Utils.formatInitial(key)) ?? key;
66
+ };
64
67
 
65
- if (equalCheck)
66
- rows = rows.filter(
67
- (item) => !Utils.equals(item.oldValue, item.newValue)
68
- );
68
+ const keys = new Set([
69
+ ...Object.keys(data.oldData),
70
+ ...Object.keys(data.newData)
71
+ ]);
69
72
 
70
- const inputs = (
71
- <Table>
72
- <TableHead>
73
- <TableRow>
74
- <TableCell width="18%">{globalApp.get('field')}</TableCell>
75
- <TableCell width="41%" align="right">
76
- {globalApp.get('oldValue')}
77
- </TableCell>
78
- <TableCell width="41%" align="right">
79
- {globalApp.get('newValue')}
80
- </TableCell>
81
- </TableRow>
82
- </TableHead>
83
- <TableBody>
84
- {rows.map((row) => (
85
- <TableRow key={row.field}>
86
- <TableCell>{getLabel!(row.field)}</TableCell>
87
- <TableCell align="right">
88
- {formatValue(row.oldValue, globalApp)}
89
- </TableCell>
90
- <TableCell align="right">
91
- {formatValue(row.newValue, globalApp)}
92
- </TableCell>
93
- </TableRow>
94
- ))}
95
- </TableBody>
96
- </Table>
97
- );
73
+ let rows = Array.from(keys).map((field) => ({
74
+ field,
75
+ oldValue: data.oldData[field],
76
+ newValue: data.newData[field]
77
+ }));
98
78
 
99
- globalApp.notifier.alert(
100
- [undefined, modelTitle],
101
- undefined,
102
- NotificationMessageType.Info,
103
- { fullScreen: globalApp.smDown, inputs }
104
- );
79
+ if (equalCheck)
80
+ rows = rows.filter((item) => !Utils.equals(item.oldValue, item.newValue));
81
+
82
+ const inputs = (
83
+ <Table>
84
+ <TableHead>
85
+ <TableRow>
86
+ <TableCell width="18%">{field}</TableCell>
87
+ <TableCell width="41%" align="right">
88
+ {oldValue}
89
+ </TableCell>
90
+ <TableCell width="41%" align="right">
91
+ {newValue}
92
+ </TableCell>
93
+ </TableRow>
94
+ </TableHead>
95
+ <TableBody>
96
+ {rows.map((row) => (
97
+ <TableRow key={row.field}>
98
+ <TableCell>{getLabel!(row.field)}</TableCell>
99
+ <TableCell align="right">
100
+ {formatValue(row.oldValue, app)}
101
+ </TableCell>
102
+ <TableCell align="right">
103
+ {formatValue(row.newValue, app)}
104
+ </TableCell>
105
+ </TableRow>
106
+ ))}
107
+ </TableBody>
108
+ </Table>
109
+ );
110
+
111
+ app.notifier.alert(
112
+ [undefined, modelTitle],
113
+ undefined,
114
+ NotificationMessageType.Info,
115
+ { fullScreen: app.smDown, inputs }
116
+ );
105
117
  };