@etsoo/react 1.5.9 → 1.5.13
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/Labels.d.ts +1 -0
- package/lib/app/Labels.js +1 -0
- package/lib/app/ReactApp.d.ts +13 -0
- package/lib/app/ReactApp.js +28 -3
- package/lib/app/ServiceApp.d.ts +6 -0
- package/lib/app/ServiceApp.js +8 -0
- package/lib/app/Utils.d.ts +2 -1
- package/lib/app/Utils.js +3 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/mu/BackButton.d.ts +13 -0
- package/lib/mu/BackButton.js +29 -0
- package/lib/mu/BridgeCloseButton.d.ts +5 -1
- package/lib/mu/BridgeCloseButton.js +5 -9
- package/lib/mu/pages/CommonPage.js +4 -2
- package/lib/mu/pages/CommonPageProps.d.ts +5 -1
- package/lib/mu/pages/EditPage.d.ts +5 -0
- package/lib/mu/pages/EditPage.js +4 -2
- package/lib/mu/pages/ViewPage.js +2 -2
- package/package.json +1 -1
- package/src/app/Labels.ts +1 -0
- package/src/app/ReactApp.ts +31 -6
- package/src/app/ServiceApp.ts +9 -0
- package/src/app/Utils.ts +3 -2
- package/src/index.ts +1 -0
- package/src/mu/BackButton.tsx +51 -0
- package/src/mu/BridgeCloseButton.tsx +17 -16
- package/src/mu/pages/CommonPage.tsx +5 -0
- package/src/mu/pages/CommonPageProps.ts +6 -1
- package/src/mu/pages/EditPage.tsx +9 -0
- package/src/mu/pages/ViewPage.tsx +5 -1
package/lib/app/Labels.d.ts
CHANGED
package/lib/app/Labels.js
CHANGED
package/lib/app/ReactApp.d.ts
CHANGED
|
@@ -108,6 +108,19 @@ export declare class ReactApp<S extends IAppSettings, D extends IUser, P extends
|
|
|
108
108
|
* @param name Application name
|
|
109
109
|
*/
|
|
110
110
|
constructor(settings: S, name: string);
|
|
111
|
+
/**
|
|
112
|
+
* Get parsed Url under bridge host
|
|
113
|
+
* @param url Url
|
|
114
|
+
* @returns Parsed Url
|
|
115
|
+
*/
|
|
116
|
+
protected getHostUrl(url: string): string;
|
|
117
|
+
/**
|
|
118
|
+
* Get parsed Url under bridge host
|
|
119
|
+
* @param url Url
|
|
120
|
+
* @param name App name in the host environment
|
|
121
|
+
* @returns Parsed Url
|
|
122
|
+
*/
|
|
123
|
+
protected getHostUrlBase(url: string, name: string): string;
|
|
111
124
|
/**
|
|
112
125
|
* Override alert action result
|
|
113
126
|
* @param result Action result
|
package/lib/app/ReactApp.js
CHANGED
|
@@ -26,8 +26,8 @@ export function ReactAppStateDetector(props) {
|
|
|
26
26
|
// Destruct
|
|
27
27
|
const { targetFields, update } = props;
|
|
28
28
|
// Context
|
|
29
|
-
const { state } = globalApp == null
|
|
30
|
-
? {
|
|
29
|
+
const { state = {} } = globalApp == null
|
|
30
|
+
? {}
|
|
31
31
|
: React.useContext(globalApp.userState.context);
|
|
32
32
|
// Ready
|
|
33
33
|
React.useEffect(() => {
|
|
@@ -67,7 +67,7 @@ export class ReactApp extends CoreApp {
|
|
|
67
67
|
this.userState = new UserState();
|
|
68
68
|
this.history =
|
|
69
69
|
window.location.hostname === ''
|
|
70
|
-
? Utils.getMemoryHistory()
|
|
70
|
+
? Utils.getMemoryHistory(this.getHostUrl(window.location.href))
|
|
71
71
|
: undefined;
|
|
72
72
|
this.cultureState = new CultureState(settings.currentCulture);
|
|
73
73
|
this.pageState = new PageState();
|
|
@@ -91,6 +91,31 @@ export class ReactApp extends CoreApp {
|
|
|
91
91
|
ReactApp._notifierProvider = NotifierMU.setup();
|
|
92
92
|
return NotifierMU.instance;
|
|
93
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Get parsed Url under bridge host
|
|
96
|
+
* @param url Url
|
|
97
|
+
* @returns Parsed Url
|
|
98
|
+
*/
|
|
99
|
+
getHostUrl(url) {
|
|
100
|
+
return this.getHostUrlBase(url, 'core');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get parsed Url under bridge host
|
|
104
|
+
* @param url Url
|
|
105
|
+
* @param name App name in the host environment
|
|
106
|
+
* @returns Parsed Url
|
|
107
|
+
*/
|
|
108
|
+
getHostUrlBase(url, name) {
|
|
109
|
+
if (url.startsWith('/'))
|
|
110
|
+
return url;
|
|
111
|
+
const identifier = `/${name}/`;
|
|
112
|
+
const pos = url.indexOf(identifier);
|
|
113
|
+
if (pos === -1)
|
|
114
|
+
return '/';
|
|
115
|
+
return url
|
|
116
|
+
.substring(pos + identifier.length - 1)
|
|
117
|
+
.replace('/index.html', '/'); // Router take / as start
|
|
118
|
+
}
|
|
94
119
|
/**
|
|
95
120
|
* Override alert action result
|
|
96
121
|
* @param result Action result
|
package/lib/app/ServiceApp.d.ts
CHANGED
|
@@ -32,6 +32,12 @@ export declare class ServiceApp<U extends IServiceUser = IServiceUser, P extends
|
|
|
32
32
|
* @param name Application name
|
|
33
33
|
*/
|
|
34
34
|
constructor(settings: S, name: string);
|
|
35
|
+
/**
|
|
36
|
+
* Get parsed Url under bridge host
|
|
37
|
+
* @param url Url
|
|
38
|
+
* @returns Parsed Url
|
|
39
|
+
*/
|
|
40
|
+
protected getHostUrl(url: string): string;
|
|
35
41
|
/**
|
|
36
42
|
* Go to the login page
|
|
37
43
|
* @param tryLogin Try to login again
|
package/lib/app/ServiceApp.js
CHANGED
|
@@ -39,6 +39,14 @@ export class ServiceApp extends ReactApp {
|
|
|
39
39
|
set serviceUser(value) {
|
|
40
40
|
this._serviceUser = value;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Get parsed Url under bridge host
|
|
44
|
+
* @param url Url
|
|
45
|
+
* @returns Parsed Url
|
|
46
|
+
*/
|
|
47
|
+
getHostUrl(url) {
|
|
48
|
+
return this.getHostUrlBase(url, 's' + this.settings.serviceId);
|
|
49
|
+
}
|
|
42
50
|
/**
|
|
43
51
|
* Go to the login page
|
|
44
52
|
* @param tryLogin Try to login again
|
package/lib/app/Utils.d.ts
CHANGED
|
@@ -12,9 +12,10 @@ export declare namespace Utils {
|
|
|
12
12
|
function formatInputValue(value: unknown): string | number | any[] | undefined;
|
|
13
13
|
/**
|
|
14
14
|
* Get memory history
|
|
15
|
+
* @param initialPath Initial path
|
|
15
16
|
* @returns History
|
|
16
17
|
*/
|
|
17
|
-
function getMemoryHistory(): History;
|
|
18
|
+
function getMemoryHistory(initialPath?: string): History;
|
|
18
19
|
/**
|
|
19
20
|
* Is safe click
|
|
20
21
|
* @param event Mouse event
|
package/lib/app/Utils.js
CHANGED
|
@@ -26,11 +26,12 @@ export var Utils;
|
|
|
26
26
|
Utils.formatInputValue = formatInputValue;
|
|
27
27
|
/**
|
|
28
28
|
* Get memory history
|
|
29
|
+
* @param initialPath Initial path
|
|
29
30
|
* @returns History
|
|
30
31
|
*/
|
|
31
|
-
function getMemoryHistory() {
|
|
32
|
+
function getMemoryHistory(initialPath = '/') {
|
|
32
33
|
if (memoryHistory == null) {
|
|
33
|
-
memoryHistory = createHistory(createMemorySource(
|
|
34
|
+
memoryHistory = createHistory(createMemorySource(initialPath));
|
|
34
35
|
}
|
|
35
36
|
return memoryHistory;
|
|
36
37
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export * from './mu/texts/DateText';
|
|
|
31
31
|
export * from './mu/texts/MoneyText';
|
|
32
32
|
export * from './mu/texts/NumberText';
|
|
33
33
|
export * from './mu/AuditDisplay';
|
|
34
|
+
export * from './mu/BackButton';
|
|
34
35
|
export * from './mu/BridgeCloseButton';
|
|
35
36
|
export * from './mu/ButtonLink';
|
|
36
37
|
export * from './mu/ComboBox';
|
package/lib/index.js
CHANGED
|
@@ -34,6 +34,7 @@ export * from './mu/texts/DateText';
|
|
|
34
34
|
export * from './mu/texts/MoneyText';
|
|
35
35
|
export * from './mu/texts/NumberText';
|
|
36
36
|
export * from './mu/AuditDisplay';
|
|
37
|
+
export * from './mu/BackButton';
|
|
37
38
|
export * from './mu/BridgeCloseButton';
|
|
38
39
|
export * from './mu/ButtonLink';
|
|
39
40
|
export * from './mu/ComboBox';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { IconButtonProps } from '@mui/material';
|
|
3
|
+
/**
|
|
4
|
+
* BackButton props
|
|
5
|
+
*/
|
|
6
|
+
export interface BackButtonProps extends IconButtonProps {
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* BackButton
|
|
10
|
+
* @param props Props
|
|
11
|
+
* @returns Component
|
|
12
|
+
*/
|
|
13
|
+
export declare function BackButton(props: BackButtonProps): JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IconButton } from '@mui/material';
|
|
2
|
+
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { useNavigate } from '@reach/router';
|
|
5
|
+
/**
|
|
6
|
+
* BackButton
|
|
7
|
+
* @param props Props
|
|
8
|
+
* @returns Component
|
|
9
|
+
*/
|
|
10
|
+
export function BackButton(props) {
|
|
11
|
+
// Destruct
|
|
12
|
+
const { color = 'primary', size = 'small', onClick, ...rest } = props;
|
|
13
|
+
// Navigate
|
|
14
|
+
const navigate = useNavigate();
|
|
15
|
+
// Click handler
|
|
16
|
+
const onClickLocal = (event) => {
|
|
17
|
+
if (onClick)
|
|
18
|
+
onClick(event);
|
|
19
|
+
navigate(-1);
|
|
20
|
+
};
|
|
21
|
+
return (React.createElement(IconButton, { "aria-label": "Back", color: color, size: size, onClick: onClickLocal, sx: {
|
|
22
|
+
border: (theme) => `1px solid ${(() => color != 'inherit' &&
|
|
23
|
+
color != 'default' &&
|
|
24
|
+
color in theme.palette
|
|
25
|
+
? theme.palette[color]
|
|
26
|
+
: theme.palette.primary)().light}`
|
|
27
|
+
}, ...rest },
|
|
28
|
+
React.createElement(ArrowBackIcon, null)));
|
|
29
|
+
}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { IBridgeHost } from '@etsoo/appscript';
|
|
3
|
-
import { IconButtonProps } from '@mui/material';
|
|
3
|
+
import { BoxProps, IconButtonProps } from '@mui/material';
|
|
4
4
|
/**
|
|
5
5
|
* Bridge close button props
|
|
6
6
|
*/
|
|
7
7
|
export interface BridgeCloseButtonProps extends IconButtonProps {
|
|
8
|
+
/**
|
|
9
|
+
* Box props
|
|
10
|
+
*/
|
|
11
|
+
boxProps?: BoxProps;
|
|
8
12
|
/**
|
|
9
13
|
* Validate the host
|
|
10
14
|
* @param host Host
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BridgeUtils } from '@etsoo/appscript';
|
|
2
2
|
import CloseIcon from '@mui/icons-material/Close';
|
|
3
|
-
import { IconButton } from '@mui/material';
|
|
3
|
+
import { Box, IconButton } from '@mui/material';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { globalApp } from '../app/ReactApp';
|
|
6
6
|
/**
|
|
@@ -10,7 +10,7 @@ import { globalApp } from '../app/ReactApp';
|
|
|
10
10
|
*/
|
|
11
11
|
export function BridgeCloseButton(props) {
|
|
12
12
|
// Destruct
|
|
13
|
-
const { onClick, title = typeof globalApp === 'undefined'
|
|
13
|
+
const { boxProps, onClick, title = typeof globalApp === 'undefined'
|
|
14
14
|
? 'Close'
|
|
15
15
|
: globalApp.get('close'), validate, ...rest } = props;
|
|
16
16
|
// Host
|
|
@@ -24,11 +24,7 @@ export function BridgeCloseButton(props) {
|
|
|
24
24
|
onClick(event);
|
|
25
25
|
host.exit();
|
|
26
26
|
};
|
|
27
|
-
return (React.createElement(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
top: (theme) => theme.spacing(0.5),
|
|
31
|
-
right: (theme) => theme.spacing(0.5)
|
|
32
|
-
}, ...rest },
|
|
33
|
-
React.createElement(CloseIcon, null)));
|
|
27
|
+
return (React.createElement(Box, { ...boxProps },
|
|
28
|
+
React.createElement(IconButton, { "aria-label": "close", onClick: onClickLocal, title: title, ...rest },
|
|
29
|
+
React.createElement(CloseIcon, null))));
|
|
34
30
|
}
|
|
@@ -7,6 +7,7 @@ import { MoreFab } from '../MoreFab';
|
|
|
7
7
|
import { ReactAppStateDetector } from '../../app/ReactApp';
|
|
8
8
|
import { Container, Fab } from '@mui/material';
|
|
9
9
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
|
10
|
+
import { BackButton } from '../BackButton';
|
|
10
11
|
/**
|
|
11
12
|
* Default scroll container
|
|
12
13
|
*/
|
|
@@ -17,7 +18,7 @@ export const CommonPageScrollContainer = global;
|
|
|
17
18
|
*/
|
|
18
19
|
export function CommonPage(props) {
|
|
19
20
|
// Destruct
|
|
20
|
-
const { children, disableGutters = true, fabButtons, fabColumnDirection, fabPaddingAdjust = 1.5, fabSize = 'small', maxWidth = false, moreActions, onRefresh, onUpdate, onUpdateAll, paddings = MUGlobal.pagePaddings, scrollContainer, targetFields, sx = {}, ...rest } = props;
|
|
21
|
+
const { children, disableGutters = true, fabButtons, fabColumnDirection, fabPaddingAdjust = 1.5, fabSize = 'small', maxWidth = false, moreActions, onRefresh, onUpdate, onUpdateAll, paddings = MUGlobal.pagePaddings, scrollContainer, supportBack = false, targetFields, sx = {}, ...rest } = props;
|
|
21
22
|
// Merge style
|
|
22
23
|
Object.assign(sx, {
|
|
23
24
|
padding: paddings
|
|
@@ -53,6 +54,7 @@ export function CommonPage(props) {
|
|
|
53
54
|
fabButtons,
|
|
54
55
|
onRefresh != null && (React.createElement(Fab, { title: labels.refresh, size: fabSize, onClick: onRefresh, sx: { display: { xs: 'none', md: 'inherit' } } },
|
|
55
56
|
React.createElement(RefreshIcon, null))),
|
|
56
|
-
React.createElement(MoreFab, { size: fabSize, title: labels.more, actions: moreActions })
|
|
57
|
+
React.createElement(MoreFab, { size: fabSize, title: labels.more, actions: moreActions }),
|
|
58
|
+
supportBack && (React.createElement(BackButton, { title: labels.back, size: fabSize }))),
|
|
57
59
|
children)));
|
|
58
60
|
}
|
|
@@ -18,7 +18,7 @@ export interface CommonPageProps extends Omit<ContainerProps, 'id'> {
|
|
|
18
18
|
*/
|
|
19
19
|
fabSize?: CustomFabSize;
|
|
20
20
|
/**
|
|
21
|
-
* Fab flex column direction
|
|
21
|
+
* Fab flex column direction, undefined to hide it
|
|
22
22
|
*/
|
|
23
23
|
fabColumnDirection?: boolean;
|
|
24
24
|
/**
|
|
@@ -49,6 +49,10 @@ export interface CommonPageProps extends Omit<ContainerProps, 'id'> {
|
|
|
49
49
|
* Scroll container
|
|
50
50
|
*/
|
|
51
51
|
scrollContainer?: HTMLElement | object;
|
|
52
|
+
/**
|
|
53
|
+
* Support back click
|
|
54
|
+
*/
|
|
55
|
+
supportBack?: boolean;
|
|
52
56
|
/**
|
|
53
57
|
* State last changed fields
|
|
54
58
|
*/
|
|
@@ -16,6 +16,11 @@ export interface EditPageProps extends Omit<CommonPageProps, 'onSubmit'> {
|
|
|
16
16
|
* On delete callback
|
|
17
17
|
*/
|
|
18
18
|
onDelete?: () => Promise<void> | void;
|
|
19
|
+
/**
|
|
20
|
+
* Support back click
|
|
21
|
+
* @default true
|
|
22
|
+
*/
|
|
23
|
+
supportBack?: boolean;
|
|
19
24
|
}
|
|
20
25
|
/**
|
|
21
26
|
* Add / Edit page
|
package/lib/mu/pages/EditPage.js
CHANGED
|
@@ -5,13 +5,14 @@ import { MUGlobal } from '../MUGlobal';
|
|
|
5
5
|
import { CommonPage, CommonPageScrollContainer } from './CommonPage';
|
|
6
6
|
import SaveIcon from '@mui/icons-material/Save';
|
|
7
7
|
import DeleteIcon from '@mui/icons-material/Delete';
|
|
8
|
+
import { BackButton } from '../BackButton';
|
|
8
9
|
/**
|
|
9
10
|
* Add / Edit page
|
|
10
11
|
* @param props Props
|
|
11
12
|
*/
|
|
12
13
|
export function EditPage(props) {
|
|
13
14
|
// Destruct
|
|
14
|
-
const { children, isEditing, onDelete, onSubmit, paddings = MUGlobal.pagePaddings, scrollContainer = CommonPageScrollContainer, ...rest } = props;
|
|
15
|
+
const { children, isEditing, onDelete, onSubmit, paddings = MUGlobal.pagePaddings, scrollContainer = CommonPageScrollContainer, supportBack = true, ...rest } = props;
|
|
15
16
|
// Labels
|
|
16
17
|
const labels = Labels.CommonPage;
|
|
17
18
|
return (React.createElement(CommonPage, { paddings: paddings, scrollContainer: scrollContainer, ...rest },
|
|
@@ -23,5 +24,6 @@ export function EditPage(props) {
|
|
|
23
24
|
paddingTop: paddings
|
|
24
25
|
} },
|
|
25
26
|
isEditing && onDelete && (React.createElement(Button, { color: "primary", variant: "outlined", onClick: () => onDelete(), startIcon: React.createElement(DeleteIcon, { color: "warning" }) }, labels.delete)),
|
|
26
|
-
React.createElement(Button, { variant: "contained", type: "submit", startIcon: React.createElement(SaveIcon, null), sx: { flexGrow: 1 } }, labels.save)
|
|
27
|
+
React.createElement(Button, { variant: "contained", type: "submit", startIcon: React.createElement(SaveIcon, null), sx: { flexGrow: 1 } }, labels.save),
|
|
28
|
+
supportBack && React.createElement(BackButton, { title: labels.back })))));
|
|
27
29
|
}
|
package/lib/mu/pages/ViewPage.js
CHANGED
|
@@ -62,7 +62,7 @@ function getItemField(field, data) {
|
|
|
62
62
|
*/
|
|
63
63
|
export function ViewPage(props) {
|
|
64
64
|
// Destruct
|
|
65
|
-
const { actions, children, fields, loadData, paddings = MUGlobal.pagePaddings, supportRefresh = true, ...rest } = props;
|
|
65
|
+
const { actions, children, fields, loadData, paddings = MUGlobal.pagePaddings, supportRefresh = true, fabColumnDirection = true, supportBack = true, ...rest } = props;
|
|
66
66
|
// Data
|
|
67
67
|
const [data, setData] = React.useState();
|
|
68
68
|
// Load data
|
|
@@ -72,7 +72,7 @@ export function ViewPage(props) {
|
|
|
72
72
|
return;
|
|
73
73
|
setData(result);
|
|
74
74
|
};
|
|
75
|
-
return (React.createElement(CommonPage, { paddings: paddings, onRefresh: supportRefresh ? refresh : undefined, onUpdate: supportRefresh ? undefined : refresh, ...rest, scrollContainer:
|
|
75
|
+
return (React.createElement(CommonPage, { paddings: paddings, onRefresh: supportRefresh ? refresh : undefined, onUpdate: supportRefresh ? undefined : refresh, ...rest, scrollContainer: globalThis, fabColumnDirection: fabColumnDirection, supportBack: supportBack }, data == null ? (React.createElement(LinearProgress, null)) : (React.createElement(React.Fragment, null,
|
|
76
76
|
React.createElement(Grid, { container: true, justifyContent: "left", spacing: paddings, className: "ET-ViewPage", sx: {
|
|
77
77
|
'.MuiTypography-subtitle2': {
|
|
78
78
|
fontWeight: 'bold'
|
package/package.json
CHANGED
package/src/app/Labels.ts
CHANGED
package/src/app/ReactApp.ts
CHANGED
|
@@ -56,12 +56,10 @@ export function ReactAppStateDetector(props: IStateProps) {
|
|
|
56
56
|
const { targetFields, update } = props;
|
|
57
57
|
|
|
58
58
|
// Context
|
|
59
|
-
const { state } =
|
|
59
|
+
const { state = {} } =
|
|
60
60
|
globalApp == null
|
|
61
|
-
? ({
|
|
62
|
-
: React.useContext(
|
|
63
|
-
(globalApp.userState as UserState<IUser>).context
|
|
64
|
-
);
|
|
61
|
+
? ({} as UserCalls<IUser>)
|
|
62
|
+
: React.useContext(globalApp.userState.context);
|
|
65
63
|
|
|
66
64
|
// Ready
|
|
67
65
|
React.useEffect(() => {
|
|
@@ -223,7 +221,7 @@ export class ReactApp<
|
|
|
223
221
|
);
|
|
224
222
|
this.history =
|
|
225
223
|
window.location.hostname === ''
|
|
226
|
-
? Utils.getMemoryHistory()
|
|
224
|
+
? Utils.getMemoryHistory(this.getHostUrl(window.location.href))
|
|
227
225
|
: undefined;
|
|
228
226
|
this.cultureState = new CultureState(settings.currentCulture);
|
|
229
227
|
this.pageState = new PageState<P>();
|
|
@@ -231,6 +229,33 @@ export class ReactApp<
|
|
|
231
229
|
globalApp = this;
|
|
232
230
|
}
|
|
233
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Get parsed Url under bridge host
|
|
234
|
+
* @param url Url
|
|
235
|
+
* @returns Parsed Url
|
|
236
|
+
*/
|
|
237
|
+
protected getHostUrl(url: string) {
|
|
238
|
+
return this.getHostUrlBase(url, 'core');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Get parsed Url under bridge host
|
|
243
|
+
* @param url Url
|
|
244
|
+
* @param name App name in the host environment
|
|
245
|
+
* @returns Parsed Url
|
|
246
|
+
*/
|
|
247
|
+
protected getHostUrlBase(url: string, name: string) {
|
|
248
|
+
if (url.startsWith('/')) return url;
|
|
249
|
+
|
|
250
|
+
const identifier = `/${name}/`;
|
|
251
|
+
const pos = url.indexOf(identifier);
|
|
252
|
+
if (pos === -1) return '/';
|
|
253
|
+
|
|
254
|
+
return url
|
|
255
|
+
.substring(pos + identifier.length - 1)
|
|
256
|
+
.replace('/index.html', '/'); // Router take / as start
|
|
257
|
+
}
|
|
258
|
+
|
|
234
259
|
/**
|
|
235
260
|
* Override alert action result
|
|
236
261
|
* @param result Action result
|
package/src/app/ServiceApp.ts
CHANGED
|
@@ -68,6 +68,15 @@ export class ServiceApp<
|
|
|
68
68
|
this.serviceApi = api;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Get parsed Url under bridge host
|
|
73
|
+
* @param url Url
|
|
74
|
+
* @returns Parsed Url
|
|
75
|
+
*/
|
|
76
|
+
protected override getHostUrl(url: string) {
|
|
77
|
+
return this.getHostUrlBase(url, 's' + this.settings.serviceId);
|
|
78
|
+
}
|
|
79
|
+
|
|
71
80
|
/**
|
|
72
81
|
* Go to the login page
|
|
73
82
|
* @param tryLogin Try to login again
|
package/src/app/Utils.ts
CHANGED
|
@@ -28,11 +28,12 @@ export namespace Utils {
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Get memory history
|
|
31
|
+
* @param initialPath Initial path
|
|
31
32
|
* @returns History
|
|
32
33
|
*/
|
|
33
|
-
export function getMemoryHistory() {
|
|
34
|
+
export function getMemoryHistory(initialPath: string = '/') {
|
|
34
35
|
if (memoryHistory == null) {
|
|
35
|
-
memoryHistory = createHistory(createMemorySource(
|
|
36
|
+
memoryHistory = createHistory(createMemorySource(initialPath));
|
|
36
37
|
}
|
|
37
38
|
return memoryHistory;
|
|
38
39
|
}
|
package/src/index.ts
CHANGED
|
@@ -38,6 +38,7 @@ export * from './mu/texts/MoneyText';
|
|
|
38
38
|
export * from './mu/texts/NumberText';
|
|
39
39
|
|
|
40
40
|
export * from './mu/AuditDisplay';
|
|
41
|
+
export * from './mu/BackButton';
|
|
41
42
|
export * from './mu/BridgeCloseButton';
|
|
42
43
|
export * from './mu/ButtonLink';
|
|
43
44
|
export * from './mu/ComboBox';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { IconButton, IconButtonProps } from '@mui/material';
|
|
2
|
+
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { useNavigate } from '@reach/router';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* BackButton props
|
|
8
|
+
*/
|
|
9
|
+
export interface BackButtonProps extends IconButtonProps {}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* BackButton
|
|
13
|
+
* @param props Props
|
|
14
|
+
* @returns Component
|
|
15
|
+
*/
|
|
16
|
+
export function BackButton(props: BackButtonProps) {
|
|
17
|
+
// Destruct
|
|
18
|
+
const { color = 'primary', size = 'small', onClick, ...rest } = props;
|
|
19
|
+
|
|
20
|
+
// Navigate
|
|
21
|
+
const navigate = useNavigate();
|
|
22
|
+
|
|
23
|
+
// Click handler
|
|
24
|
+
const onClickLocal = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
25
|
+
if (onClick) onClick(event);
|
|
26
|
+
navigate(-1);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<IconButton
|
|
31
|
+
aria-label="Back"
|
|
32
|
+
color={color}
|
|
33
|
+
size={size}
|
|
34
|
+
onClick={onClickLocal}
|
|
35
|
+
sx={{
|
|
36
|
+
border: (theme) =>
|
|
37
|
+
`1px solid ${
|
|
38
|
+
(() =>
|
|
39
|
+
color != 'inherit' &&
|
|
40
|
+
color != 'default' &&
|
|
41
|
+
color in theme.palette
|
|
42
|
+
? theme.palette[color]
|
|
43
|
+
: theme.palette.primary)().light
|
|
44
|
+
}`
|
|
45
|
+
}}
|
|
46
|
+
{...rest}
|
|
47
|
+
>
|
|
48
|
+
<ArrowBackIcon />
|
|
49
|
+
</IconButton>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BridgeUtils, IBridgeHost } from '@etsoo/appscript';
|
|
2
2
|
import CloseIcon from '@mui/icons-material/Close';
|
|
3
|
-
import { IconButton, IconButtonProps } from '@mui/material';
|
|
3
|
+
import { Box, BoxProps, IconButton, IconButtonProps } from '@mui/material';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { globalApp } from '../app/ReactApp';
|
|
6
6
|
|
|
@@ -8,6 +8,11 @@ import { globalApp } from '../app/ReactApp';
|
|
|
8
8
|
* Bridge close button props
|
|
9
9
|
*/
|
|
10
10
|
export interface BridgeCloseButtonProps extends IconButtonProps {
|
|
11
|
+
/**
|
|
12
|
+
* Box props
|
|
13
|
+
*/
|
|
14
|
+
boxProps?: BoxProps;
|
|
15
|
+
|
|
11
16
|
/**
|
|
12
17
|
* Validate the host
|
|
13
18
|
* @param host Host
|
|
@@ -23,6 +28,7 @@ export interface BridgeCloseButtonProps extends IconButtonProps {
|
|
|
23
28
|
export function BridgeCloseButton(props: BridgeCloseButtonProps) {
|
|
24
29
|
// Destruct
|
|
25
30
|
const {
|
|
31
|
+
boxProps,
|
|
26
32
|
onClick,
|
|
27
33
|
title = typeof globalApp === 'undefined'
|
|
28
34
|
? 'Close'
|
|
@@ -45,20 +51,15 @@ export function BridgeCloseButton(props: BridgeCloseButtonProps) {
|
|
|
45
51
|
};
|
|
46
52
|
|
|
47
53
|
return (
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}}
|
|
59
|
-
{...rest}
|
|
60
|
-
>
|
|
61
|
-
<CloseIcon />
|
|
62
|
-
</IconButton>
|
|
54
|
+
<Box {...boxProps}>
|
|
55
|
+
<IconButton
|
|
56
|
+
aria-label="close"
|
|
57
|
+
onClick={onClickLocal}
|
|
58
|
+
title={title}
|
|
59
|
+
{...rest}
|
|
60
|
+
>
|
|
61
|
+
<CloseIcon />
|
|
62
|
+
</IconButton>
|
|
63
|
+
</Box>
|
|
63
64
|
);
|
|
64
65
|
}
|
|
@@ -8,6 +8,7 @@ import { MoreFab } from '../MoreFab';
|
|
|
8
8
|
import { ReactAppStateDetector } from '../../app/ReactApp';
|
|
9
9
|
import { Container, Fab } from '@mui/material';
|
|
10
10
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
|
11
|
+
import { BackButton } from '../BackButton';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Default scroll container
|
|
@@ -34,6 +35,7 @@ export function CommonPage(props: CommonPageProps) {
|
|
|
34
35
|
onUpdateAll,
|
|
35
36
|
paddings = MUGlobal.pagePaddings,
|
|
36
37
|
scrollContainer,
|
|
38
|
+
supportBack = false,
|
|
37
39
|
targetFields,
|
|
38
40
|
sx = {},
|
|
39
41
|
...rest
|
|
@@ -115,6 +117,9 @@ export function CommonPage(props: CommonPageProps) {
|
|
|
115
117
|
title={labels.more}
|
|
116
118
|
actions={moreActions}
|
|
117
119
|
/>
|
|
120
|
+
{supportBack && (
|
|
121
|
+
<BackButton title={labels.back} size={fabSize} />
|
|
122
|
+
)}
|
|
118
123
|
</FabBox>
|
|
119
124
|
{children}
|
|
120
125
|
</Container>
|
|
@@ -20,7 +20,7 @@ export interface CommonPageProps extends Omit<ContainerProps, 'id'> {
|
|
|
20
20
|
fabSize?: CustomFabSize;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* Fab flex column direction
|
|
23
|
+
* Fab flex column direction, undefined to hide it
|
|
24
24
|
*/
|
|
25
25
|
fabColumnDirection?: boolean;
|
|
26
26
|
|
|
@@ -59,6 +59,11 @@ export interface CommonPageProps extends Omit<ContainerProps, 'id'> {
|
|
|
59
59
|
*/
|
|
60
60
|
scrollContainer?: HTMLElement | object;
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Support back click
|
|
64
|
+
*/
|
|
65
|
+
supportBack?: boolean;
|
|
66
|
+
|
|
62
67
|
/**
|
|
63
68
|
* State last changed fields
|
|
64
69
|
*/
|
|
@@ -6,6 +6,7 @@ import { CommonPage, CommonPageScrollContainer } from './CommonPage';
|
|
|
6
6
|
import { CommonPageProps } from './CommonPageProps';
|
|
7
7
|
import SaveIcon from '@mui/icons-material/Save';
|
|
8
8
|
import DeleteIcon from '@mui/icons-material/Delete';
|
|
9
|
+
import { BackButton } from '../BackButton';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Add / Edit page props
|
|
@@ -25,6 +26,12 @@ export interface EditPageProps extends Omit<CommonPageProps, 'onSubmit'> {
|
|
|
25
26
|
* On delete callback
|
|
26
27
|
*/
|
|
27
28
|
onDelete?: () => Promise<void> | void;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Support back click
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
supportBack?: boolean;
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
/**
|
|
@@ -40,6 +47,7 @@ export function EditPage(props: EditPageProps) {
|
|
|
40
47
|
onSubmit,
|
|
41
48
|
paddings = MUGlobal.pagePaddings,
|
|
42
49
|
scrollContainer = CommonPageScrollContainer,
|
|
50
|
+
supportBack = true,
|
|
43
51
|
...rest
|
|
44
52
|
} = props;
|
|
45
53
|
|
|
@@ -91,6 +99,7 @@ export function EditPage(props: EditPageProps) {
|
|
|
91
99
|
>
|
|
92
100
|
{labels.save}
|
|
93
101
|
</Button>
|
|
102
|
+
{supportBack && <BackButton title={labels.back} />}
|
|
94
103
|
</Grid>
|
|
95
104
|
</form>
|
|
96
105
|
</CommonPage>
|
|
@@ -165,6 +165,8 @@ export function ViewPage<T extends {}>(props: ViewPageProps<T>) {
|
|
|
165
165
|
loadData,
|
|
166
166
|
paddings = MUGlobal.pagePaddings,
|
|
167
167
|
supportRefresh = true,
|
|
168
|
+
fabColumnDirection = true,
|
|
169
|
+
supportBack = true,
|
|
168
170
|
...rest
|
|
169
171
|
} = props;
|
|
170
172
|
|
|
@@ -184,7 +186,9 @@ export function ViewPage<T extends {}>(props: ViewPageProps<T>) {
|
|
|
184
186
|
onRefresh={supportRefresh ? refresh : undefined}
|
|
185
187
|
onUpdate={supportRefresh ? undefined : refresh}
|
|
186
188
|
{...rest}
|
|
187
|
-
scrollContainer={
|
|
189
|
+
scrollContainer={globalThis}
|
|
190
|
+
fabColumnDirection={fabColumnDirection}
|
|
191
|
+
supportBack={supportBack}
|
|
188
192
|
>
|
|
189
193
|
{data == null ? (
|
|
190
194
|
<LinearProgress />
|