@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.
- package/lib/app/ReactApp.d.ts +4 -0
- package/lib/app/ReactApp.js +4 -2
- package/lib/mu/pages/ViewPage.d.ts +35 -3
- package/lib/mu/pages/ViewPage.js +70 -2
- package/package.json +2 -2
- package/src/app/ReactApp.ts +4 -2
- package/src/mu/pages/ViewPage.tsx +159 -4
package/lib/app/ReactApp.d.ts
CHANGED
|
@@ -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
|
package/lib/app/ReactApp.js
CHANGED
|
@@ -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
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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 {};
|
package/lib/mu/pages/ViewPage.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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.
|
|
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",
|
package/src/app/ReactApp.ts
CHANGED
|
@@ -34,8 +34,10 @@ import {
|
|
|
34
34
|
import { InputDialogProps } from './InputDialogProps';
|
|
35
35
|
import { Labels } from './Labels';
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
}
|