@etsoo/react 1.3.95 → 1.3.99
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/components/ScrollerGrid.d.ts +2 -2
- package/lib/mu/AutocompleteExtendedProps.d.ts +2 -2
- package/lib/mu/ComboBox.d.ts +1 -1
- package/lib/mu/ComboBox.js +1 -3
- package/lib/mu/DataGridEx.js +0 -1
- package/lib/mu/DnDList.d.ts +7 -6
- package/lib/mu/DnDList.js +25 -9
- package/lib/mu/ItemList.d.ts +6 -12
- package/lib/mu/ItemList.js +8 -2
- package/lib/mu/OptionGroup.d.ts +3 -3
- package/lib/mu/OptionGroup.js +14 -4
- package/lib/mu/ScrollerListEx.d.ts +2 -2
- package/lib/mu/ScrollerListEx.js +2 -2
- package/lib/mu/SelectEx.d.ts +2 -2
- package/lib/mu/TableEx.d.ts +2 -2
- package/lib/mu/TableEx.js +5 -2
- package/lib/mu/Tiplist.js +3 -3
- package/lib/mu/pages/FixedListPage.d.ts +1 -1
- package/lib/mu/pages/ListPage.d.ts +1 -1
- package/lib/mu/pages/ResponsivePage.d.ts +1 -1
- package/lib/mu/pages/TablePage.d.ts +1 -1
- package/package.json +2 -2
- package/src/components/ScrollerGrid.tsx +2 -2
- package/src/mu/AutocompleteExtendedProps.ts +2 -2
- package/src/mu/ComboBox.tsx +2 -4
- package/src/mu/DataGridEx.tsx +0 -1
- package/src/mu/DnDList.tsx +40 -20
- package/src/mu/ItemList.tsx +15 -17
- package/src/mu/OptionGroup.tsx +16 -10
- package/src/mu/ScrollerListEx.tsx +4 -4
- package/src/mu/SelectEx.tsx +2 -2
- package/src/mu/TableEx.tsx +14 -5
- package/src/mu/Tiplist.tsx +1 -4
- package/src/mu/pages/FixedListPage.tsx +1 -1
- package/src/mu/pages/ListPage.tsx +1 -1
- package/src/mu/pages/ResponsivePage.tsx +1 -1
- package/src/mu/pages/TablePage.tsx +1 -1
|
@@ -33,7 +33,7 @@ export interface ScrollerGridProps<T> extends GridLoader<T>, Omit<VariableSizeGr
|
|
|
33
33
|
* Id field
|
|
34
34
|
* @default id
|
|
35
35
|
*/
|
|
36
|
-
idField?:
|
|
36
|
+
idField?: keyof T;
|
|
37
37
|
/**
|
|
38
38
|
* Item renderer
|
|
39
39
|
*/
|
|
@@ -109,4 +109,4 @@ export interface ScrollerGridForwardRef extends GridMethodRef {
|
|
|
109
109
|
* @param props Props
|
|
110
110
|
* @returns Component
|
|
111
111
|
*/
|
|
112
|
-
export declare const ScrollerGrid: <T extends Record<string,
|
|
112
|
+
export declare const ScrollerGrid: <T extends Record<string, unknown>>(props: ScrollerGridProps<T>) => JSX.Element;
|
|
@@ -4,11 +4,11 @@ import { ChangeEventHandler } from 'react';
|
|
|
4
4
|
/**
|
|
5
5
|
* Autocomplete extended props
|
|
6
6
|
*/
|
|
7
|
-
export interface AutocompleteExtendedProps<T extends Record<string,
|
|
7
|
+
export interface AutocompleteExtendedProps<T extends Record<string, unknown>> extends Omit<AutocompleteProps<T, undefined, false, false>, 'renderInput' | 'options'> {
|
|
8
8
|
/**
|
|
9
9
|
* Id field, default is id
|
|
10
10
|
*/
|
|
11
|
-
idField?:
|
|
11
|
+
idField?: keyof T;
|
|
12
12
|
/**
|
|
13
13
|
* Id value
|
|
14
14
|
*/
|
package/lib/mu/ComboBox.d.ts
CHANGED
package/lib/mu/ComboBox.js
CHANGED
|
@@ -52,9 +52,7 @@ export function ComboBox(props) {
|
|
|
52
52
|
const input = inputRef.current;
|
|
53
53
|
if (input) {
|
|
54
54
|
// Update value
|
|
55
|
-
const newValue = value != null
|
|
56
|
-
? `${Reflect.get(value, idField)}`
|
|
57
|
-
: '';
|
|
55
|
+
const newValue = value != null ? `${Reflect.get(value, idField)}` : '';
|
|
58
56
|
if (newValue !== input.value) {
|
|
59
57
|
// Different value, trigger change event
|
|
60
58
|
Utils.triggerChange(input, newValue, false);
|
package/lib/mu/DataGridEx.js
CHANGED
|
@@ -244,7 +244,6 @@ export function DataGridEx(props) {
|
|
|
244
244
|
}
|
|
245
245
|
// Selected
|
|
246
246
|
const selected = data != null &&
|
|
247
|
-
idField in data &&
|
|
248
247
|
(selectedRowIndex.current === rowIndex ||
|
|
249
248
|
selectedItems.some((selectedItem) => selectedItem != null &&
|
|
250
249
|
selectedItem[idField] === data[idField]));
|
package/lib/mu/DnDList.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import React, { CSSProperties } from 'react';
|
|
|
2
2
|
/**
|
|
3
3
|
* DnD list props
|
|
4
4
|
*/
|
|
5
|
-
export interface DnDListProps<D extends {},
|
|
5
|
+
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) => 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 {}, L extends keyof D, E extends React.E
|
|
|
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
|
*/
|
|
@@ -27,7 +27,7 @@ export interface DnDListProps<D extends {}, L extends keyof D, E extends React.E
|
|
|
27
27
|
/**
|
|
28
28
|
* Label field
|
|
29
29
|
*/
|
|
30
|
-
labelField:
|
|
30
|
+
labelField: keyof D;
|
|
31
31
|
/**
|
|
32
32
|
* Load data
|
|
33
33
|
*/
|
|
@@ -35,7 +35,7 @@ export interface DnDListProps<D extends {}, L extends keyof D, E extends React.E
|
|
|
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
|
*/
|
|
@@ -43,7 +43,8 @@ export interface DnDListProps<D extends {}, L extends keyof D, E extends React.E
|
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
45
|
* Drag and drop list
|
|
46
|
+
* https://github.com/atlassian/react-beautiful-dnd
|
|
46
47
|
* @param props Props
|
|
47
48
|
* @returns Component
|
|
48
49
|
*/
|
|
49
|
-
export declare function DnDList<D extends {},
|
|
50
|
+
export declare function DnDList<D extends {}, E extends React.ElementType = React.ElementType>(props: DnDListProps<D, E>): JSX.Element;
|
package/lib/mu/DnDList.js
CHANGED
|
@@ -3,6 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
|
|
4
4
|
/**
|
|
5
5
|
* Drag and drop list
|
|
6
|
+
* https://github.com/atlassian/react-beautiful-dnd
|
|
6
7
|
* @param props Props
|
|
7
8
|
* @returns Component
|
|
8
9
|
*/
|
|
@@ -13,7 +14,6 @@ export function DnDList(props) {
|
|
|
13
14
|
const [items, setItems] = React.useState([]);
|
|
14
15
|
// Drag end handler
|
|
15
16
|
const onDragEnd = (result) => {
|
|
16
|
-
console.log(result);
|
|
17
17
|
// Dropped outside the list
|
|
18
18
|
if (!result.destination) {
|
|
19
19
|
return;
|
|
@@ -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,24 @@ export function DnDList(props) {
|
|
|
39
39
|
setItems(newItems);
|
|
40
40
|
return true;
|
|
41
41
|
};
|
|
42
|
-
//
|
|
43
|
-
const
|
|
42
|
+
// Add items
|
|
43
|
+
const addItems = (inputItems) => {
|
|
44
|
+
// Clone
|
|
45
|
+
const newItems = [...items];
|
|
46
|
+
// Insert items
|
|
47
|
+
inputItems.forEach((newItem) => {
|
|
48
|
+
// Existence check
|
|
49
|
+
if (newItems.some((item) => item[labelField] == newItem[labelField])) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
newItems.push(newItem);
|
|
53
|
+
});
|
|
54
|
+
// Update the state
|
|
55
|
+
setItems(newItems);
|
|
56
|
+
return newItems.length - items.length;
|
|
57
|
+
};
|
|
58
|
+
// Delete item
|
|
59
|
+
const deleteItem = (index) => {
|
|
44
60
|
// Clone
|
|
45
61
|
const newItems = [...items];
|
|
46
62
|
// Remove the item
|
|
@@ -53,7 +69,7 @@ export function DnDList(props) {
|
|
|
53
69
|
}, [name]);
|
|
54
70
|
// Layout
|
|
55
71
|
return (React.createElement(React.Fragment, null,
|
|
56
|
-
sideRenderer && sideRenderer(true,
|
|
72
|
+
sideRenderer && sideRenderer(true, addItem, addItems),
|
|
57
73
|
React.createElement(Component, { ...componentProps },
|
|
58
74
|
React.createElement(DragDropContext, { onDragEnd: onDragEnd },
|
|
59
75
|
React.createElement(Droppable, { droppableId: name }, (provided, snapshot) => (React.createElement("div", { ...provided.droppableProps, ref: provided.innerRef, style: getListStyle(snapshot.isDraggingOver) },
|
|
@@ -63,12 +79,12 @@ export function DnDList(props) {
|
|
|
63
79
|
if (id == null)
|
|
64
80
|
return;
|
|
65
81
|
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),
|
|
82
|
+
...getItemStyle(snapshot.isDragging, index),
|
|
67
83
|
...provided
|
|
68
84
|
.draggableProps
|
|
69
85
|
.style
|
|
70
|
-
} }, children(item, index,
|
|
86
|
+
} }, children(item, index, deleteItem)))));
|
|
71
87
|
}),
|
|
72
88
|
provided.placeholder))))),
|
|
73
|
-
sideRenderer && sideRenderer(false,
|
|
89
|
+
sideRenderer && sideRenderer(false, addItem, addItems)));
|
|
74
90
|
}
|
package/lib/mu/ItemList.d.ts
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
/**
|
|
3
|
-
* Item list label callback
|
|
4
|
-
*/
|
|
5
|
-
export interface ItemListLabel {
|
|
6
|
-
(item: any): string;
|
|
7
|
-
}
|
|
8
2
|
/**
|
|
9
3
|
* Item list properties
|
|
10
4
|
*/
|
|
11
|
-
export interface ItemListProps {
|
|
5
|
+
export interface ItemListProps<T extends Record<string, unknown>> {
|
|
12
6
|
/**
|
|
13
7
|
* Style class name
|
|
14
8
|
*/
|
|
@@ -16,11 +10,11 @@ export interface ItemListProps {
|
|
|
16
10
|
/**
|
|
17
11
|
* Id field name
|
|
18
12
|
*/
|
|
19
|
-
idField?:
|
|
13
|
+
idField?: keyof T;
|
|
20
14
|
/**
|
|
21
15
|
* Label field name or callback
|
|
22
16
|
*/
|
|
23
|
-
labelField?:
|
|
17
|
+
labelField?: keyof T | ((item: T) => string);
|
|
24
18
|
/**
|
|
25
19
|
* Button icon
|
|
26
20
|
*/
|
|
@@ -32,7 +26,7 @@ export interface ItemListProps {
|
|
|
32
26
|
/**
|
|
33
27
|
* Close event
|
|
34
28
|
*/
|
|
35
|
-
onClose?(item:
|
|
29
|
+
onClose?(item: T, changed: boolean): void;
|
|
36
30
|
/**
|
|
37
31
|
* Current selected language
|
|
38
32
|
*/
|
|
@@ -48,7 +42,7 @@ export interface ItemListProps {
|
|
|
48
42
|
/**
|
|
49
43
|
* Items
|
|
50
44
|
*/
|
|
51
|
-
items:
|
|
45
|
+
items: T[];
|
|
52
46
|
/**
|
|
53
47
|
* Button variant
|
|
54
48
|
*/
|
|
@@ -58,4 +52,4 @@ export interface ItemListProps {
|
|
|
58
52
|
* Item list component
|
|
59
53
|
* @param props Properties
|
|
60
54
|
*/
|
|
61
|
-
export declare function ItemList(props: ItemListProps): JSX.Element;
|
|
55
|
+
export declare function ItemList<T extends Record<string, unknown> = Record<string, unknown>>(props: ItemListProps<T>): JSX.Element;
|
package/lib/mu/ItemList.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Dialog, DialogTitle, List, ListItem, ListItemText, DialogContent, Button } from '@mui/material';
|
|
3
|
+
import { DataTypes } from '@etsoo/shared';
|
|
3
4
|
/**
|
|
4
5
|
* Item list component
|
|
5
6
|
* @param props Properties
|
|
@@ -10,15 +11,20 @@ export function ItemList(props) {
|
|
|
10
11
|
const { className, color = 'primary', items, idField = 'id', labelField = 'label', icon, onClose, selectedValue, size = 'medium', title, variant = 'outlined' } = props;
|
|
11
12
|
// Get id
|
|
12
13
|
const getId = (item) => {
|
|
13
|
-
|
|
14
|
+
var _a;
|
|
15
|
+
const id = item[idField];
|
|
16
|
+
if (typeof id === 'number')
|
|
17
|
+
return id;
|
|
18
|
+
return (_a = DataTypes.convert(id, 'string')) !== null && _a !== void 0 ? _a : '';
|
|
14
19
|
};
|
|
15
20
|
// Get label
|
|
16
21
|
const getLabel = (item) => {
|
|
22
|
+
var _a;
|
|
17
23
|
if (typeof labelField === 'function') {
|
|
18
24
|
return labelField(item);
|
|
19
25
|
}
|
|
20
26
|
else {
|
|
21
|
-
return item[labelField];
|
|
27
|
+
return (_a = DataTypes.convert(item[labelField], 'string')) !== null && _a !== void 0 ? _a : '';
|
|
22
28
|
}
|
|
23
29
|
};
|
|
24
30
|
// Dialog open or not state
|
package/lib/mu/OptionGroup.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface OptionGroupProps<T extends Record<string, any> = IdLabelDto, D
|
|
|
17
17
|
/**
|
|
18
18
|
* Id field, default is id
|
|
19
19
|
*/
|
|
20
|
-
idField?:
|
|
20
|
+
idField?: keyof T;
|
|
21
21
|
/**
|
|
22
22
|
* Label
|
|
23
23
|
*/
|
|
@@ -25,7 +25,7 @@ export interface OptionGroupProps<T extends Record<string, any> = IdLabelDto, D
|
|
|
25
25
|
/**
|
|
26
26
|
* Label field, default is label
|
|
27
27
|
*/
|
|
28
|
-
labelField?:
|
|
28
|
+
labelField?: keyof T;
|
|
29
29
|
/**
|
|
30
30
|
* Multiple choose item
|
|
31
31
|
*/
|
|
@@ -56,4 +56,4 @@ export interface OptionGroupProps<T extends Record<string, any> = IdLabelDto, D
|
|
|
56
56
|
* @param props Props
|
|
57
57
|
* @returns Component
|
|
58
58
|
*/
|
|
59
|
-
export declare function OptionGroup<T extends Record<string,
|
|
59
|
+
export declare function OptionGroup<T extends Record<string, unknown> = IdLabelDto, D extends DataTypes.IdType = string>(props: OptionGroupProps<T, D>): JSX.Element;
|
package/lib/mu/OptionGroup.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Utils } from '@etsoo/shared';
|
|
1
|
+
import { DataTypes, Utils } from '@etsoo/shared';
|
|
2
2
|
import { Checkbox, FormControl, FormControlLabel, FormGroup, FormLabel, Radio, RadioGroup } from '@mui/material';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
/**
|
|
@@ -10,8 +10,12 @@ export function OptionGroup(props) {
|
|
|
10
10
|
// Destruct
|
|
11
11
|
const { getOptionLabel, defaultValue, idField = 'id', label, labelField = 'label', multiple = false, name, onValueChange, options, readOnly, row, size, ...rest } = props;
|
|
12
12
|
// Get option value
|
|
13
|
+
// D type should be the source id type
|
|
13
14
|
const getOptionValue = (option) => {
|
|
14
|
-
|
|
15
|
+
const value = DataTypes.getIdValue(option, idField);
|
|
16
|
+
if (value == null)
|
|
17
|
+
return null;
|
|
18
|
+
return value;
|
|
15
19
|
};
|
|
16
20
|
// Checkbox values
|
|
17
21
|
const [values, setValues] = React.useState(defaultValue == null
|
|
@@ -27,11 +31,15 @@ export function OptionGroup(props) {
|
|
|
27
31
|
return false;
|
|
28
32
|
return values.includes(value);
|
|
29
33
|
};
|
|
34
|
+
// First item value
|
|
35
|
+
const firstOptionValue = getOptionValue(options[0]);
|
|
30
36
|
// Items
|
|
31
37
|
const list = options.map((option) => {
|
|
32
38
|
// Control
|
|
33
39
|
const control = multiple ? (React.createElement(Checkbox, { name: name, readOnly: readOnly, size: size, checked: itemChecked(option), onChange: (event) => {
|
|
34
|
-
|
|
40
|
+
if (firstOptionValue == null)
|
|
41
|
+
return;
|
|
42
|
+
const typeValue = Utils.parseString(event.target.value, firstOptionValue);
|
|
35
43
|
const changedValues = [...values];
|
|
36
44
|
if (event.target.checked) {
|
|
37
45
|
if (changedValues.includes(typeValue))
|
|
@@ -59,7 +67,9 @@ export function OptionGroup(props) {
|
|
|
59
67
|
});
|
|
60
68
|
// Group
|
|
61
69
|
const group = multiple ? (React.createElement(FormGroup, { row: row }, list)) : (React.createElement(RadioGroup, { row: row, name: name, value: defaultValue, onChange: (_event, value) => {
|
|
62
|
-
|
|
70
|
+
if (firstOptionValue == null)
|
|
71
|
+
return;
|
|
72
|
+
const typeValue = Utils.parseString(value, firstOptionValue);
|
|
63
73
|
if (onValueChange)
|
|
64
74
|
onValueChange(typeValue);
|
|
65
75
|
} }, list));
|
|
@@ -25,7 +25,7 @@ export interface ScrollerListExProps<T> extends Omit<ScrollerListProps<T>, 'item
|
|
|
25
25
|
/**
|
|
26
26
|
* Id field
|
|
27
27
|
*/
|
|
28
|
-
idField?:
|
|
28
|
+
idField?: keyof T;
|
|
29
29
|
/**
|
|
30
30
|
* Inner item renderer
|
|
31
31
|
*/
|
|
@@ -48,4 +48,4 @@ export interface ScrollerListExProps<T> extends Omit<ScrollerListProps<T>, 'item
|
|
|
48
48
|
* @param props Props
|
|
49
49
|
* @returns Component
|
|
50
50
|
*/
|
|
51
|
-
export declare function ScrollerListEx<T extends Record<string,
|
|
51
|
+
export declare function ScrollerListEx<T extends Record<string, unknown>>(props: ScrollerListExProps<T>): JSX.Element;
|
package/lib/mu/ScrollerListEx.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { css } from '@emotion/css';
|
|
2
|
-
import { Utils } from '@etsoo/shared';
|
|
2
|
+
import { DataTypes, Utils } from '@etsoo/shared';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { ScrollerList } from '../components/ScrollerList';
|
|
5
5
|
// Scroll bar size
|
|
@@ -82,7 +82,7 @@ export function ScrollerListEx(props) {
|
|
|
82
82
|
return selected;
|
|
83
83
|
};
|
|
84
84
|
// Destruct
|
|
85
|
-
const { alternatingColors = [undefined, undefined], className, idField = 'id', innerItemRenderer, itemSize, itemKey = (index, data) => data
|
|
85
|
+
const { alternatingColors = [undefined, undefined], className, idField = 'id', innerItemRenderer, itemSize, itemKey = (index, data) => { var _a; return (_a = DataTypes.getIdValue(data, idField)) !== null && _a !== void 0 ? _a : index; }, itemRenderer = (itemProps) => {
|
|
86
86
|
const itemHeight = typeof itemSize === 'function'
|
|
87
87
|
? itemSize(itemProps.index)
|
|
88
88
|
: itemSize;
|
package/lib/mu/SelectEx.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface SelectExProps<T extends {}> extends Omit<SelectProps, 'labelId'
|
|
|
8
8
|
/**
|
|
9
9
|
* Id field, default is id
|
|
10
10
|
*/
|
|
11
|
-
idField?:
|
|
11
|
+
idField?: keyof T;
|
|
12
12
|
/**
|
|
13
13
|
* Item icon renderer
|
|
14
14
|
*/
|
|
@@ -16,7 +16,7 @@ export interface SelectExProps<T extends {}> extends Omit<SelectProps, 'labelId'
|
|
|
16
16
|
/**
|
|
17
17
|
* Label field, default is label
|
|
18
18
|
*/
|
|
19
|
-
labelField?: ((option: T) => string) |
|
|
19
|
+
labelField?: ((option: T) => string) | keyof T;
|
|
20
20
|
/**
|
|
21
21
|
* Load data callback
|
|
22
22
|
*/
|
package/lib/mu/TableEx.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export interface TableExProps<T extends Record<string, any>> extends TableProps,
|
|
|
35
35
|
/**
|
|
36
36
|
* Id field
|
|
37
37
|
*/
|
|
38
|
-
idField?:
|
|
38
|
+
idField?: keyof T;
|
|
39
39
|
/**
|
|
40
40
|
* Max height
|
|
41
41
|
*/
|
|
@@ -62,4 +62,4 @@ export interface TableExProps<T extends Record<string, any>> extends TableProps,
|
|
|
62
62
|
* @param props Props
|
|
63
63
|
* @returns Component
|
|
64
64
|
*/
|
|
65
|
-
export declare function TableEx<T extends Record<string,
|
|
65
|
+
export declare function TableEx<T extends Record<string, unknown>>(props: TableExProps<T>): JSX.Element;
|
package/lib/mu/TableEx.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DataTypes } from '@etsoo/shared';
|
|
1
2
|
import { Checkbox, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TablePagination, TableRow, TableSortLabel, useTheme } from '@mui/material';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import { GridAlignGet } from '../components/GridColumn';
|
|
@@ -220,12 +221,13 @@ export function TableEx(props) {
|
|
|
220
221
|
backgroundColor: alternatingColors[1]
|
|
221
222
|
}
|
|
222
223
|
} }, [...Array(batchSize)].map((_item, rowIndex) => {
|
|
224
|
+
var _a;
|
|
223
225
|
// Row
|
|
224
226
|
const row = rowIndex < rows.length
|
|
225
227
|
? rows[rowIndex]
|
|
226
228
|
: undefined;
|
|
227
229
|
// Row id field value
|
|
228
|
-
const rowId = row
|
|
230
|
+
const rowId = (_a = DataTypes.getIdValue(row, idField)) !== null && _a !== void 0 ? _a : rowIndex;
|
|
229
231
|
// Selected or not
|
|
230
232
|
const isItemSelected = selectable
|
|
231
233
|
? selectedItems.some((item) => item[idField] === rowId)
|
|
@@ -255,7 +257,8 @@ export function TableEx(props) {
|
|
|
255
257
|
columnIndex,
|
|
256
258
|
cellProps
|
|
257
259
|
})) : (React.createElement(React.Fragment, null, "\u00A0"));
|
|
258
|
-
return (React.createElement(TableCell, { key: rowId +
|
|
260
|
+
return (React.createElement(TableCell, { key: rowId.toString() +
|
|
261
|
+
columnIndex, ...cellProps }, child));
|
|
259
262
|
})));
|
|
260
263
|
})))),
|
|
261
264
|
React.createElement(TablePagination, { component: "div", showFirstButton: true, count: totalRows, rowsPerPage: batchSize, page: currentPage, onPageChange: handleChangePage, onRowsPerPageChange: handleChangeRowsPerPage, rowsPerPageOptions: [
|
package/lib/mu/Tiplist.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DataTypes } from '@etsoo/shared';
|
|
1
2
|
import { Autocomplete } from '@mui/material';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import { Utils } from '../app/Utils';
|
|
@@ -94,14 +95,13 @@ export function Tiplist(props) {
|
|
|
94
95
|
});
|
|
95
96
|
};
|
|
96
97
|
const setInputValue = (value) => {
|
|
98
|
+
var _a;
|
|
97
99
|
stateUpdate({ value });
|
|
98
100
|
// Input value
|
|
99
101
|
const input = inputRef.current;
|
|
100
102
|
if (input) {
|
|
101
103
|
// Update value
|
|
102
|
-
const newValue = value
|
|
103
|
-
? `${Reflect.get(value, idField)}`
|
|
104
|
-
: '';
|
|
104
|
+
const newValue = (_a = DataTypes.getStringValue(value, idField)) !== null && _a !== void 0 ? _a : '';
|
|
105
105
|
if (newValue !== input.value) {
|
|
106
106
|
// Different value, trigger change event
|
|
107
107
|
Utils.triggerChange(input, newValue, false);
|
|
@@ -6,7 +6,7 @@ import { ListPageProps } from './ListPageProps';
|
|
|
6
6
|
* @param props Props
|
|
7
7
|
* @returns Component
|
|
8
8
|
*/
|
|
9
|
-
export declare function FixedListPage<T, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate>(props: ListPageProps<T, F> & {
|
|
9
|
+
export declare function FixedListPage<T extends {}, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate>(props: ListPageProps<T, F> & {
|
|
10
10
|
/**
|
|
11
11
|
* Height will be deducted
|
|
12
12
|
* @param height Current calcuated height
|
|
@@ -6,4 +6,4 @@ import { ListPageProps } from './ListPageProps';
|
|
|
6
6
|
* @param props Props
|
|
7
7
|
* @returns Component
|
|
8
8
|
*/
|
|
9
|
-
export declare function ListPage<T, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate>(props: ListPageProps<T, F>): JSX.Element;
|
|
9
|
+
export declare function ListPage<T extends {}, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate>(props: ListPageProps<T, F>): JSX.Element;
|
|
@@ -6,4 +6,4 @@ import { ResponsePageProps } from './ResponsivePageProps';
|
|
|
6
6
|
* @param props Props
|
|
7
7
|
* @returns Component
|
|
8
8
|
*/
|
|
9
|
-
export declare function ResponsivePage<T, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate>(props: ResponsePageProps<T, F>): JSX.Element;
|
|
9
|
+
export declare function ResponsivePage<T extends {}, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate>(props: ResponsePageProps<T, F>): JSX.Element;
|
|
@@ -6,4 +6,4 @@ import { TablePageProps } from './TablePageProps';
|
|
|
6
6
|
* @param props Props
|
|
7
7
|
* @returns Component
|
|
8
8
|
*/
|
|
9
|
-
export declare function TablePage<T, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate>(props: TablePageProps<T, F>): JSX.Element;
|
|
9
|
+
export declare function TablePage<T extends {}, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate>(props: TablePageProps<T, F>): JSX.Element;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/react",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.99",
|
|
4
4
|
"description": "TypeScript ReactJs framework",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@emotion/styled": "^11.6.0",
|
|
53
53
|
"@etsoo/appscript": "^1.2.11",
|
|
54
54
|
"@etsoo/notificationbase": "^1.0.95",
|
|
55
|
-
"@etsoo/shared": "^1.0.
|
|
55
|
+
"@etsoo/shared": "^1.0.97",
|
|
56
56
|
"@mui/icons-material": "^5.2.5",
|
|
57
57
|
"@mui/material": "^5.2.6",
|
|
58
58
|
"@reach/router": "^1.3.4",
|
|
@@ -51,7 +51,7 @@ export interface ScrollerGridProps<T>
|
|
|
51
51
|
* Id field
|
|
52
52
|
* @default id
|
|
53
53
|
*/
|
|
54
|
-
idField?:
|
|
54
|
+
idField?: keyof T;
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Item renderer
|
|
@@ -140,7 +140,7 @@ export interface ScrollerGridForwardRef extends GridMethodRef {
|
|
|
140
140
|
* @param props Props
|
|
141
141
|
* @returns Component
|
|
142
142
|
*/
|
|
143
|
-
export const ScrollerGrid = <T extends Record<string,
|
|
143
|
+
export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
144
144
|
props: ScrollerGridProps<T>
|
|
145
145
|
) => {
|
|
146
146
|
// Destruct
|
|
@@ -5,7 +5,7 @@ import { ChangeEventHandler } from 'react';
|
|
|
5
5
|
/**
|
|
6
6
|
* Autocomplete extended props
|
|
7
7
|
*/
|
|
8
|
-
export interface AutocompleteExtendedProps<T extends Record<string,
|
|
8
|
+
export interface AutocompleteExtendedProps<T extends Record<string, unknown>>
|
|
9
9
|
extends Omit<
|
|
10
10
|
AutocompleteProps<T, undefined, false, false>,
|
|
11
11
|
'renderInput' | 'options'
|
|
@@ -13,7 +13,7 @@ export interface AutocompleteExtendedProps<T extends Record<string, any>>
|
|
|
13
13
|
/**
|
|
14
14
|
* Id field, default is id
|
|
15
15
|
*/
|
|
16
|
-
idField?:
|
|
16
|
+
idField?: keyof T;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Id value
|
package/src/mu/ComboBox.tsx
CHANGED
|
@@ -14,7 +14,7 @@ export interface ComboBoxProps<T extends {}>
|
|
|
14
14
|
/**
|
|
15
15
|
* Label field
|
|
16
16
|
*/
|
|
17
|
-
labelField?:
|
|
17
|
+
labelField?: keyof T;
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Load data callback
|
|
@@ -118,9 +118,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
|
|
|
118
118
|
if (input) {
|
|
119
119
|
// Update value
|
|
120
120
|
const newValue =
|
|
121
|
-
value != null
|
|
122
|
-
? `${Reflect.get(value, idField)}`
|
|
123
|
-
: '';
|
|
121
|
+
value != null ? `${Reflect.get(value, idField)}` : '';
|
|
124
122
|
|
|
125
123
|
if (newValue !== input.value) {
|
|
126
124
|
// Different value, trigger change event
|
package/src/mu/DataGridEx.tsx
CHANGED
package/src/mu/DnDList.tsx
CHANGED
|
@@ -10,18 +10,14 @@ import {
|
|
|
10
10
|
/**
|
|
11
11
|
* DnD list props
|
|
12
12
|
*/
|
|
13
|
-
export interface DnDListProps<
|
|
14
|
-
D extends {},
|
|
15
|
-
L extends keyof D,
|
|
16
|
-
E extends React.ElementType
|
|
17
|
-
> {
|
|
13
|
+
export interface DnDListProps<D extends {}, E extends React.ElementType> {
|
|
18
14
|
/**
|
|
19
15
|
* Item renderer
|
|
20
16
|
*/
|
|
21
17
|
children: (
|
|
22
18
|
item: D,
|
|
23
19
|
index: number,
|
|
24
|
-
|
|
20
|
+
deleteItem: (index: number) => void
|
|
25
21
|
) => React.ReactNode;
|
|
26
22
|
|
|
27
23
|
/**
|
|
@@ -38,7 +34,7 @@ export interface DnDListProps<
|
|
|
38
34
|
/**
|
|
39
35
|
* Get list item style callback
|
|
40
36
|
*/
|
|
41
|
-
getItemStyle?: (isDragging: boolean) => CSSProperties;
|
|
37
|
+
getItemStyle?: (isDragging: boolean, index: number) => CSSProperties;
|
|
42
38
|
|
|
43
39
|
/**
|
|
44
40
|
* Get list style callback
|
|
@@ -48,7 +44,7 @@ export interface DnDListProps<
|
|
|
48
44
|
/**
|
|
49
45
|
* Label field
|
|
50
46
|
*/
|
|
51
|
-
labelField:
|
|
47
|
+
labelField: keyof D;
|
|
52
48
|
|
|
53
49
|
/**
|
|
54
50
|
* Load data
|
|
@@ -60,7 +56,8 @@ export interface DnDListProps<
|
|
|
60
56
|
*/
|
|
61
57
|
sideRenderer?: (
|
|
62
58
|
top: boolean,
|
|
63
|
-
|
|
59
|
+
addItem: (item: D) => boolean,
|
|
60
|
+
addItems: (items: D[]) => number
|
|
64
61
|
) => React.ReactNode;
|
|
65
62
|
|
|
66
63
|
/**
|
|
@@ -71,14 +68,14 @@ export interface DnDListProps<
|
|
|
71
68
|
|
|
72
69
|
/**
|
|
73
70
|
* Drag and drop list
|
|
71
|
+
* https://github.com/atlassian/react-beautiful-dnd
|
|
74
72
|
* @param props Props
|
|
75
73
|
* @returns Component
|
|
76
74
|
*/
|
|
77
75
|
export function DnDList<
|
|
78
76
|
D extends {},
|
|
79
|
-
L extends keyof D,
|
|
80
77
|
E extends React.ElementType = React.ElementType
|
|
81
|
-
>(props: DnDListProps<D,
|
|
78
|
+
>(props: DnDListProps<D, E>) {
|
|
82
79
|
// Destruct
|
|
83
80
|
const {
|
|
84
81
|
children,
|
|
@@ -97,7 +94,6 @@ export function DnDList<
|
|
|
97
94
|
|
|
98
95
|
// Drag end handler
|
|
99
96
|
const onDragEnd = (result: DropResult) => {
|
|
100
|
-
console.log(result);
|
|
101
97
|
// Dropped outside the list
|
|
102
98
|
if (!result.destination) {
|
|
103
99
|
return;
|
|
@@ -116,8 +112,8 @@ export function DnDList<
|
|
|
116
112
|
setItems(newItems);
|
|
117
113
|
};
|
|
118
114
|
|
|
119
|
-
// Add
|
|
120
|
-
const
|
|
115
|
+
// Add item
|
|
116
|
+
const addItem = (newItem: D) => {
|
|
121
117
|
// Existence check
|
|
122
118
|
if (items.some((item) => item[labelField] == newItem[labelField])) {
|
|
123
119
|
return false;
|
|
@@ -132,8 +128,31 @@ export function DnDList<
|
|
|
132
128
|
return true;
|
|
133
129
|
};
|
|
134
130
|
|
|
135
|
-
//
|
|
136
|
-
const
|
|
131
|
+
// Add items
|
|
132
|
+
const addItems = (inputItems: D[]) => {
|
|
133
|
+
// Clone
|
|
134
|
+
const newItems = [...items];
|
|
135
|
+
|
|
136
|
+
// Insert items
|
|
137
|
+
inputItems.forEach((newItem) => {
|
|
138
|
+
// Existence check
|
|
139
|
+
if (
|
|
140
|
+
newItems.some((item) => item[labelField] == newItem[labelField])
|
|
141
|
+
) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
newItems.push(newItem);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Update the state
|
|
149
|
+
setItems(newItems);
|
|
150
|
+
|
|
151
|
+
return newItems.length - items.length;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
// Delete item
|
|
155
|
+
const deleteItem = (index: number) => {
|
|
137
156
|
// Clone
|
|
138
157
|
const newItems = [...items];
|
|
139
158
|
|
|
@@ -151,7 +170,7 @@ export function DnDList<
|
|
|
151
170
|
// Layout
|
|
152
171
|
return (
|
|
153
172
|
<React.Fragment>
|
|
154
|
-
{sideRenderer && sideRenderer(true,
|
|
173
|
+
{sideRenderer && sideRenderer(true, addItem, addItems)}
|
|
155
174
|
<Component {...componentProps}>
|
|
156
175
|
<DragDropContext onDragEnd={onDragEnd}>
|
|
157
176
|
<Droppable droppableId={name}>
|
|
@@ -182,7 +201,8 @@ export function DnDList<
|
|
|
182
201
|
{...provided.dragHandleProps}
|
|
183
202
|
style={{
|
|
184
203
|
...getItemStyle(
|
|
185
|
-
snapshot.isDragging
|
|
204
|
+
snapshot.isDragging,
|
|
205
|
+
index
|
|
186
206
|
),
|
|
187
207
|
...provided
|
|
188
208
|
.draggableProps
|
|
@@ -192,7 +212,7 @@ export function DnDList<
|
|
|
192
212
|
{children(
|
|
193
213
|
item,
|
|
194
214
|
index,
|
|
195
|
-
|
|
215
|
+
deleteItem
|
|
196
216
|
)}
|
|
197
217
|
</div>
|
|
198
218
|
)}
|
|
@@ -205,7 +225,7 @@ export function DnDList<
|
|
|
205
225
|
</Droppable>
|
|
206
226
|
</DragDropContext>
|
|
207
227
|
</Component>
|
|
208
|
-
{sideRenderer && sideRenderer(false,
|
|
228
|
+
{sideRenderer && sideRenderer(false, addItem, addItems)}
|
|
209
229
|
</React.Fragment>
|
|
210
230
|
);
|
|
211
231
|
}
|
package/src/mu/ItemList.tsx
CHANGED
|
@@ -8,18 +8,12 @@ import {
|
|
|
8
8
|
DialogContent,
|
|
9
9
|
Button
|
|
10
10
|
} from '@mui/material';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Item list label callback
|
|
14
|
-
*/
|
|
15
|
-
export interface ItemListLabel {
|
|
16
|
-
(item: any): string;
|
|
17
|
-
}
|
|
11
|
+
import { DataTypes } from '@etsoo/shared';
|
|
18
12
|
|
|
19
13
|
/**
|
|
20
14
|
* Item list properties
|
|
21
15
|
*/
|
|
22
|
-
export interface ItemListProps {
|
|
16
|
+
export interface ItemListProps<T extends Record<string, unknown>> {
|
|
23
17
|
/**
|
|
24
18
|
* Style class name
|
|
25
19
|
*/
|
|
@@ -28,12 +22,12 @@ export interface ItemListProps {
|
|
|
28
22
|
/**
|
|
29
23
|
* Id field name
|
|
30
24
|
*/
|
|
31
|
-
idField?:
|
|
25
|
+
idField?: keyof T;
|
|
32
26
|
|
|
33
27
|
/**
|
|
34
28
|
* Label field name or callback
|
|
35
29
|
*/
|
|
36
|
-
labelField?:
|
|
30
|
+
labelField?: keyof T | ((item: T) => string);
|
|
37
31
|
|
|
38
32
|
/**
|
|
39
33
|
* Button icon
|
|
@@ -48,7 +42,7 @@ export interface ItemListProps {
|
|
|
48
42
|
/**
|
|
49
43
|
* Close event
|
|
50
44
|
*/
|
|
51
|
-
onClose?(item:
|
|
45
|
+
onClose?(item: T, changed: boolean): void;
|
|
52
46
|
|
|
53
47
|
/**
|
|
54
48
|
* Current selected language
|
|
@@ -68,7 +62,7 @@ export interface ItemListProps {
|
|
|
68
62
|
/**
|
|
69
63
|
* Items
|
|
70
64
|
*/
|
|
71
|
-
items:
|
|
65
|
+
items: T[];
|
|
72
66
|
|
|
73
67
|
/**
|
|
74
68
|
* Button variant
|
|
@@ -80,7 +74,9 @@ export interface ItemListProps {
|
|
|
80
74
|
* Item list component
|
|
81
75
|
* @param props Properties
|
|
82
76
|
*/
|
|
83
|
-
export function ItemList
|
|
77
|
+
export function ItemList<
|
|
78
|
+
T extends Record<string, unknown> = Record<string, unknown>
|
|
79
|
+
>(props: ItemListProps<T>) {
|
|
84
80
|
// properties destructure
|
|
85
81
|
const {
|
|
86
82
|
className,
|
|
@@ -97,16 +93,18 @@ export function ItemList(props: ItemListProps) {
|
|
|
97
93
|
} = props;
|
|
98
94
|
|
|
99
95
|
// Get id
|
|
100
|
-
const getId = (item:
|
|
101
|
-
|
|
96
|
+
const getId = (item: T): string | number => {
|
|
97
|
+
const id = item[idField];
|
|
98
|
+
if (typeof id === 'number') return id;
|
|
99
|
+
return DataTypes.convert(id, 'string') ?? '';
|
|
102
100
|
};
|
|
103
101
|
|
|
104
102
|
// Get label
|
|
105
|
-
const getLabel = (item:
|
|
103
|
+
const getLabel = (item: T): string => {
|
|
106
104
|
if (typeof labelField === 'function') {
|
|
107
105
|
return labelField(item);
|
|
108
106
|
} else {
|
|
109
|
-
return item[labelField];
|
|
107
|
+
return DataTypes.convert(item[labelField], 'string') ?? '';
|
|
110
108
|
}
|
|
111
109
|
};
|
|
112
110
|
|
package/src/mu/OptionGroup.tsx
CHANGED
|
@@ -32,7 +32,7 @@ export interface OptionGroupProps<
|
|
|
32
32
|
/**
|
|
33
33
|
* Id field, default is id
|
|
34
34
|
*/
|
|
35
|
-
idField?:
|
|
35
|
+
idField?: keyof T;
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Label
|
|
@@ -42,7 +42,7 @@ export interface OptionGroupProps<
|
|
|
42
42
|
/**
|
|
43
43
|
* Label field, default is label
|
|
44
44
|
*/
|
|
45
|
-
labelField?:
|
|
45
|
+
labelField?: keyof T;
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* Multiple choose item
|
|
@@ -81,7 +81,7 @@ export interface OptionGroupProps<
|
|
|
81
81
|
* @returns Component
|
|
82
82
|
*/
|
|
83
83
|
export function OptionGroup<
|
|
84
|
-
T extends Record<string,
|
|
84
|
+
T extends Record<string, unknown> = IdLabelDto,
|
|
85
85
|
D extends DataTypes.IdType = string
|
|
86
86
|
>(props: OptionGroupProps<T, D>) {
|
|
87
87
|
// Destruct
|
|
@@ -102,8 +102,11 @@ export function OptionGroup<
|
|
|
102
102
|
} = props;
|
|
103
103
|
|
|
104
104
|
// Get option value
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
// D type should be the source id type
|
|
106
|
+
const getOptionValue = (option: T): D | null => {
|
|
107
|
+
const value = DataTypes.getIdValue(option, idField);
|
|
108
|
+
if (value == null) return null;
|
|
109
|
+
return value as D;
|
|
107
110
|
};
|
|
108
111
|
|
|
109
112
|
// Checkbox values
|
|
@@ -124,6 +127,9 @@ export function OptionGroup<
|
|
|
124
127
|
return values.includes(value);
|
|
125
128
|
};
|
|
126
129
|
|
|
130
|
+
// First item value
|
|
131
|
+
const firstOptionValue = getOptionValue(options[0]);
|
|
132
|
+
|
|
127
133
|
// Items
|
|
128
134
|
const list = options.map((option) => {
|
|
129
135
|
// Control
|
|
@@ -134,9 +140,11 @@ export function OptionGroup<
|
|
|
134
140
|
size={size}
|
|
135
141
|
checked={itemChecked(option)}
|
|
136
142
|
onChange={(event) => {
|
|
143
|
+
if (firstOptionValue == null) return;
|
|
144
|
+
|
|
137
145
|
const typeValue = Utils.parseString<D>(
|
|
138
146
|
event.target.value,
|
|
139
|
-
|
|
147
|
+
firstOptionValue
|
|
140
148
|
);
|
|
141
149
|
|
|
142
150
|
const changedValues = [...values];
|
|
@@ -188,10 +196,8 @@ export function OptionGroup<
|
|
|
188
196
|
name={name}
|
|
189
197
|
value={defaultValue}
|
|
190
198
|
onChange={(_event, value) => {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
options[0][idField]
|
|
194
|
-
);
|
|
199
|
+
if (firstOptionValue == null) return;
|
|
200
|
+
const typeValue = Utils.parseString<D>(value, firstOptionValue);
|
|
195
201
|
if (onValueChange) onValueChange(typeValue);
|
|
196
202
|
}}
|
|
197
203
|
>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { css } from '@emotion/css';
|
|
2
|
-
import { Utils } from '@etsoo/shared';
|
|
2
|
+
import { DataTypes, Utils } from '@etsoo/shared';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { ListChildComponentProps } from 'react-window';
|
|
5
5
|
import { ScrollerList, ScrollerListProps } from '../components/ScrollerList';
|
|
@@ -73,7 +73,7 @@ export interface ScrollerListExProps<T>
|
|
|
73
73
|
/**
|
|
74
74
|
* Id field
|
|
75
75
|
*/
|
|
76
|
-
idField?:
|
|
76
|
+
idField?: keyof T;
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
79
|
* Inner item renderer
|
|
@@ -161,7 +161,7 @@ function defaultItemRenderer<T>({
|
|
|
161
161
|
* @param props Props
|
|
162
162
|
* @returns Component
|
|
163
163
|
*/
|
|
164
|
-
export function ScrollerListEx<T extends Record<string,
|
|
164
|
+
export function ScrollerListEx<T extends Record<string, unknown>>(
|
|
165
165
|
props: ScrollerListExProps<T>
|
|
166
166
|
) {
|
|
167
167
|
// Selected item ref
|
|
@@ -201,7 +201,7 @@ export function ScrollerListEx<T extends Record<string, any>>(
|
|
|
201
201
|
innerItemRenderer,
|
|
202
202
|
itemSize,
|
|
203
203
|
itemKey = (index: number, data: T) =>
|
|
204
|
-
data
|
|
204
|
+
DataTypes.getIdValue(data, idField) ?? index,
|
|
205
205
|
itemRenderer = (itemProps) => {
|
|
206
206
|
const itemHeight =
|
|
207
207
|
typeof itemSize === 'function'
|
package/src/mu/SelectEx.tsx
CHANGED
|
@@ -23,7 +23,7 @@ export interface SelectExProps<T extends {}>
|
|
|
23
23
|
/**
|
|
24
24
|
* Id field, default is id
|
|
25
25
|
*/
|
|
26
|
-
idField?:
|
|
26
|
+
idField?: keyof T;
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Item icon renderer
|
|
@@ -33,7 +33,7 @@ export interface SelectExProps<T extends {}>
|
|
|
33
33
|
/**
|
|
34
34
|
* Label field, default is label
|
|
35
35
|
*/
|
|
36
|
-
labelField?: ((option: T) => string) |
|
|
36
|
+
labelField?: ((option: T) => string) | keyof T;
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* Load data callback
|
package/src/mu/TableEx.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DataTypes } from '@etsoo/shared';
|
|
1
2
|
import {
|
|
2
3
|
Checkbox,
|
|
3
4
|
Paper,
|
|
@@ -67,7 +68,7 @@ export interface TableExProps<T extends Record<string, any>>
|
|
|
67
68
|
/**
|
|
68
69
|
* Id field
|
|
69
70
|
*/
|
|
70
|
-
idField?:
|
|
71
|
+
idField?: keyof T;
|
|
71
72
|
|
|
72
73
|
/**
|
|
73
74
|
* Max height
|
|
@@ -100,10 +101,14 @@ export interface TableExProps<T extends Record<string, any>>
|
|
|
100
101
|
* @param props Props
|
|
101
102
|
* @returns Component
|
|
102
103
|
*/
|
|
103
|
-
export function TableEx<T extends Record<string,
|
|
104
|
+
export function TableEx<T extends Record<string, unknown>>(
|
|
105
|
+
props: TableExProps<T>
|
|
106
|
+
) {
|
|
104
107
|
// Theme
|
|
105
108
|
const theme = useTheme();
|
|
106
109
|
|
|
110
|
+
type keyType = keyof T;
|
|
111
|
+
|
|
107
112
|
// Destruct
|
|
108
113
|
const {
|
|
109
114
|
alternatingColors = [theme.palette.action.hover, undefined],
|
|
@@ -111,7 +116,7 @@ export function TableEx<T extends Record<string, any>>(props: TableExProps<T>) {
|
|
|
111
116
|
columns,
|
|
112
117
|
defaultOrderBy,
|
|
113
118
|
headerColors = [undefined, undefined],
|
|
114
|
-
idField = 'id',
|
|
119
|
+
idField = 'id' as keyType,
|
|
115
120
|
loadBatchSize,
|
|
116
121
|
loadData,
|
|
117
122
|
maxHeight,
|
|
@@ -441,7 +446,8 @@ export function TableEx<T extends Record<string, any>>(props: TableExProps<T>) {
|
|
|
441
446
|
: undefined;
|
|
442
447
|
|
|
443
448
|
// Row id field value
|
|
444
|
-
const rowId =
|
|
449
|
+
const rowId =
|
|
450
|
+
DataTypes.getIdValue(row, idField) ?? rowIndex;
|
|
445
451
|
|
|
446
452
|
// Selected or not
|
|
447
453
|
const isItemSelected = selectable
|
|
@@ -522,7 +528,10 @@ export function TableEx<T extends Record<string, any>>(props: TableExProps<T>) {
|
|
|
522
528
|
|
|
523
529
|
return (
|
|
524
530
|
<TableCell
|
|
525
|
-
key={
|
|
531
|
+
key={
|
|
532
|
+
rowId.toString() +
|
|
533
|
+
columnIndex
|
|
534
|
+
}
|
|
526
535
|
{...cellProps}
|
|
527
536
|
>
|
|
528
537
|
{child}
|
package/src/mu/Tiplist.tsx
CHANGED
|
@@ -176,10 +176,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
|
|
|
176
176
|
const input = inputRef.current;
|
|
177
177
|
if (input) {
|
|
178
178
|
// Update value
|
|
179
|
-
const newValue =
|
|
180
|
-
value != null && idField in value
|
|
181
|
-
? `${Reflect.get(value, idField)}`
|
|
182
|
-
: '';
|
|
179
|
+
const newValue = DataTypes.getStringValue(value, idField) ?? '';
|
|
183
180
|
if (newValue !== input.value) {
|
|
184
181
|
// Different value, trigger change event
|
|
185
182
|
Utils.triggerChange(input, newValue, false);
|