@etsoo/react 1.4.58 → 1.4.62

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.
@@ -8,6 +8,10 @@ import { IStateProps } from '../states/IState';
8
8
  import { IPageData, PageAction, PageState } from '../states/PageState';
9
9
  import { UserAction, UserState } from '../states/UserState';
10
10
  import { InputDialogProps } from './InputDialogProps';
11
+ /**
12
+ * Global application
13
+ */
14
+ export declare let globalApp: IReactApp<IAppSettings, any, IPageData>;
11
15
  /**
12
16
  * React app state detector
13
17
  * Case 1: undefined, when refresh the whole page
@@ -7,8 +7,10 @@ import { CultureState } from '../states/CultureState';
7
7
  import { PageActionType, PageState } from '../states/PageState';
8
8
  import { UserActionType, UserState } from '../states/UserState';
9
9
  import { Labels } from './Labels';
10
- // Global application
11
- let globalApp;
10
+ /**
11
+ * Global application
12
+ */
13
+ export let globalApp;
12
14
  /**
13
15
  * React app state detector
14
16
  * Case 1: undefined, when refresh the whole page
@@ -1,12 +1,44 @@
1
- /// <reference types="react" />
1
+ import { GridProps } from '@mui/material';
2
+ import React from 'react';
2
3
  import { CommonPageProps } from './CommonPageProps';
4
+ /**
5
+ * View page display field
6
+ */
7
+ export interface ViewPageField<T extends {}> extends GridProps {
8
+ /**
9
+ * Data field
10
+ */
11
+ data: keyof T | ((item: T) => React.ReactNode);
12
+ /**
13
+ * Label field
14
+ */
15
+ label: string | (() => React.ReactNode);
16
+ /**
17
+ * Display as single row
18
+ */
19
+ singleRow?: boolean;
20
+ }
21
+ declare type ViewPageFieldType<T> = (string & keyof T) | ViewPageField<T>;
3
22
  /**
4
23
  * View page props
5
24
  */
6
- export interface ViewPageProps extends CommonPageProps {
25
+ export interface ViewPageProps<T extends {}> extends CommonPageProps {
26
+ /**
27
+ * Fields to display
28
+ */
29
+ fields: ViewPageFieldType<T>[];
30
+ /**
31
+ * Load data
32
+ */
33
+ loadData: () => PromiseLike<T | undefined>;
34
+ /**
35
+ * Support refresh
36
+ */
37
+ supportRefresh?: boolean;
7
38
  }
8
39
  /**
9
40
  * View page
10
41
  * @param props Props
11
42
  */
12
- export declare function ViewPage(props: ViewPageProps): JSX.Element;
43
+ export declare function ViewPage<T extends {}>(props: ViewPageProps<T>): JSX.Element;
44
+ export {};
@@ -1,11 +1,79 @@
1
+ import { Grid, LinearProgress, Typography } from '@mui/material';
1
2
  import React from 'react';
3
+ import { globalApp } from '../../app/ReactApp';
4
+ import { MUGlobal } from '../MUGlobal';
2
5
  import { CommonPage } from './CommonPage';
6
+ function formatItemData(fieldData) {
7
+ if (fieldData == null)
8
+ return undefined;
9
+ if (typeof fieldData === 'string')
10
+ return fieldData;
11
+ if (fieldData instanceof Date)
12
+ return globalApp.formatDate(fieldData, 'd');
13
+ return `${fieldData}`;
14
+ }
15
+ function getItemField(field, data) {
16
+ var _a, _b;
17
+ // Item data and label
18
+ let itemData, itemLabel, gridProps = {};
19
+ if (typeof field === 'object') {
20
+ // Destruct
21
+ const { data: fieldData, label: fieldLabel, singleRow = false, ...rest } = field;
22
+ gridProps = {
23
+ ...rest,
24
+ ...(singleRow && { xs: 12, sm: 12, md: 12, lg: 12, xl: 12 })
25
+ };
26
+ // Field data
27
+ if (typeof fieldData === 'function')
28
+ itemData = fieldData(data);
29
+ else
30
+ itemData = formatItemData(formatItemData);
31
+ // Field label
32
+ itemLabel =
33
+ typeof fieldLabel === 'function'
34
+ ? fieldLabel()
35
+ : (_a = globalApp.get(fieldLabel)) !== null && _a !== void 0 ? _a : fieldLabel;
36
+ }
37
+ else {
38
+ itemData = formatItemData(data[field]);
39
+ itemLabel = (_b = globalApp.get(field)) !== null && _b !== void 0 ? _b : field;
40
+ }
41
+ return [
42
+ itemData,
43
+ itemLabel,
44
+ { xs: 12, sm: 6, md: 6, lg: 4, xl: 3, ...gridProps }
45
+ ];
46
+ }
3
47
  /**
4
48
  * View page
5
49
  * @param props Props
6
50
  */
7
51
  export function ViewPage(props) {
8
52
  // Destruct
9
- const { ...rest } = props;
10
- return React.createElement(CommonPage, { ...rest, scrollContainer: global });
53
+ const { children, fields, loadData, paddings = MUGlobal.pagePaddings, supportRefresh = true, ...rest } = props;
54
+ // Data
55
+ const [data, setData] = React.useState();
56
+ // Load data
57
+ const onRefresh = async () => {
58
+ const result = await loadData();
59
+ if (result == null)
60
+ return;
61
+ setData(result);
62
+ };
63
+ return (React.createElement(CommonPage, { paddings: paddings, onRefresh: supportRefresh ? onRefresh : undefined, onUpdate: supportRefresh ? undefined : onRefresh, ...rest, scrollContainer: global }, data == null ? (React.createElement(LinearProgress, null)) : (React.createElement(React.Fragment, null,
64
+ React.createElement(Grid, { container: true, justifyContent: "left", spacing: paddings, sx: {
65
+ '.MuiTypography-subtitle2': { fontWeight: 'bold' }
66
+ } }, fields.map((field, index) => {
67
+ // Get data
68
+ const [itemData, itemLabel, gridProps] = getItemField(field, data);
69
+ if (itemData == null)
70
+ return undefined;
71
+ // Layout
72
+ return (React.createElement(Grid, { item: true, ...gridProps, key: index },
73
+ React.createElement(Typography, { variant: "caption", component: "div" },
74
+ itemLabel,
75
+ ":"),
76
+ React.createElement(Typography, { variant: "subtitle2" }, itemData)));
77
+ })),
78
+ children))));
11
79
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.4.58",
3
+ "version": "1.4.62",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -77,7 +77,7 @@
77
77
  },
78
78
  "devDependencies": {
79
79
  "@babel/cli": "^7.16.8",
80
- "@babel/core": "^7.16.10",
80
+ "@babel/core": "^7.16.12",
81
81
  "@babel/plugin-transform-runtime": "^7.16.10",
82
82
  "@babel/preset-env": "^7.16.11",
83
83
  "@babel/runtime-corejs3": "^7.16.8",
@@ -34,8 +34,10 @@ import {
34
34
  import { InputDialogProps } from './InputDialogProps';
35
35
  import { Labels } from './Labels';
36
36
 
37
- // Global application
38
- let globalApp: IReactApp<IAppSettings, any, IPageData>;
37
+ /**
38
+ * Global application
39
+ */
40
+ export let globalApp: IReactApp<IAppSettings, any, IPageData>;
39
41
 
40
42
  /**
41
43
  * React app state detector
@@ -1,19 +1,174 @@
1
+ import { Grid, GridProps, LinearProgress, Typography } from '@mui/material';
1
2
  import React from 'react';
3
+ import { globalApp } from '../../app/ReactApp';
4
+ import { MUGlobal } from '../MUGlobal';
2
5
  import { CommonPage } from './CommonPage';
3
6
  import { CommonPageProps } from './CommonPageProps';
4
7
 
8
+ /**
9
+ * View page display field
10
+ */
11
+ export interface ViewPageField<T extends {}> extends GridProps {
12
+ /**
13
+ * Data field
14
+ */
15
+ data: keyof T | ((item: T) => React.ReactNode);
16
+
17
+ /**
18
+ * Label field
19
+ */
20
+ label: string | (() => React.ReactNode);
21
+
22
+ /**
23
+ * Display as single row
24
+ */
25
+ singleRow?: boolean;
26
+ }
27
+
28
+ type ViewPageFieldType<T> = (string & keyof T) | ViewPageField<T>;
29
+
5
30
  /**
6
31
  * View page props
7
32
  */
8
- export interface ViewPageProps extends CommonPageProps {}
33
+ export interface ViewPageProps<T extends {}> extends CommonPageProps {
34
+ /**
35
+ * Fields to display
36
+ */
37
+ fields: ViewPageFieldType<T>[];
38
+
39
+ /**
40
+ * Load data
41
+ */
42
+ loadData: () => PromiseLike<T | undefined>;
43
+
44
+ /**
45
+ * Support refresh
46
+ */
47
+ supportRefresh?: boolean;
48
+ }
49
+
50
+ function formatItemData(fieldData: unknown): string | undefined {
51
+ if (fieldData == null) return undefined;
52
+ if (typeof fieldData === 'string') return fieldData;
53
+ if (fieldData instanceof Date) return globalApp.formatDate(fieldData, 'd');
54
+ return `${fieldData}`;
55
+ }
56
+
57
+ function getItemField<T>(
58
+ field: ViewPageFieldType<T>,
59
+ data: T
60
+ ): [React.ReactNode, React.ReactNode, GridProps] {
61
+ // Item data and label
62
+ let itemData: React.ReactNode,
63
+ itemLabel: React.ReactNode,
64
+ gridProps: GridProps = {};
65
+
66
+ if (typeof field === 'object') {
67
+ // Destruct
68
+ const {
69
+ data: fieldData,
70
+ label: fieldLabel,
71
+ singleRow = false,
72
+ ...rest
73
+ } = field;
74
+
75
+ gridProps = {
76
+ ...rest,
77
+ ...(singleRow && { xs: 12, sm: 12, md: 12, lg: 12, xl: 12 })
78
+ };
79
+
80
+ // Field data
81
+ if (typeof fieldData === 'function') itemData = fieldData(data);
82
+ else itemData = formatItemData(formatItemData);
83
+
84
+ // Field label
85
+ itemLabel =
86
+ typeof fieldLabel === 'function'
87
+ ? fieldLabel()
88
+ : globalApp.get<string>(fieldLabel) ?? fieldLabel;
89
+ } else {
90
+ itemData = formatItemData(data[field]);
91
+ itemLabel = globalApp.get<string>(field) ?? field;
92
+ }
93
+
94
+ return [
95
+ itemData,
96
+ itemLabel,
97
+ { xs: 12, sm: 6, md: 6, lg: 4, xl: 3, ...gridProps }
98
+ ];
99
+ }
9
100
 
10
101
  /**
11
102
  * View page
12
103
  * @param props Props
13
104
  */
14
- export function ViewPage(props: ViewPageProps) {
105
+ export function ViewPage<T extends {}>(props: ViewPageProps<T>) {
15
106
  // Destruct
16
- const { ...rest } = props;
107
+ const {
108
+ children,
109
+ fields,
110
+ loadData,
111
+ paddings = MUGlobal.pagePaddings,
112
+ supportRefresh = true,
113
+ ...rest
114
+ } = props;
115
+
116
+ // Data
117
+ const [data, setData] = React.useState<T>();
118
+
119
+ // Load data
120
+ const onRefresh = async () => {
121
+ const result = await loadData();
122
+ if (result == null) return;
123
+ setData(result);
124
+ };
125
+
126
+ return (
127
+ <CommonPage
128
+ paddings={paddings}
129
+ onRefresh={supportRefresh ? onRefresh : undefined}
130
+ onUpdate={supportRefresh ? undefined : onRefresh}
131
+ {...rest}
132
+ scrollContainer={global}
133
+ >
134
+ {data == null ? (
135
+ <LinearProgress />
136
+ ) : (
137
+ <React.Fragment>
138
+ <Grid
139
+ container
140
+ justifyContent="left"
141
+ spacing={paddings}
142
+ sx={{
143
+ '.MuiTypography-subtitle2': { fontWeight: 'bold' }
144
+ }}
145
+ >
146
+ {fields.map((field, index) => {
147
+ // Get data
148
+ const [itemData, itemLabel, gridProps] =
149
+ getItemField(field, data);
150
+
151
+ if (itemData == null) return undefined;
17
152
 
18
- return <CommonPage {...rest} scrollContainer={global}></CommonPage>;
153
+ // Layout
154
+ return (
155
+ <Grid item {...gridProps} key={index}>
156
+ <Typography
157
+ variant="caption"
158
+ component="div"
159
+ >
160
+ {itemLabel}:
161
+ </Typography>
162
+ <Typography variant="subtitle2">
163
+ {itemData}
164
+ </Typography>
165
+ </Grid>
166
+ );
167
+ })}
168
+ </Grid>
169
+ {children}
170
+ </React.Fragment>
171
+ )}
172
+ </CommonPage>
173
+ );
19
174
  }