@etsoo/react 1.4.2 → 1.4.6

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,4 +11,4 @@ export interface IServiceUser extends IUser {
11
11
  /**
12
12
  * Service user login result
13
13
  */
14
- export declare type ServiceLoginResult = IActionResult<IServiceUser>;
14
+ export declare type ServiceLoginResult<U extends IServiceUser = IServiceUser> = IActionResult<U>;
@@ -1,5 +1,5 @@
1
- import { CoreApp, IAppSettings, ICoreApp, IUser, IUserData } from '@etsoo/appscript';
2
- import { NotificationRenderProps } from '@etsoo/notificationbase';
1
+ import { CoreApp, IActionResult, IAppSettings, ICoreApp, IUser, IUserData } from '@etsoo/appscript';
2
+ import { NotificationRenderProps, NotificationReturn } from '@etsoo/notificationbase';
3
3
  import { DataTypes } from '@etsoo/shared';
4
4
  import React from 'react';
5
5
  import { NotificationReactCallProps } from '../notifier/Notifier';
@@ -87,6 +87,12 @@ export declare class ReactApp<S extends IAppSettings, D extends IUser, P extends
87
87
  * @param name Application name
88
88
  */
89
89
  constructor(settings: S, name: string);
90
+ /**
91
+ * Override alert action result
92
+ * @param result Action result
93
+ * @param callback Callback
94
+ */
95
+ alertResult(result: IActionResult, callback?: NotificationReturn<void>): void;
90
96
  /**
91
97
  * Change culture
92
98
  * @param culture New culture definition
@@ -1,4 +1,4 @@
1
- import { CoreApp, createClient } from '@etsoo/appscript';
1
+ import { ActionResultError, CoreApp, createClient } from '@etsoo/appscript';
2
2
  import { WindowStorage } from '@etsoo/shared';
3
3
  import React from 'react';
4
4
  import { NotifierMU } from '../mu/NotifierMU';
@@ -83,6 +83,26 @@ export class ReactApp extends CoreApp {
83
83
  ReactApp._notifierProvider = NotifierMU.setup();
84
84
  return NotifierMU.instance;
85
85
  }
86
+ /**
87
+ * Override alert action result
88
+ * @param result Action result
89
+ * @param callback Callback
90
+ */
91
+ alertResult(result, callback) {
92
+ this.formatResult(result);
93
+ const message = ActionResultError.format(result);
94
+ if (message.endsWith(')')) {
95
+ const startPos = message.lastIndexOf('(');
96
+ if (startPos > 0) {
97
+ const main = message.substring(0, startPos).trim();
98
+ const tip = message.substring(startPos);
99
+ const titleNode = React.createElement(React.Fragment, null, main, React.createElement('div', { style: { fontSize: '9px' } }, tip));
100
+ this.notifier.alert(titleNode, callback);
101
+ return;
102
+ }
103
+ }
104
+ this.notifier.alert(message, callback);
105
+ }
86
106
  /**
87
107
  * Change culture
88
108
  * @param culture New culture definition
@@ -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<U extends IServiceUser = IServiceUser, P extends IServicePageData = IServicePageData, 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, ISmartERPUser, P> {
15
15
  /**
16
16
  * Service API
17
17
  */
@@ -20,8 +20,8 @@ export declare class ServiceApp<U extends IServiceUser = IServiceUser, P extends
20
20
  /**
21
21
  * Service user
22
22
  */
23
- get serviceUser(): IServiceUser | undefined;
24
- protected set serviceUser(value: IServiceUser | undefined);
23
+ get serviceUser(): U | undefined;
24
+ protected set serviceUser(value: U | undefined);
25
25
  /**
26
26
  * Service passphrase
27
27
  */
@@ -67,5 +67,5 @@ export declare class ServiceApp<U extends IServiceUser = IServiceUser, P extends
67
67
  * @param refreshToken Refresh token
68
68
  * @param serviceUser Service user
69
69
  */
70
- userLoginEx(user: ISmartERPUser, refreshToken: string, serviceUser: IServiceUser): void;
70
+ userLoginEx(user: ISmartERPUser, refreshToken: string, serviceUser: U): void;
71
71
  }
package/lib/index.d.ts CHANGED
@@ -14,7 +14,6 @@ export * from './components/GridLoader';
14
14
  export * from './components/ListItemReact';
15
15
  export * from './components/ScrollerGrid';
16
16
  export * from './components/ScrollerList';
17
- export * from './mu/pages/AddPage';
18
17
  export * from './mu/pages/CommonPage';
19
18
  export * from './mu/pages/CommonPageProps';
20
19
  export * from './mu/pages/DataGridPage';
package/lib/index.js CHANGED
@@ -17,7 +17,6 @@ export * from './components/ListItemReact';
17
17
  export * from './components/ScrollerGrid';
18
18
  export * from './components/ScrollerList';
19
19
  // mu
20
- export * from './mu/pages/AddPage';
21
20
  export * from './mu/pages/CommonPage';
22
21
  export * from './mu/pages/CommonPageProps';
23
22
  export * from './mu/pages/DataGridPage';
@@ -32,6 +32,10 @@ export interface DnDListProps<D extends {}, E extends React.ElementType> {
32
32
  * Load data
33
33
  */
34
34
  loadData: (name: string) => PromiseLike<D[]>;
35
+ /**
36
+ * Data change handler
37
+ */
38
+ onChange?: (items: D[]) => void;
35
39
  /**
36
40
  * Top and bottom sides renderer
37
41
  */
package/lib/mu/DnDList.js CHANGED
@@ -9,9 +9,16 @@ import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
9
9
  */
10
10
  export function DnDList(props) {
11
11
  // Destruct
12
- const { children, Component = 'div', componentProps, getItemStyle = (_isDragging) => ({}), getListStyle = () => undefined, labelField, loadData, name, sideRenderer } = props;
12
+ const { children, Component = 'div', componentProps, getItemStyle = (_isDragging) => ({}), getListStyle = () => undefined, labelField, loadData, name, onChange, sideRenderer } = props;
13
13
  // State
14
14
  const [items, setItems] = React.useState([]);
15
+ const changeItems = (items) => {
16
+ // Possible to alter items with the handler
17
+ if (onChange)
18
+ onChange(items);
19
+ // Update state
20
+ setItems(items);
21
+ };
15
22
  // Drag end handler
16
23
  const onDragEnd = (result) => {
17
24
  // Dropped outside the list
@@ -25,7 +32,7 @@ export function DnDList(props) {
25
32
  // Insert to the destination index
26
33
  newItems.splice(result.destination.index, 0, removed);
27
34
  // Update the state
28
- setItems(newItems);
35
+ changeItems(newItems);
29
36
  };
30
37
  // Add item
31
38
  const addItem = (newItem) => {
@@ -36,7 +43,7 @@ export function DnDList(props) {
36
43
  // Clone
37
44
  const newItems = [newItem, ...items];
38
45
  // Update the state
39
- setItems(newItems);
46
+ changeItems(newItems);
40
47
  return true;
41
48
  };
42
49
  // Edit item
@@ -50,7 +57,7 @@ export function DnDList(props) {
50
57
  // Remove the item
51
58
  newItems.splice(index, 1, newItem);
52
59
  // Update the state
53
- setItems(newItems);
60
+ changeItems(newItems);
54
61
  return true;
55
62
  };
56
63
  // Add items
@@ -66,7 +73,7 @@ export function DnDList(props) {
66
73
  newItems.push(newItem);
67
74
  });
68
75
  // Update the state
69
- setItems(newItems);
76
+ changeItems(newItems);
70
77
  return newItems.length - items.length;
71
78
  };
72
79
  // Delete item
@@ -76,9 +83,10 @@ export function DnDList(props) {
76
83
  // Remove the item
77
84
  newItems.splice(index, 1);
78
85
  // Update the state
79
- setItems(newItems);
86
+ changeItems(newItems);
80
87
  };
81
88
  React.useEffect(() => {
89
+ // Load data
82
90
  loadData(name).then((items) => setItems(items));
83
91
  }, [name]);
84
92
  // Layout
@@ -1,15 +1,7 @@
1
- import { DataTypes } from '@etsoo/shared';
2
- import { RouteComponentProps } from '@reach/router';
3
1
  import { FormEventHandler } from 'react';
4
2
  import { CommonPageProps } from './CommonPageProps';
5
3
  /**
6
- * Edit page router props, include 'id' (/:id) query parameter
7
- */
8
- export declare type EditPageRouterProps<T extends DataTypes.IdType = number> = RouteComponentProps<{
9
- id: T;
10
- }>;
11
- /**
12
- * Edit page props
4
+ * Add / Edit page props
13
5
  */
14
6
  export interface EditPageProps extends Omit<CommonPageProps, 'onSubmit'> {
15
7
  /**
@@ -18,7 +10,7 @@ export interface EditPageProps extends Omit<CommonPageProps, 'onSubmit'> {
18
10
  onSubmit?: FormEventHandler<HTMLFormElement>;
19
11
  }
20
12
  /**
21
- * Edit page
13
+ * Add / Edit page
22
14
  * @param props Props
23
15
  */
24
16
  export declare function EditPage(props: EditPageProps): JSX.Element;
@@ -5,7 +5,7 @@ import { MUGlobal } from '../MUGlobal';
5
5
  import { CommonPage, CommonPageScrollContainer } from './CommonPage';
6
6
  import SaveIcon from '@mui/icons-material/Save';
7
7
  /**
8
- * Edit page
8
+ * Add / Edit page
9
9
  * @param props Props
10
10
  */
11
11
  export function EditPage(props) {
@@ -1,11 +1,21 @@
1
1
  import { DataTypes } from '@etsoo/shared';
2
2
  import { RouteComponentProps } from '@reach/router';
3
+ /**
4
+ * Add / Edit page router props, include 'id' (/:id) or none when adding query parameter
5
+ */
6
+ export declare type EditPageRouterProps<T extends DataTypes.IdType = number> = IdRouterProps<T> & WildcardRouterProps<T>;
3
7
  /**
4
8
  * Id router props, include 'id' (/:id) query parameter
5
9
  */
6
10
  export declare type IdRouterProps<T extends DataTypes.IdType = number> = RouteComponentProps<{
7
11
  id: T;
8
12
  }>;
13
+ /**
14
+ * Wildcard router props, (/*) query parameter
15
+ */
16
+ export declare type WildcardRouterProps<T extends DataTypes.Basic = string> = RouteComponentProps<{
17
+ '*': T;
18
+ }>;
9
19
  /**
10
20
  * Id state router props, include 'id' in location.state
11
21
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.4.2",
3
+ "version": "1.4.6",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -50,11 +50,11 @@
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.15",
53
+ "@etsoo/appscript": "^1.2.18",
54
54
  "@etsoo/notificationbase": "^1.1.0",
55
- "@etsoo/shared": "^1.0.97",
55
+ "@etsoo/shared": "^1.1.0",
56
56
  "@mui/icons-material": "^5.2.5",
57
- "@mui/material": "^5.2.6",
57
+ "@mui/material": "^5.2.7",
58
58
  "@reach/router": "^1.3.4",
59
59
  "@types/pica": "^5.1.3",
60
60
  "@types/pulltorefreshjs": "^0.1.5",
@@ -83,11 +83,11 @@
83
83
  "@babel/runtime-corejs3": "^7.16.7",
84
84
  "@types/jest": "^27.4.0",
85
85
  "@types/react-test-renderer": "^17.0.1",
86
- "@typescript-eslint/eslint-plugin": "^5.8.1",
87
- "@typescript-eslint/parser": "^5.8.1",
88
- "eslint": "^8.5.0",
86
+ "@typescript-eslint/eslint-plugin": "^5.9.0",
87
+ "@typescript-eslint/parser": "^5.9.0",
88
+ "eslint": "^8.6.0",
89
89
  "eslint-config-airbnb-base": "^15.0.0",
90
- "eslint-plugin-import": "^2.25.3",
90
+ "eslint-plugin-import": "^2.25.4",
91
91
  "eslint-plugin-react": "^7.28.0",
92
92
  "jest": "^27.4.5",
93
93
  "react-test-renderer": "^17.0.2",
@@ -13,4 +13,5 @@ export interface IServiceUser extends IUser {
13
13
  /**
14
14
  * Service user login result
15
15
  */
16
- export type ServiceLoginResult = IActionResult<IServiceUser>;
16
+ export type ServiceLoginResult<U extends IServiceUser = IServiceUser> =
17
+ IActionResult<U>;
@@ -1,12 +1,17 @@
1
1
  import {
2
+ ActionResultError,
2
3
  CoreApp,
3
4
  createClient,
5
+ IActionResult,
4
6
  IAppSettings,
5
7
  ICoreApp,
6
8
  IUser,
7
9
  IUserData
8
10
  } from '@etsoo/appscript';
9
- import { NotificationRenderProps } from '@etsoo/notificationbase';
11
+ import {
12
+ NotificationRenderProps,
13
+ NotificationReturn
14
+ } from '@etsoo/notificationbase';
10
15
  import { DataTypes, WindowStorage } from '@etsoo/shared';
11
16
  import React from 'react';
12
17
  import { NotifierMU } from '../mu/NotifierMU';
@@ -197,6 +202,40 @@ export class ReactApp<
197
202
  globalApp = this;
198
203
  }
199
204
 
205
+ /**
206
+ * Override alert action result
207
+ * @param result Action result
208
+ * @param callback Callback
209
+ */
210
+ override alertResult(
211
+ result: IActionResult,
212
+ callback?: NotificationReturn<void>
213
+ ) {
214
+ this.formatResult(result);
215
+ const message = ActionResultError.format(result);
216
+ if (message.endsWith(')')) {
217
+ const startPos = message.lastIndexOf('(');
218
+ if (startPos > 0) {
219
+ const main = message.substring(0, startPos).trim();
220
+ const tip = message.substring(startPos);
221
+
222
+ const titleNode = React.createElement(
223
+ React.Fragment,
224
+ null,
225
+ main,
226
+ React.createElement(
227
+ 'div',
228
+ { style: { fontSize: '9px' } },
229
+ tip
230
+ )
231
+ );
232
+ this.notifier.alert(titleNode, callback);
233
+ return;
234
+ }
235
+ }
236
+ this.notifier.alert(message, callback);
237
+ }
238
+
200
239
  /**
201
240
  * Change culture
202
241
  * @param culture New culture definition
@@ -24,20 +24,20 @@ export class ServiceApp<
24
24
  U extends IServiceUser = IServiceUser,
25
25
  P extends IServicePageData = IServicePageData,
26
26
  S extends IServiceAppSettings = IServiceAppSettings
27
- > extends ReactApp<S, U, P> {
27
+ > extends ReactApp<S, ISmartERPUser, P> {
28
28
  /**
29
29
  * Service API
30
30
  */
31
31
  readonly serviceApi: IApi;
32
32
 
33
- private _serviceUser?: IServiceUser;
33
+ private _serviceUser?: U;
34
34
  /**
35
35
  * Service user
36
36
  */
37
37
  get serviceUser() {
38
38
  return this._serviceUser;
39
39
  }
40
- protected set serviceUser(value: IServiceUser | undefined) {
40
+ protected set serviceUser(value: U | undefined) {
41
41
  this._serviceUser = value;
42
42
  }
43
43
 
@@ -140,7 +140,9 @@ export class ServiceApp<
140
140
  const userData = result.data;
141
141
 
142
142
  // Use core system access token to service api to exchange service access token
143
- const serviceResult = await this.serviceApi.put<ServiceLoginResult>(
143
+ const serviceResult = await this.serviceApi.put<
144
+ ServiceLoginResult<U>
145
+ >(
144
146
  'Auth/ExchangeToken',
145
147
  {
146
148
  token: this.encryptEnhanced(
@@ -322,7 +324,7 @@ export class ServiceApp<
322
324
  userLoginEx(
323
325
  user: ISmartERPUser,
324
326
  refreshToken: string,
325
- serviceUser: IServiceUser
327
+ serviceUser: U
326
328
  ): void {
327
329
  // Service user login
328
330
  this.servicePassphrase =
package/src/index.ts CHANGED
@@ -19,7 +19,6 @@ export * from './components/ScrollerGrid';
19
19
  export * from './components/ScrollerList';
20
20
 
21
21
  // mu
22
- export * from './mu/pages/AddPage';
23
22
  export * from './mu/pages/CommonPage';
24
23
  export * from './mu/pages/CommonPageProps';
25
24
  export * from './mu/pages/DataGridPage';
@@ -52,6 +52,11 @@ export interface DnDListProps<D extends {}, E extends React.ElementType> {
52
52
  */
53
53
  loadData: (name: string) => PromiseLike<D[]>;
54
54
 
55
+ /**
56
+ * Data change handler
57
+ */
58
+ onChange?: (items: D[]) => void;
59
+
55
60
  /**
56
61
  * Top and bottom sides renderer
57
62
  */
@@ -87,12 +92,21 @@ export function DnDList<
87
92
  labelField,
88
93
  loadData,
89
94
  name,
95
+ onChange,
90
96
  sideRenderer
91
97
  } = props;
92
98
 
93
99
  // State
94
100
  const [items, setItems] = React.useState<D[]>([]);
95
101
 
102
+ const changeItems = (items: D[]) => {
103
+ // Possible to alter items with the handler
104
+ if (onChange) onChange(items);
105
+
106
+ // Update state
107
+ setItems(items);
108
+ };
109
+
96
110
  // Drag end handler
97
111
  const onDragEnd = (result: DropResult) => {
98
112
  // Dropped outside the list
@@ -110,7 +124,7 @@ export function DnDList<
110
124
  newItems.splice(result.destination.index, 0, removed);
111
125
 
112
126
  // Update the state
113
- setItems(newItems);
127
+ changeItems(newItems);
114
128
  };
115
129
 
116
130
  // Add item
@@ -124,7 +138,7 @@ export function DnDList<
124
138
  const newItems = [newItem, ...items];
125
139
 
126
140
  // Update the state
127
- setItems(newItems);
141
+ changeItems(newItems);
128
142
 
129
143
  return true;
130
144
  };
@@ -143,7 +157,7 @@ export function DnDList<
143
157
  newItems.splice(index, 1, newItem);
144
158
 
145
159
  // Update the state
146
- setItems(newItems);
160
+ changeItems(newItems);
147
161
 
148
162
  return true;
149
163
  };
@@ -166,7 +180,7 @@ export function DnDList<
166
180
  });
167
181
 
168
182
  // Update the state
169
- setItems(newItems);
183
+ changeItems(newItems);
170
184
 
171
185
  return newItems.length - items.length;
172
186
  };
@@ -180,10 +194,11 @@ export function DnDList<
180
194
  newItems.splice(index, 1);
181
195
 
182
196
  // Update the state
183
- setItems(newItems);
197
+ changeItems(newItems);
184
198
  };
185
199
 
186
200
  React.useEffect(() => {
201
+ // Load data
187
202
  loadData(name).then((items) => setItems(items));
188
203
  }, [name]);
189
204
 
@@ -1,6 +1,4 @@
1
- import { DataTypes } from '@etsoo/shared';
2
1
  import { Button, Grid } from '@mui/material';
3
- import { RouteComponentProps } from '@reach/router';
4
2
  import React, { FormEventHandler } from 'react';
5
3
  import { Labels } from '../../app/Labels';
6
4
  import { MUGlobal } from '../MUGlobal';
@@ -9,13 +7,7 @@ import { CommonPageProps } from './CommonPageProps';
9
7
  import SaveIcon from '@mui/icons-material/Save';
10
8
 
11
9
  /**
12
- * Edit page router props, include 'id' (/:id) query parameter
13
- */
14
- export type EditPageRouterProps<T extends DataTypes.IdType = number> =
15
- RouteComponentProps<{ id: T }>;
16
-
17
- /**
18
- * Edit page props
10
+ * Add / Edit page props
19
11
  */
20
12
  export interface EditPageProps extends Omit<CommonPageProps, 'onSubmit'> {
21
13
  /**
@@ -25,7 +17,7 @@ export interface EditPageProps extends Omit<CommonPageProps, 'onSubmit'> {
25
17
  }
26
18
 
27
19
  /**
28
- * Edit page
20
+ * Add / Edit page
29
21
  * @param props Props
30
22
  */
31
23
  export function EditPage(props: EditPageProps) {
@@ -1,12 +1,24 @@
1
1
  import { DataTypes } from '@etsoo/shared';
2
2
  import { RouteComponentProps } from '@reach/router';
3
3
 
4
+ /**
5
+ * Add / Edit page router props, include 'id' (/:id) or none when adding query parameter
6
+ */
7
+ export type EditPageRouterProps<T extends DataTypes.IdType = number> =
8
+ IdRouterProps<T> & WildcardRouterProps<T>;
9
+
4
10
  /**
5
11
  * Id router props, include 'id' (/:id) query parameter
6
12
  */
7
13
  export type IdRouterProps<T extends DataTypes.IdType = number> =
8
14
  RouteComponentProps<{ id: T }>;
9
15
 
16
+ /**
17
+ * Wildcard router props, (/*) query parameter
18
+ */
19
+ export type WildcardRouterProps<T extends DataTypes.Basic = string> =
20
+ RouteComponentProps<{ '*': T }>;
21
+
10
22
  /**
11
23
  * Id state router props, include 'id' in location.state
12
24
  */
@@ -1,11 +0,0 @@
1
- import { CommonPageProps } from './CommonPageProps';
2
- /**
3
- * Add page props
4
- */
5
- export interface AddPageProps extends CommonPageProps {
6
- }
7
- /**
8
- * Add page
9
- * @param props Props
10
- */
11
- export declare function AddPage(props: AddPageProps): void;
@@ -1,5 +0,0 @@
1
- /**
2
- * Add page
3
- * @param props Props
4
- */
5
- export function AddPage(props) { }
@@ -1,12 +0,0 @@
1
- import { CommonPageProps } from './CommonPageProps';
2
-
3
- /**
4
- * Add page props
5
- */
6
- export interface AddPageProps extends CommonPageProps {}
7
-
8
- /**
9
- * Add page
10
- * @param props Props
11
- */
12
- export function AddPage(props: AddPageProps) {}