@etsoo/react 1.3.90 → 1.3.94

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.
@@ -11,7 +11,7 @@ import { RefreshTokenRQ } from './RefreshTokenRQ';
11
11
  * Use the acess token to the service api, get a service access token
12
12
  * Use the new acess token and refresh token to login
13
13
  */
14
- export declare class ServiceApp<P extends IServicePageData = IServicePageData, U extends IServiceUser = IServiceUser, S extends IServiceAppSettings = IServiceAppSettings> extends ReactApp<S, U, P> {
14
+ export declare class ServiceApp<U extends IServiceUser = IServiceUser, P extends IServicePageData = IServicePageData, S extends IServiceAppSettings = IServiceAppSettings> extends ReactApp<S, U, P> {
15
15
  /**
16
16
  * Service API
17
17
  */
@@ -48,8 +48,6 @@ export class ServiceApp extends ReactApp {
48
48
  coreUrl +
49
49
  '?serviceId=' +
50
50
  this.settings.serviceId +
51
- '&serviceDeviceId=' +
52
- encodeURIComponent(this.deviceId) +
53
51
  '&' +
54
52
  DomUtils.CultureField +
55
53
  '=' +
package/lib/index.d.ts CHANGED
@@ -38,6 +38,7 @@ export * from './mu/CustomFabProps';
38
38
  export * from './mu/DataGridEx';
39
39
  export * from './mu/DataGridRenderers';
40
40
  export * from './mu/DialogButton';
41
+ export * from './mu/DnDList';
41
42
  export * from './mu/DraggablePaperComponent';
42
43
  export * from './mu/EmailInput';
43
44
  export * from './mu/FabBox';
package/lib/index.js CHANGED
@@ -41,6 +41,7 @@ export * from './mu/CustomFabProps';
41
41
  export * from './mu/DataGridEx';
42
42
  export * from './mu/DataGridRenderers';
43
43
  export * from './mu/DialogButton';
44
+ export * from './mu/DnDList';
44
45
  export * from './mu/DraggablePaperComponent';
45
46
  export * from './mu/EmailInput';
46
47
  export * from './mu/FabBox';
@@ -0,0 +1,33 @@
1
+ import { DataTypes } from '@etsoo/shared';
2
+ import React, { CSSProperties } from 'react';
3
+ /**
4
+ * DnD list props
5
+ */
6
+ export interface DnDListProps {
7
+ /**
8
+ * Item renderer
9
+ */
10
+ children: (item: DataTypes.IdItem, index: number, onDelete: (index: number) => void) => React.ReactNode;
11
+ /**
12
+ * Get list item style callback
13
+ */
14
+ getItemStyle?: (isDragging: boolean) => CSSProperties;
15
+ /**
16
+ * Get list style callback
17
+ */
18
+ getListStyle?: (isDraggingOver: boolean) => CSSProperties;
19
+ /**
20
+ * Top and bottom sides renderer
21
+ */
22
+ sideRenderer?: (top: boolean, onAdd: (item: DataTypes.IdItem) => boolean) => React.ReactNode;
23
+ /**
24
+ * Name for hidden form input
25
+ */
26
+ name: string;
27
+ }
28
+ /**
29
+ * Drag and drop list
30
+ * @param props Props
31
+ * @returns Component
32
+ */
33
+ export declare function DnDList(props: DnDListProps): JSX.Element;
@@ -0,0 +1,66 @@
1
+ import { DataTypes } from '@etsoo/shared';
2
+ import React from 'react';
3
+ import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
4
+ /**
5
+ * Drag and drop list
6
+ * @param props Props
7
+ * @returns Component
8
+ */
9
+ export function DnDList(props) {
10
+ // Destruct
11
+ const { children, getItemStyle = (_isDragging) => ({}), getListStyle = () => undefined, name, sideRenderer } = props;
12
+ // State
13
+ const [items, setItems] = React.useState([]);
14
+ // Drag end handler
15
+ const onDragEnd = (result) => {
16
+ console.log(result);
17
+ // Dropped outside the list
18
+ if (!result.destination) {
19
+ return;
20
+ }
21
+ // Clone
22
+ const newItems = [...items];
23
+ // Removed item
24
+ const [removed] = newItems.splice(result.source.index, 1);
25
+ // Insert to the destination index
26
+ newItems.splice(result.destination.index, 0, removed);
27
+ // Update the state
28
+ setItems(newItems);
29
+ };
30
+ // Add handler
31
+ const onAdd = (newItem) => {
32
+ // Existence check
33
+ if (items.some((item) => DataTypes.getItemId(item) === DataTypes.getItemId(newItem))) {
34
+ return false;
35
+ }
36
+ // Clone
37
+ const newItems = [newItem, ...items];
38
+ // Update the state
39
+ setItems(newItems);
40
+ return true;
41
+ };
42
+ // Delete handler
43
+ const onDelete = (index) => {
44
+ // Clone
45
+ const newItems = [...items];
46
+ // Remove the item
47
+ newItems.splice(index, 1);
48
+ // Update the state
49
+ setItems(newItems);
50
+ };
51
+ // Layout
52
+ return (React.createElement(React.Fragment, null,
53
+ sideRenderer && sideRenderer(true, onAdd),
54
+ React.createElement(DragDropContext, { onDragEnd: onDragEnd },
55
+ React.createElement(Droppable, { droppableId: name }, (provided, snapshot) => (React.createElement("div", { ...provided.droppableProps, ref: provided.innerRef, style: getListStyle(snapshot.isDraggingOver) },
56
+ items.map((item, index) => {
57
+ const id = DataTypes.getItemId(item);
58
+ return (React.createElement(Draggable, { key: id, draggableId: id, index: index }, (provided, snapshot) => (React.createElement("div", { ref: provided.innerRef, ...provided.draggableProps, ...provided.dragHandleProps, style: {
59
+ ...getItemStyle(snapshot.isDragging),
60
+ ...provided.draggableProps
61
+ .style
62
+ } }, children(item, index, onDelete)))));
63
+ }),
64
+ provided.placeholder)))),
65
+ sideRenderer && sideRenderer(false, onAdd)));
66
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.3.90",
3
+ "version": "1.3.94",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -50,17 +50,18 @@
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.7",
53
+ "@etsoo/appscript": "^1.2.11",
54
54
  "@etsoo/notificationbase": "^1.0.95",
55
- "@etsoo/shared": "^1.0.94",
55
+ "@etsoo/shared": "^1.0.95",
56
56
  "@mui/icons-material": "^5.2.5",
57
- "@mui/material": "^5.2.5",
57
+ "@mui/material": "^5.2.6",
58
58
  "@reach/router": "^1.3.4",
59
59
  "@types/pica": "^5.1.3",
60
60
  "@types/pulltorefreshjs": "^0.1.5",
61
61
  "@types/reach__router": "^1.3.10",
62
62
  "@types/react": "^17.0.38",
63
63
  "@types/react-avatar-editor": "^10.3.6",
64
+ "@types/react-beautiful-dnd": "^13.1.2",
64
65
  "@types/react-dom": "^17.0.11",
65
66
  "@types/react-input-mask": "^3.0.1",
66
67
  "@types/react-window": "^1.8.5",
@@ -68,6 +69,7 @@
68
69
  "pulltorefreshjs": "^0.1.22",
69
70
  "react": "^17.0.2",
70
71
  "react-avatar-editor": "^12.0.0",
72
+ "react-beautiful-dnd": "^13.1.0",
71
73
  "react-dom": "^17.0.2",
72
74
  "react-draggable": "^4.4.4",
73
75
  "react-imask": "^6.2.2",
@@ -81,8 +83,8 @@
81
83
  "@babel/runtime-corejs3": "^7.16.5",
82
84
  "@types/jest": "^27.0.3",
83
85
  "@types/react-test-renderer": "^17.0.1",
84
- "@typescript-eslint/eslint-plugin": "^5.8.0",
85
- "@typescript-eslint/parser": "^5.8.0",
86
+ "@typescript-eslint/eslint-plugin": "^5.8.1",
87
+ "@typescript-eslint/parser": "^5.8.1",
86
88
  "eslint": "^8.5.0",
87
89
  "eslint-config-airbnb-base": "^15.0.0",
88
90
  "eslint-plugin-import": "^2.25.3",
@@ -21,8 +21,8 @@ import { RefreshTokenRQ } from './RefreshTokenRQ';
21
21
  * Use the new acess token and refresh token to login
22
22
  */
23
23
  export class ServiceApp<
24
- P extends IServicePageData = IServicePageData,
25
24
  U extends IServiceUser = IServiceUser,
25
+ P extends IServicePageData = IServicePageData,
26
26
  S extends IServiceAppSettings = IServiceAppSettings
27
27
  > extends ReactApp<S, U, P> {
28
28
  /**
@@ -76,8 +76,6 @@ export class ServiceApp<
76
76
  coreUrl +
77
77
  '?serviceId=' +
78
78
  this.settings.serviceId +
79
- '&serviceDeviceId=' +
80
- encodeURIComponent(this.deviceId) +
81
79
  '&' +
82
80
  DomUtils.CultureField +
83
81
  '=' +
package/src/index.ts CHANGED
@@ -45,6 +45,7 @@ export * from './mu/CustomFabProps';
45
45
  export * from './mu/DataGridEx';
46
46
  export * from './mu/DataGridRenderers';
47
47
  export * from './mu/DialogButton';
48
+ export * from './mu/DnDList';
48
49
  export * from './mu/DraggablePaperComponent';
49
50
  export * from './mu/EmailInput';
50
51
  export * from './mu/FabBox';
@@ -0,0 +1,170 @@
1
+ import { DataTypes } from '@etsoo/shared';
2
+ import React, { CSSProperties } from 'react';
3
+ import {
4
+ DragDropContext,
5
+ Draggable,
6
+ Droppable,
7
+ DropResult
8
+ } from 'react-beautiful-dnd';
9
+
10
+ /**
11
+ * DnD list props
12
+ */
13
+ export interface DnDListProps {
14
+ /**
15
+ * Item renderer
16
+ */
17
+ children: (
18
+ item: DataTypes.IdItem,
19
+ index: number,
20
+ onDelete: (index: number) => void
21
+ ) => React.ReactNode;
22
+
23
+ /**
24
+ * Get list item style callback
25
+ */
26
+ getItemStyle?: (isDragging: boolean) => CSSProperties;
27
+
28
+ /**
29
+ * Get list style callback
30
+ */
31
+ getListStyle?: (isDraggingOver: boolean) => CSSProperties;
32
+
33
+ /**
34
+ * Top and bottom sides renderer
35
+ */
36
+ sideRenderer?: (
37
+ top: boolean,
38
+ onAdd: (item: DataTypes.IdItem) => boolean
39
+ ) => React.ReactNode;
40
+
41
+ /**
42
+ * Name for hidden form input
43
+ */
44
+ name: string;
45
+ }
46
+
47
+ /**
48
+ * Drag and drop list
49
+ * @param props Props
50
+ * @returns Component
51
+ */
52
+ export function DnDList(props: DnDListProps) {
53
+ // Destruct
54
+ const {
55
+ children,
56
+ getItemStyle = (_isDragging) => ({}),
57
+ getListStyle = () => undefined,
58
+ name,
59
+ sideRenderer
60
+ } = props;
61
+
62
+ // State
63
+ const [items, setItems] = React.useState<DataTypes.IdItem[]>([]);
64
+
65
+ // Drag end handler
66
+ const onDragEnd = (result: DropResult) => {
67
+ console.log(result);
68
+ // Dropped outside the list
69
+ if (!result.destination) {
70
+ return;
71
+ }
72
+
73
+ // Clone
74
+ const newItems = [...items];
75
+
76
+ // Removed item
77
+ const [removed] = newItems.splice(result.source.index, 1);
78
+
79
+ // Insert to the destination index
80
+ newItems.splice(result.destination.index, 0, removed);
81
+
82
+ // Update the state
83
+ setItems(newItems);
84
+ };
85
+
86
+ // Add handler
87
+ const onAdd = (newItem: DataTypes.IdItem) => {
88
+ // Existence check
89
+ if (
90
+ items.some(
91
+ (item) =>
92
+ DataTypes.getItemId(item) === DataTypes.getItemId(newItem)
93
+ )
94
+ ) {
95
+ return false;
96
+ }
97
+
98
+ // Clone
99
+ const newItems = [newItem, ...items];
100
+
101
+ // Update the state
102
+ setItems(newItems);
103
+
104
+ return true;
105
+ };
106
+
107
+ // Delete handler
108
+ const onDelete = (index: number) => {
109
+ // Clone
110
+ const newItems = [...items];
111
+
112
+ // Remove the item
113
+ newItems.splice(index, 1);
114
+
115
+ // Update the state
116
+ setItems(newItems);
117
+ };
118
+
119
+ // Layout
120
+ return (
121
+ <React.Fragment>
122
+ {sideRenderer && sideRenderer(true, onAdd)}
123
+ <DragDropContext onDragEnd={onDragEnd}>
124
+ <Droppable droppableId={name}>
125
+ {(provided, snapshot) => (
126
+ <div
127
+ {...provided.droppableProps}
128
+ ref={provided.innerRef}
129
+ style={getListStyle(snapshot.isDraggingOver)}
130
+ >
131
+ {items.map((item, index) => {
132
+ const id = DataTypes.getItemId(item);
133
+ return (
134
+ <Draggable
135
+ key={id}
136
+ draggableId={id}
137
+ index={index}
138
+ >
139
+ {(provided, snapshot) => (
140
+ <div
141
+ ref={provided.innerRef}
142
+ {...provided.draggableProps}
143
+ {...provided.dragHandleProps}
144
+ style={{
145
+ ...getItemStyle(
146
+ snapshot.isDragging
147
+ ),
148
+ ...provided.draggableProps
149
+ .style
150
+ }}
151
+ >
152
+ {children(
153
+ item,
154
+ index,
155
+ onDelete
156
+ )}
157
+ </div>
158
+ )}
159
+ </Draggable>
160
+ );
161
+ })}
162
+ {provided.placeholder}
163
+ </div>
164
+ )}
165
+ </Droppable>
166
+ </DragDropContext>
167
+ {sideRenderer && sideRenderer(false, onAdd)}
168
+ </React.Fragment>
169
+ );
170
+ }