@etsoo/react 1.3.97 → 1.4.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.
- package/lib/mu/DnDList.d.ts +3 -3
- package/lib/mu/DnDList.js +39 -8
- package/lib/mu/NotifierMU.js +23 -6
- package/lib/mu/pages/EditPage.js +2 -2
- package/package.json +9 -9
- package/src/mu/DnDList.tsx +60 -11
- package/src/mu/NotifierMU.tsx +36 -5
- package/src/mu/pages/EditPage.tsx +2 -2
package/lib/mu/DnDList.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
|
6
6
|
/**
|
|
7
7
|
* Item renderer
|
|
8
8
|
*/
|
|
9
|
-
children: (item: D, index: number,
|
|
9
|
+
children: (item: D, index: number, deleteItem: (index: number) => void, editItem: (newItem: D, indexOrLabel: number | string) => void) => React.ReactNode;
|
|
10
10
|
/**
|
|
11
11
|
* List container component
|
|
12
12
|
* https://javascript.plainenglish.io/building-a-polymorphic-component-in-react-and-typescript-d9f236950af4
|
|
@@ -19,7 +19,7 @@ export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
|
19
19
|
/**
|
|
20
20
|
* Get list item style callback
|
|
21
21
|
*/
|
|
22
|
-
getItemStyle?: (isDragging: boolean) => CSSProperties;
|
|
22
|
+
getItemStyle?: (isDragging: boolean, index: number) => CSSProperties;
|
|
23
23
|
/**
|
|
24
24
|
* Get list style callback
|
|
25
25
|
*/
|
|
@@ -35,7 +35,7 @@ export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
|
35
35
|
/**
|
|
36
36
|
* Top and bottom sides renderer
|
|
37
37
|
*/
|
|
38
|
-
sideRenderer?: (top: boolean,
|
|
38
|
+
sideRenderer?: (top: boolean, addItem: (item: D) => boolean, addItems: (items: D[]) => number) => React.ReactNode;
|
|
39
39
|
/**
|
|
40
40
|
* Name for hidden form input
|
|
41
41
|
*/
|
package/lib/mu/DnDList.js
CHANGED
|
@@ -27,8 +27,8 @@ export function DnDList(props) {
|
|
|
27
27
|
// Update the state
|
|
28
28
|
setItems(newItems);
|
|
29
29
|
};
|
|
30
|
-
// Add
|
|
31
|
-
const
|
|
30
|
+
// Add item
|
|
31
|
+
const addItem = (newItem) => {
|
|
32
32
|
// Existence check
|
|
33
33
|
if (items.some((item) => item[labelField] == newItem[labelField])) {
|
|
34
34
|
return false;
|
|
@@ -39,8 +39,39 @@ export function DnDList(props) {
|
|
|
39
39
|
setItems(newItems);
|
|
40
40
|
return true;
|
|
41
41
|
};
|
|
42
|
-
//
|
|
43
|
-
const
|
|
42
|
+
// Edit item
|
|
43
|
+
const editItem = (newItem, indexOrLabel) => {
|
|
44
|
+
const index = typeof indexOrLabel === 'number'
|
|
45
|
+
? indexOrLabel
|
|
46
|
+
: items.findIndex((item) => DataTypes.convert(item[labelField], 'string') ==
|
|
47
|
+
indexOrLabel);
|
|
48
|
+
if (index === -1)
|
|
49
|
+
return;
|
|
50
|
+
// Clone
|
|
51
|
+
const newItems = [...items];
|
|
52
|
+
// Remove the item
|
|
53
|
+
newItems.splice(index, 1, newItem);
|
|
54
|
+
// Update the state
|
|
55
|
+
setItems(newItems);
|
|
56
|
+
};
|
|
57
|
+
// Add items
|
|
58
|
+
const addItems = (inputItems) => {
|
|
59
|
+
// Clone
|
|
60
|
+
const newItems = [...items];
|
|
61
|
+
// Insert items
|
|
62
|
+
inputItems.forEach((newItem) => {
|
|
63
|
+
// Existence check
|
|
64
|
+
if (newItems.some((item) => item[labelField] == newItem[labelField])) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
newItems.push(newItem);
|
|
68
|
+
});
|
|
69
|
+
// Update the state
|
|
70
|
+
setItems(newItems);
|
|
71
|
+
return newItems.length - items.length;
|
|
72
|
+
};
|
|
73
|
+
// Delete item
|
|
74
|
+
const deleteItem = (index) => {
|
|
44
75
|
// Clone
|
|
45
76
|
const newItems = [...items];
|
|
46
77
|
// Remove the item
|
|
@@ -53,7 +84,7 @@ export function DnDList(props) {
|
|
|
53
84
|
}, [name]);
|
|
54
85
|
// Layout
|
|
55
86
|
return (React.createElement(React.Fragment, null,
|
|
56
|
-
sideRenderer && sideRenderer(true,
|
|
87
|
+
sideRenderer && sideRenderer(true, addItem, addItems),
|
|
57
88
|
React.createElement(Component, { ...componentProps },
|
|
58
89
|
React.createElement(DragDropContext, { onDragEnd: onDragEnd },
|
|
59
90
|
React.createElement(Droppable, { droppableId: name }, (provided, snapshot) => (React.createElement("div", { ...provided.droppableProps, ref: provided.innerRef, style: getListStyle(snapshot.isDraggingOver) },
|
|
@@ -63,12 +94,12 @@ export function DnDList(props) {
|
|
|
63
94
|
if (id == null)
|
|
64
95
|
return;
|
|
65
96
|
return (React.createElement(Draggable, { key: id, draggableId: id, index: index }, (provided, snapshot) => (React.createElement("div", { ref: provided.innerRef, ...provided.draggableProps, ...provided.dragHandleProps, style: {
|
|
66
|
-
...getItemStyle(snapshot.isDragging),
|
|
97
|
+
...getItemStyle(snapshot.isDragging, index),
|
|
67
98
|
...provided
|
|
68
99
|
.draggableProps
|
|
69
100
|
.style
|
|
70
|
-
} }, children(item, index,
|
|
101
|
+
} }, children(item, index, deleteItem, editItem)))));
|
|
71
102
|
}),
|
|
72
103
|
provided.placeholder))))),
|
|
73
|
-
sideRenderer && sideRenderer(false,
|
|
104
|
+
sideRenderer && sideRenderer(false, addItem, addItems)));
|
|
74
105
|
}
|
package/lib/mu/NotifierMU.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NotificationAlign, NotificationMessageType, NotificationType } from '@etsoo/notificationbase';
|
|
2
|
-
import { Alert, AlertTitle, Backdrop, Box, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Fade, Slider, Snackbar, styled, Switch, TextField } from '@mui/material';
|
|
2
|
+
import { Alert, AlertTitle, Backdrop, Box, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Fade, Slider, Snackbar, styled, Switch, TextField, Typography } from '@mui/material';
|
|
3
3
|
import { Error, Info, Help, Warning, Done } from '@mui/icons-material';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { Labels } from '../app/Labels';
|
|
@@ -120,14 +120,21 @@ export class NotificationMU extends NotificationReact {
|
|
|
120
120
|
const labels = Labels.NotificationMU;
|
|
121
121
|
const title = (_a = this.title) !== null && _a !== void 0 ? _a : labels.promptTitle;
|
|
122
122
|
const { cancelLabel = labels.promptCancel, okLabel = labels.promptOK, inputs, type, fullScreen, fullWidth = true, maxWidth, primaryButton, ...rest } = (_b = this.inputProps) !== null && _b !== void 0 ? _b : {};
|
|
123
|
+
const inputRef = React.createRef();
|
|
124
|
+
const errorRef = React.createRef();
|
|
125
|
+
const setError = (error) => {
|
|
126
|
+
if (errorRef.current == null)
|
|
127
|
+
return;
|
|
128
|
+
errorRef.current.innerText = error !== null && error !== void 0 ? error : '';
|
|
129
|
+
};
|
|
123
130
|
const handleSubmit = async (event) => {
|
|
124
131
|
// Result
|
|
125
132
|
let result = undefined;
|
|
133
|
+
const input = inputRef.current;
|
|
126
134
|
if (this.onReturn) {
|
|
127
135
|
// Inputs case, no HTMLForm set to value, set the current form
|
|
128
136
|
if (inputs && value == null)
|
|
129
137
|
value = event.currentTarget.form;
|
|
130
|
-
const input = inputRef.current;
|
|
131
138
|
if (input) {
|
|
132
139
|
if (type === 'date') {
|
|
133
140
|
const dateValue = input.valueAsDate;
|
|
@@ -165,12 +172,21 @@ export class NotificationMU extends NotificationReact {
|
|
|
165
172
|
// Get the value
|
|
166
173
|
// returns false to prevent default dismiss
|
|
167
174
|
const v = await result;
|
|
168
|
-
if (v === false)
|
|
175
|
+
if (v === false) {
|
|
176
|
+
input === null || input === void 0 ? void 0 : input.focus();
|
|
169
177
|
return;
|
|
178
|
+
}
|
|
179
|
+
if (Array.isArray(v)) {
|
|
180
|
+
if (!v[0]) {
|
|
181
|
+
const error = v[1];
|
|
182
|
+
setError(error);
|
|
183
|
+
input === null || input === void 0 ? void 0 : input.focus();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
170
187
|
this.dismiss();
|
|
171
188
|
};
|
|
172
189
|
let localInputs;
|
|
173
|
-
let inputRef = React.createRef();
|
|
174
190
|
let value = undefined;
|
|
175
191
|
if (inputs == null) {
|
|
176
192
|
if (type === 'switch') {
|
|
@@ -180,7 +196,7 @@ export class NotificationMU extends NotificationReact {
|
|
|
180
196
|
localInputs = React.createElement(Slider, { onChange: (_e, v) => (value = v) });
|
|
181
197
|
}
|
|
182
198
|
else {
|
|
183
|
-
localInputs = (React.createElement(TextField, { inputRef: inputRef, autoFocus: true, margin: "dense", fullWidth: true, type: type, required: true, ...rest }));
|
|
199
|
+
localInputs = (React.createElement(TextField, { inputRef: inputRef, onChange: () => setError(undefined), autoFocus: true, margin: "dense", fullWidth: true, type: type, required: true, ...rest }));
|
|
184
200
|
}
|
|
185
201
|
}
|
|
186
202
|
else {
|
|
@@ -193,7 +209,8 @@ export class NotificationMU extends NotificationReact {
|
|
|
193
209
|
React.createElement("span", { className: "dialogTitle" }, title)),
|
|
194
210
|
React.createElement(DialogContent, null,
|
|
195
211
|
React.createElement(DialogContentText, null, this.content),
|
|
196
|
-
localInputs
|
|
212
|
+
localInputs,
|
|
213
|
+
React.createElement(Typography, { variant: "caption", display: "block", ref: errorRef, color: (theme) => theme.palette.error.main })),
|
|
197
214
|
React.createElement(DialogActions, null,
|
|
198
215
|
React.createElement(Button, { color: "secondary", onClick: () => {
|
|
199
216
|
if (this.onReturn)
|
package/lib/mu/pages/EditPage.js
CHANGED
|
@@ -3,7 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import { Labels } from '../../app/Labels';
|
|
4
4
|
import { MUGlobal } from '../MUGlobal';
|
|
5
5
|
import { CommonPage, CommonPageScrollContainer } from './CommonPage';
|
|
6
|
-
import
|
|
6
|
+
import SaveIcon from '@mui/icons-material/Save';
|
|
7
7
|
/**
|
|
8
8
|
* Edit page
|
|
9
9
|
* @param props Props
|
|
@@ -21,5 +21,5 @@ export function EditPage(props) {
|
|
|
21
21
|
bottom: (theme) => MUGlobal.updateWithTheme(paddings, theme.spacing),
|
|
22
22
|
paddingTop: paddings
|
|
23
23
|
} },
|
|
24
|
-
React.createElement(Button, { variant: "contained", type: "submit", fullWidth: true, startIcon: React.createElement(
|
|
24
|
+
React.createElement(Button, { variant: "contained", type: "submit", fullWidth: true, startIcon: React.createElement(SaveIcon, null) }, labels.save)))));
|
|
25
25
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "TypeScript ReactJs framework",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"@emotion/react": "^11.7.1",
|
|
51
51
|
"@emotion/style": "^0.8.0",
|
|
52
52
|
"@emotion/styled": "^11.6.0",
|
|
53
|
-
"@etsoo/appscript": "^1.2.
|
|
54
|
-
"@etsoo/notificationbase": "^1.0.
|
|
53
|
+
"@etsoo/appscript": "^1.2.12",
|
|
54
|
+
"@etsoo/notificationbase": "^1.0.96",
|
|
55
55
|
"@etsoo/shared": "^1.0.97",
|
|
56
56
|
"@mui/icons-material": "^5.2.5",
|
|
57
57
|
"@mui/material": "^5.2.6",
|
|
@@ -76,12 +76,12 @@
|
|
|
76
76
|
"react-window": "^1.8.6"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
|
-
"@babel/cli": "^7.16.
|
|
80
|
-
"@babel/core": "^7.16.
|
|
81
|
-
"@babel/plugin-transform-runtime": "^7.16.
|
|
82
|
-
"@babel/preset-env": "^7.16.
|
|
83
|
-
"@babel/runtime-corejs3": "^7.16.
|
|
84
|
-
"@types/jest": "^27.0
|
|
79
|
+
"@babel/cli": "^7.16.7",
|
|
80
|
+
"@babel/core": "^7.16.7",
|
|
81
|
+
"@babel/plugin-transform-runtime": "^7.16.7",
|
|
82
|
+
"@babel/preset-env": "^7.16.7",
|
|
83
|
+
"@babel/runtime-corejs3": "^7.16.7",
|
|
84
|
+
"@types/jest": "^27.4.0",
|
|
85
85
|
"@types/react-test-renderer": "^17.0.1",
|
|
86
86
|
"@typescript-eslint/eslint-plugin": "^5.8.1",
|
|
87
87
|
"@typescript-eslint/parser": "^5.8.1",
|
package/src/mu/DnDList.tsx
CHANGED
|
@@ -17,7 +17,8 @@ export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
|
17
17
|
children: (
|
|
18
18
|
item: D,
|
|
19
19
|
index: number,
|
|
20
|
-
|
|
20
|
+
deleteItem: (index: number) => void,
|
|
21
|
+
editItem: (newItem: D, indexOrLabel: number | string) => void
|
|
21
22
|
) => React.ReactNode;
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -34,7 +35,7 @@ export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
|
34
35
|
/**
|
|
35
36
|
* Get list item style callback
|
|
36
37
|
*/
|
|
37
|
-
getItemStyle?: (isDragging: boolean) => CSSProperties;
|
|
38
|
+
getItemStyle?: (isDragging: boolean, index: number) => CSSProperties;
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
41
|
* Get list style callback
|
|
@@ -56,7 +57,8 @@ export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
|
56
57
|
*/
|
|
57
58
|
sideRenderer?: (
|
|
58
59
|
top: boolean,
|
|
59
|
-
|
|
60
|
+
addItem: (item: D) => boolean,
|
|
61
|
+
addItems: (items: D[]) => number
|
|
60
62
|
) => React.ReactNode;
|
|
61
63
|
|
|
62
64
|
/**
|
|
@@ -111,8 +113,8 @@ export function DnDList<
|
|
|
111
113
|
setItems(newItems);
|
|
112
114
|
};
|
|
113
115
|
|
|
114
|
-
// Add
|
|
115
|
-
const
|
|
116
|
+
// Add item
|
|
117
|
+
const addItem = (newItem: D) => {
|
|
116
118
|
// Existence check
|
|
117
119
|
if (items.some((item) => item[labelField] == newItem[labelField])) {
|
|
118
120
|
return false;
|
|
@@ -127,8 +129,53 @@ export function DnDList<
|
|
|
127
129
|
return true;
|
|
128
130
|
};
|
|
129
131
|
|
|
130
|
-
//
|
|
131
|
-
const
|
|
132
|
+
// Edit item
|
|
133
|
+
const editItem = (newItem: D, indexOrLabel: number | string) => {
|
|
134
|
+
const index =
|
|
135
|
+
typeof indexOrLabel === 'number'
|
|
136
|
+
? indexOrLabel
|
|
137
|
+
: items.findIndex(
|
|
138
|
+
(item) =>
|
|
139
|
+
DataTypes.convert(item[labelField], 'string') ==
|
|
140
|
+
indexOrLabel
|
|
141
|
+
);
|
|
142
|
+
if (index === -1) return;
|
|
143
|
+
|
|
144
|
+
// Clone
|
|
145
|
+
const newItems = [...items];
|
|
146
|
+
|
|
147
|
+
// Remove the item
|
|
148
|
+
newItems.splice(index, 1, newItem);
|
|
149
|
+
|
|
150
|
+
// Update the state
|
|
151
|
+
setItems(newItems);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
// Add items
|
|
155
|
+
const addItems = (inputItems: D[]) => {
|
|
156
|
+
// Clone
|
|
157
|
+
const newItems = [...items];
|
|
158
|
+
|
|
159
|
+
// Insert items
|
|
160
|
+
inputItems.forEach((newItem) => {
|
|
161
|
+
// Existence check
|
|
162
|
+
if (
|
|
163
|
+
newItems.some((item) => item[labelField] == newItem[labelField])
|
|
164
|
+
) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
newItems.push(newItem);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Update the state
|
|
172
|
+
setItems(newItems);
|
|
173
|
+
|
|
174
|
+
return newItems.length - items.length;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// Delete item
|
|
178
|
+
const deleteItem = (index: number) => {
|
|
132
179
|
// Clone
|
|
133
180
|
const newItems = [...items];
|
|
134
181
|
|
|
@@ -146,7 +193,7 @@ export function DnDList<
|
|
|
146
193
|
// Layout
|
|
147
194
|
return (
|
|
148
195
|
<React.Fragment>
|
|
149
|
-
{sideRenderer && sideRenderer(true,
|
|
196
|
+
{sideRenderer && sideRenderer(true, addItem, addItems)}
|
|
150
197
|
<Component {...componentProps}>
|
|
151
198
|
<DragDropContext onDragEnd={onDragEnd}>
|
|
152
199
|
<Droppable droppableId={name}>
|
|
@@ -177,7 +224,8 @@ export function DnDList<
|
|
|
177
224
|
{...provided.dragHandleProps}
|
|
178
225
|
style={{
|
|
179
226
|
...getItemStyle(
|
|
180
|
-
snapshot.isDragging
|
|
227
|
+
snapshot.isDragging,
|
|
228
|
+
index
|
|
181
229
|
),
|
|
182
230
|
...provided
|
|
183
231
|
.draggableProps
|
|
@@ -187,7 +235,8 @@ export function DnDList<
|
|
|
187
235
|
{children(
|
|
188
236
|
item,
|
|
189
237
|
index,
|
|
190
|
-
|
|
238
|
+
deleteItem,
|
|
239
|
+
editItem
|
|
191
240
|
)}
|
|
192
241
|
</div>
|
|
193
242
|
)}
|
|
@@ -200,7 +249,7 @@ export function DnDList<
|
|
|
200
249
|
</Droppable>
|
|
201
250
|
</DragDropContext>
|
|
202
251
|
</Component>
|
|
203
|
-
{sideRenderer && sideRenderer(false,
|
|
252
|
+
{sideRenderer && sideRenderer(false, addItem, addItems)}
|
|
204
253
|
</React.Fragment>
|
|
205
254
|
);
|
|
206
255
|
}
|
package/src/mu/NotifierMU.tsx
CHANGED
|
@@ -25,7 +25,8 @@ import {
|
|
|
25
25
|
Snackbar,
|
|
26
26
|
styled,
|
|
27
27
|
Switch,
|
|
28
|
-
TextField
|
|
28
|
+
TextField,
|
|
29
|
+
Typography
|
|
29
30
|
} from '@mui/material';
|
|
30
31
|
import { Error, Info, Help, Warning, Done } from '@mui/icons-material';
|
|
31
32
|
import React from 'react';
|
|
@@ -238,18 +239,31 @@ export class NotificationMU extends NotificationReact {
|
|
|
238
239
|
...rest
|
|
239
240
|
} = this.inputProps ?? {};
|
|
240
241
|
|
|
242
|
+
const inputRef = React.createRef<HTMLInputElement>();
|
|
243
|
+
const errorRef = React.createRef<HTMLSpanElement>();
|
|
244
|
+
|
|
245
|
+
const setError = (error?: string) => {
|
|
246
|
+
if (errorRef.current == null) return;
|
|
247
|
+
errorRef.current.innerText = error ?? '';
|
|
248
|
+
};
|
|
249
|
+
|
|
241
250
|
const handleSubmit = async (
|
|
242
251
|
event: React.MouseEvent<HTMLButtonElement>
|
|
243
252
|
) => {
|
|
244
253
|
// Result
|
|
245
|
-
let result:
|
|
254
|
+
let result:
|
|
255
|
+
| boolean
|
|
256
|
+
| [boolean, string | undefined]
|
|
257
|
+
| void
|
|
258
|
+
| PromiseLike<boolean | [boolean, string | undefined] | void> =
|
|
246
259
|
undefined;
|
|
247
260
|
|
|
261
|
+
const input = inputRef.current;
|
|
262
|
+
|
|
248
263
|
if (this.onReturn) {
|
|
249
264
|
// Inputs case, no HTMLForm set to value, set the current form
|
|
250
265
|
if (inputs && value == null) value = event.currentTarget.form;
|
|
251
266
|
|
|
252
|
-
const input = inputRef.current;
|
|
253
267
|
if (input) {
|
|
254
268
|
if (type === 'date') {
|
|
255
269
|
const dateValue = input.valueAsDate;
|
|
@@ -284,13 +298,23 @@ export class NotificationMU extends NotificationReact {
|
|
|
284
298
|
// Get the value
|
|
285
299
|
// returns false to prevent default dismiss
|
|
286
300
|
const v = await result;
|
|
287
|
-
if (v === false)
|
|
301
|
+
if (v === false) {
|
|
302
|
+
input?.focus();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (Array.isArray(v)) {
|
|
306
|
+
if (!v[0]) {
|
|
307
|
+
const error = v[1];
|
|
308
|
+
setError(error);
|
|
309
|
+
input?.focus();
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
288
313
|
|
|
289
314
|
this.dismiss();
|
|
290
315
|
};
|
|
291
316
|
|
|
292
317
|
let localInputs: React.ReactNode;
|
|
293
|
-
let inputRef = React.createRef<HTMLInputElement>();
|
|
294
318
|
let value: any = undefined;
|
|
295
319
|
|
|
296
320
|
if (inputs == null) {
|
|
@@ -310,6 +334,7 @@ export class NotificationMU extends NotificationReact {
|
|
|
310
334
|
localInputs = (
|
|
311
335
|
<TextField
|
|
312
336
|
inputRef={inputRef}
|
|
337
|
+
onChange={() => setError(undefined)}
|
|
313
338
|
autoFocus
|
|
314
339
|
margin="dense"
|
|
315
340
|
fullWidth
|
|
@@ -341,6 +366,12 @@ export class NotificationMU extends NotificationReact {
|
|
|
341
366
|
<DialogContent>
|
|
342
367
|
<DialogContentText>{this.content}</DialogContentText>
|
|
343
368
|
{localInputs}
|
|
369
|
+
<Typography
|
|
370
|
+
variant="caption"
|
|
371
|
+
display="block"
|
|
372
|
+
ref={errorRef}
|
|
373
|
+
color={(theme) => theme.palette.error.main}
|
|
374
|
+
/>
|
|
344
375
|
</DialogContent>
|
|
345
376
|
<DialogActions>
|
|
346
377
|
<Button
|
|
@@ -6,7 +6,7 @@ import { Labels } from '../../app/Labels';
|
|
|
6
6
|
import { MUGlobal } from '../MUGlobal';
|
|
7
7
|
import { CommonPage, CommonPageScrollContainer } from './CommonPage';
|
|
8
8
|
import { CommonPageProps } from './CommonPageProps';
|
|
9
|
-
import
|
|
9
|
+
import SaveIcon from '@mui/icons-material/Save';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Edit page router props, include 'id' (/:id) query parameter
|
|
@@ -70,7 +70,7 @@ export function EditPage(props: EditPageProps) {
|
|
|
70
70
|
variant="contained"
|
|
71
71
|
type="submit"
|
|
72
72
|
fullWidth
|
|
73
|
-
startIcon={<
|
|
73
|
+
startIcon={<SaveIcon />}
|
|
74
74
|
>
|
|
75
75
|
{labels.save}
|
|
76
76
|
</Button>
|