@etsoo/react 1.5.33 → 1.5.36
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 +3 -3
- package/lib/app/ReactApp.js +9 -7
- package/lib/app/ReactUtils.d.ts +0 -25
- package/lib/app/ReactUtils.js +0 -91
- package/lib/components/HRouter.d.ts +8 -0
- package/lib/components/HRouter.js +15 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +2 -1
- package/lib/mu/BackButton.js +4 -3
- package/lib/mu/ButtonLink.js +2 -2
- package/lib/mu/IconButtonLink.js +2 -2
- package/lib/mu/MoreFab.js +1 -1
- package/lib/mu/RLink.d.ts +2 -2
- package/lib/mu/RLink.js +1 -1
- package/lib/mu/TabBox.js +1 -1
- package/lib/uses/useParamsEx.d.ts +6 -0
- package/lib/uses/useParamsEx.js +12 -0
- package/package.json +6 -7
- package/src/app/ReactApp.ts +11 -11
- package/src/app/ReactUtils.ts +0 -112
- package/src/components/HRouter.tsx +26 -0
- package/src/index.ts +2 -1
- package/src/mu/BackButton.tsx +5 -3
- package/src/mu/ButtonLink.tsx +2 -3
- package/src/mu/IconButtonLink.tsx +2 -2
- package/src/mu/MoreFab.tsx +1 -1
- package/src/mu/RLink.tsx +2 -2
- package/src/mu/TabBox.tsx +1 -1
- package/src/uses/useParamsEx.ts +14 -0
- package/lib/states/RouterProps.d.ts +0 -39
- package/lib/states/RouterProps.js +0 -14
- package/src/states/RouterProps.ts +0 -46
package/lib/app/ReactApp.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { CoreApp, IActionResult, IAppSettings, ICoreApp, IUser, IUserData } from '@etsoo/appscript';
|
|
2
2
|
import { NotificationRenderProps, NotificationReturn } from '@etsoo/notificationbase';
|
|
3
3
|
import { DataTypes } from '@etsoo/shared';
|
|
4
|
-
import { History } from '@reach/router';
|
|
5
4
|
import React from 'react';
|
|
6
5
|
import { NotificationReactCallProps } from '../notifier/Notifier';
|
|
7
6
|
import { CultureAction, CultureState } from '../states/CultureState';
|
|
@@ -9,6 +8,7 @@ import { IStateProps } from '../states/IState';
|
|
|
9
8
|
import { IPageData, PageAction, PageState } from '../states/PageState';
|
|
10
9
|
import { UserAction, UserState } from '../states/UserState';
|
|
11
10
|
import { InputDialogProps } from './InputDialogProps';
|
|
11
|
+
import { History } from 'history';
|
|
12
12
|
/**
|
|
13
13
|
* Global application
|
|
14
14
|
*/
|
|
@@ -36,7 +36,7 @@ export interface IReactApp<S extends IAppSettings, D extends IUser, P extends IP
|
|
|
36
36
|
/**
|
|
37
37
|
* Router history
|
|
38
38
|
*/
|
|
39
|
-
readonly history
|
|
39
|
+
readonly history: History;
|
|
40
40
|
/**
|
|
41
41
|
* Is screen size down 'sm'
|
|
42
42
|
*/
|
|
@@ -79,7 +79,7 @@ export declare class ReactApp<S extends IAppSettings, D extends IUser, P extends
|
|
|
79
79
|
/**
|
|
80
80
|
* Router history
|
|
81
81
|
*/
|
|
82
|
-
readonly history
|
|
82
|
+
readonly history: History;
|
|
83
83
|
/**
|
|
84
84
|
* Page state
|
|
85
85
|
*/
|
package/lib/app/ReactApp.js
CHANGED
|
@@ -8,7 +8,7 @@ import { CultureState } from '../states/CultureState';
|
|
|
8
8
|
import { PageActionType, PageState } from '../states/PageState';
|
|
9
9
|
import { UserActionType, UserState } from '../states/UserState';
|
|
10
10
|
import { Labels } from './Labels';
|
|
11
|
-
import {
|
|
11
|
+
import { createBrowserHistory, createMemoryHistory } from 'history';
|
|
12
12
|
/**
|
|
13
13
|
* Global application
|
|
14
14
|
*/
|
|
@@ -65,15 +65,18 @@ export class ReactApp extends CoreApp {
|
|
|
65
65
|
* User state
|
|
66
66
|
*/
|
|
67
67
|
this.userState = new UserState();
|
|
68
|
-
this.history =
|
|
69
|
-
BridgeUtils.host == null
|
|
70
|
-
? undefined
|
|
71
|
-
: ReactUtils.getMemoryHistory(BridgeUtils.host.getStartUrl());
|
|
72
68
|
if (BridgeUtils.host) {
|
|
69
|
+
const startUrl = BridgeUtils.host.getStartUrl();
|
|
70
|
+
this.history = createMemoryHistory({
|
|
71
|
+
initialEntries: startUrl == null ? undefined : [startUrl]
|
|
72
|
+
});
|
|
73
73
|
BridgeUtils.host.onUpdate((app, version) => {
|
|
74
74
|
this.notifier.message(NotificationMessageType.Success, this.get('updateTip') + `(${[app, version].join(', ')})`, this.get('updateReady'));
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
|
+
else {
|
|
78
|
+
this.history = createBrowserHistory();
|
|
79
|
+
}
|
|
77
80
|
this.cultureState = new CultureState(settings.currentCulture);
|
|
78
81
|
this.pageState = new PageState();
|
|
79
82
|
globalApp = this;
|
|
@@ -204,8 +207,7 @@ export class ReactApp extends CoreApp {
|
|
|
204
207
|
* @param url Url
|
|
205
208
|
*/
|
|
206
209
|
redirectTo(url) {
|
|
207
|
-
|
|
208
|
-
navigate(url);
|
|
210
|
+
this.history.push(url);
|
|
209
211
|
}
|
|
210
212
|
/**
|
|
211
213
|
* Set page data
|
package/lib/app/ReactUtils.d.ts
CHANGED
|
@@ -1,38 +1,14 @@
|
|
|
1
|
-
import { History, HistorySource } from '@reach/router';
|
|
2
1
|
import React from 'react';
|
|
3
|
-
declare type MemoryHistorySource = HistorySource & {
|
|
4
|
-
history: {
|
|
5
|
-
get entries(): any;
|
|
6
|
-
get index(): number;
|
|
7
|
-
go(to: number): void;
|
|
8
|
-
};
|
|
9
|
-
};
|
|
10
2
|
/**
|
|
11
3
|
* React utils
|
|
12
4
|
*/
|
|
13
5
|
export declare namespace ReactUtils {
|
|
14
|
-
/**
|
|
15
|
-
* Cretae memory source to fix go back bug
|
|
16
|
-
* @param initialPath Initial path
|
|
17
|
-
*/
|
|
18
|
-
function createMemorySource(initialPath?: string): MemoryHistorySource;
|
|
19
6
|
/**
|
|
20
7
|
* Format input value
|
|
21
8
|
* @param value Input value
|
|
22
9
|
* @returns Formatted value
|
|
23
10
|
*/
|
|
24
11
|
function formatInputValue(value: unknown): string | number | any[] | undefined;
|
|
25
|
-
/**
|
|
26
|
-
* Get memory history
|
|
27
|
-
* @param initialPath Initial path
|
|
28
|
-
* @returns History
|
|
29
|
-
*/
|
|
30
|
-
function getMemoryHistory(initialPath?: string | null): History;
|
|
31
|
-
/**
|
|
32
|
-
* Get navigate function, works with memory history
|
|
33
|
-
* @returns NavigateFn
|
|
34
|
-
*/
|
|
35
|
-
function getNavigateFn(): import("@reach/router").NavigateFn;
|
|
36
12
|
/**
|
|
37
13
|
* Is safe click
|
|
38
14
|
* @param event Mouse event
|
|
@@ -47,4 +23,3 @@ export declare namespace ReactUtils {
|
|
|
47
23
|
*/
|
|
48
24
|
function triggerChange(input: HTMLInputElement, value: string, cancelable: boolean): void;
|
|
49
25
|
}
|
|
50
|
-
export {};
|
package/lib/app/ReactUtils.js
CHANGED
|
@@ -1,77 +1,8 @@
|
|
|
1
|
-
import { createHistory, navigate } from '@reach/router';
|
|
2
1
|
/**
|
|
3
2
|
* React utils
|
|
4
3
|
*/
|
|
5
4
|
export var ReactUtils;
|
|
6
5
|
(function (ReactUtils) {
|
|
7
|
-
// Memory history
|
|
8
|
-
// https://github.com/reach/router/issues/225
|
|
9
|
-
let memoryHistory;
|
|
10
|
-
/**
|
|
11
|
-
* Cretae memory source to fix go back bug
|
|
12
|
-
* @param initialPath Initial path
|
|
13
|
-
*/
|
|
14
|
-
function createMemorySource(initialPath = '/') {
|
|
15
|
-
const searchIndex = initialPath.indexOf('?');
|
|
16
|
-
const pathname = searchIndex > -1
|
|
17
|
-
? initialPath.substring(0, searchIndex)
|
|
18
|
-
: initialPath;
|
|
19
|
-
const initialLocation = {
|
|
20
|
-
pathname,
|
|
21
|
-
search: searchIndex > -1 ? initialPath.substring(searchIndex) : ''
|
|
22
|
-
};
|
|
23
|
-
let index = 0;
|
|
24
|
-
const stack = [initialLocation];
|
|
25
|
-
const states = [null];
|
|
26
|
-
return {
|
|
27
|
-
get location() {
|
|
28
|
-
return stack[index];
|
|
29
|
-
},
|
|
30
|
-
addEventListener(name, fn) { },
|
|
31
|
-
removeEventListener(name, fn) { },
|
|
32
|
-
history: {
|
|
33
|
-
get entries() {
|
|
34
|
-
return stack;
|
|
35
|
-
},
|
|
36
|
-
get index() {
|
|
37
|
-
return index;
|
|
38
|
-
},
|
|
39
|
-
get state() {
|
|
40
|
-
return states[index];
|
|
41
|
-
},
|
|
42
|
-
pushState(state, _, uri) {
|
|
43
|
-
const [pathname, search = ''] = uri.split('?');
|
|
44
|
-
index++;
|
|
45
|
-
// View a, index = 0
|
|
46
|
-
// View b, index = 1
|
|
47
|
-
// Go(-1), a, index = 0
|
|
48
|
-
// View c, index = 1, directly push is wrong
|
|
49
|
-
if (index < stack.length) {
|
|
50
|
-
stack.splice(index);
|
|
51
|
-
states.splice(index);
|
|
52
|
-
}
|
|
53
|
-
stack.push({
|
|
54
|
-
pathname,
|
|
55
|
-
search: search.length ? `?${search}` : search
|
|
56
|
-
});
|
|
57
|
-
states.push(state);
|
|
58
|
-
},
|
|
59
|
-
replaceState(state, _, uri) {
|
|
60
|
-
const [pathname, search = ''] = uri.split('?');
|
|
61
|
-
stack[index] = { pathname, search };
|
|
62
|
-
states[index] = state;
|
|
63
|
-
},
|
|
64
|
-
go(to) {
|
|
65
|
-
const newIndex = index + to;
|
|
66
|
-
if (newIndex < 0 || newIndex > states.length - 1) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
index = newIndex;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
ReactUtils.createMemorySource = createMemorySource;
|
|
75
6
|
/**
|
|
76
7
|
* Format input value
|
|
77
8
|
* @param value Input value
|
|
@@ -89,28 +20,6 @@ export var ReactUtils;
|
|
|
89
20
|
return String(value);
|
|
90
21
|
}
|
|
91
22
|
ReactUtils.formatInputValue = formatInputValue;
|
|
92
|
-
/**
|
|
93
|
-
* Get memory history
|
|
94
|
-
* @param initialPath Initial path
|
|
95
|
-
* @returns History
|
|
96
|
-
*/
|
|
97
|
-
function getMemoryHistory(initialPath) {
|
|
98
|
-
if (memoryHistory == null) {
|
|
99
|
-
memoryHistory = createHistory(createMemorySource(initialPath !== null && initialPath !== void 0 ? initialPath : '/'));
|
|
100
|
-
}
|
|
101
|
-
return memoryHistory;
|
|
102
|
-
}
|
|
103
|
-
ReactUtils.getMemoryHistory = getMemoryHistory;
|
|
104
|
-
/**
|
|
105
|
-
* Get navigate function, works with memory history
|
|
106
|
-
* @returns NavigateFn
|
|
107
|
-
*/
|
|
108
|
-
function getNavigateFn() {
|
|
109
|
-
if (memoryHistory == null)
|
|
110
|
-
return navigate;
|
|
111
|
-
return memoryHistory.navigate;
|
|
112
|
-
}
|
|
113
|
-
ReactUtils.getNavigateFn = getNavigateFn;
|
|
114
23
|
/**
|
|
115
24
|
* Is safe click
|
|
116
25
|
* @param event Mouse event
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { HistoryRouterProps } from 'react-router-dom';
|
|
3
|
+
/**
|
|
4
|
+
* Open to use HistoryRouter of react-router-dom
|
|
5
|
+
* @param History router properties
|
|
6
|
+
* @returns Component
|
|
7
|
+
*/
|
|
8
|
+
export declare function HRouter({ basename, children, history }: HistoryRouterProps): JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Router } from 'react-router-dom';
|
|
3
|
+
/**
|
|
4
|
+
* Open to use HistoryRouter of react-router-dom
|
|
5
|
+
* @param History router properties
|
|
6
|
+
* @returns Component
|
|
7
|
+
*/
|
|
8
|
+
export function HRouter({ basename, children, history }) {
|
|
9
|
+
const [state, setState] = React.useState({
|
|
10
|
+
action: history.action,
|
|
11
|
+
location: history.location
|
|
12
|
+
});
|
|
13
|
+
React.useLayoutEffect(() => history.listen(setState), [history]);
|
|
14
|
+
return (React.createElement(Router, { basename: basename, children: children, location: state.location, navigationType: state.action, navigator: history }));
|
|
15
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from './app/RefreshTokenRQ';
|
|
|
11
11
|
export * from './app/ServiceApp';
|
|
12
12
|
export * from './components/GridColumn';
|
|
13
13
|
export * from './components/GridLoader';
|
|
14
|
+
export * from './components/HRouter';
|
|
14
15
|
export * from './components/ListItemReact';
|
|
15
16
|
export * from './components/ScrollerGrid';
|
|
16
17
|
export * from './components/ScrollerList';
|
|
@@ -84,11 +85,11 @@ export * from '@etsoo/notificationbase';
|
|
|
84
85
|
export * from './states/CultureState';
|
|
85
86
|
export * from './states/IState';
|
|
86
87
|
export * from './states/PageState';
|
|
87
|
-
export * from './states/RouterProps';
|
|
88
88
|
export * from './states/State';
|
|
89
89
|
export * from './states/UserState';
|
|
90
90
|
export * from './uses/useCombinedRefs';
|
|
91
91
|
export * from './uses/useDelayedExecutor';
|
|
92
92
|
export * from './uses/useDimensions';
|
|
93
|
+
export * from './uses/useParamsEx';
|
|
93
94
|
export * from './uses/useTimeout';
|
|
94
95
|
export * from './uses/useWindowSize';
|
package/lib/index.js
CHANGED
|
@@ -13,6 +13,7 @@ export * from './app/ServiceApp';
|
|
|
13
13
|
// components
|
|
14
14
|
export * from './components/GridColumn';
|
|
15
15
|
export * from './components/GridLoader';
|
|
16
|
+
export * from './components/HRouter';
|
|
16
17
|
export * from './components/ListItemReact';
|
|
17
18
|
export * from './components/ScrollerGrid';
|
|
18
19
|
export * from './components/ScrollerList';
|
|
@@ -89,12 +90,12 @@ export * from '@etsoo/notificationbase';
|
|
|
89
90
|
export * from './states/CultureState';
|
|
90
91
|
export * from './states/IState';
|
|
91
92
|
export * from './states/PageState';
|
|
92
|
-
export * from './states/RouterProps';
|
|
93
93
|
export * from './states/State';
|
|
94
94
|
export * from './states/UserState';
|
|
95
95
|
// uses
|
|
96
96
|
export * from './uses/useCombinedRefs';
|
|
97
97
|
export * from './uses/useDelayedExecutor';
|
|
98
98
|
export * from './uses/useDimensions';
|
|
99
|
+
export * from './uses/useParamsEx';
|
|
99
100
|
export * from './uses/useTimeout';
|
|
100
101
|
export * from './uses/useWindowSize';
|
package/lib/mu/BackButton.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IconButton, useTheme } from '@mui/material';
|
|
2
2
|
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { useNavigate } from 'react-router-dom';
|
|
5
5
|
/**
|
|
6
6
|
* BackButton
|
|
7
7
|
* @param props Props
|
|
@@ -12,6 +12,8 @@ export function BackButton(props) {
|
|
|
12
12
|
const { color = 'primary', size = 'small', onClick, ...rest } = props;
|
|
13
13
|
// Theme
|
|
14
14
|
const theme = useTheme();
|
|
15
|
+
// Navigate
|
|
16
|
+
const navigate = useNavigate();
|
|
15
17
|
// Color
|
|
16
18
|
const pColor = color != 'inherit' && color != 'default' && color in theme.palette
|
|
17
19
|
? theme.palette[color]
|
|
@@ -21,8 +23,7 @@ export function BackButton(props) {
|
|
|
21
23
|
if (onClick)
|
|
22
24
|
onClick(event);
|
|
23
25
|
// Navigate
|
|
24
|
-
|
|
25
|
-
await navigate(-1);
|
|
26
|
+
navigate(-1);
|
|
26
27
|
};
|
|
27
28
|
return (React.createElement(IconButton, { "aria-label": "Back", color: color, size: size, onClick: onClickLocal, sx: {
|
|
28
29
|
backgroundColor: pColor.contrastText,
|
package/lib/mu/ButtonLink.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Button } from '@mui/material';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { useNavigate } from 'react-router-dom';
|
|
4
4
|
/**
|
|
5
5
|
* ButtonLink
|
|
6
6
|
* @param props Props
|
|
@@ -10,7 +10,7 @@ export function ButtonLink(props) {
|
|
|
10
10
|
// Destruct
|
|
11
11
|
const { href, ...rest } = props;
|
|
12
12
|
// Navigate
|
|
13
|
-
const navigate =
|
|
13
|
+
const navigate = useNavigate();
|
|
14
14
|
const onClick = href.includes('://')
|
|
15
15
|
? () => window.open(href, '_blank')
|
|
16
16
|
: () => navigate(href);
|
package/lib/mu/IconButtonLink.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IconButton } from '@mui/material';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { useNavigate } from 'react-router-dom';
|
|
4
4
|
/**
|
|
5
5
|
* IconButtonLink
|
|
6
6
|
* @param props Props
|
|
@@ -10,7 +10,7 @@ export function IconButtonLink(props) {
|
|
|
10
10
|
// Destruct
|
|
11
11
|
const { href, ...rest } = props;
|
|
12
12
|
// Navigate
|
|
13
|
-
const navigate =
|
|
13
|
+
const navigate = useNavigate();
|
|
14
14
|
// Layout
|
|
15
15
|
return React.createElement(IconButton, { ...rest, onClick: () => navigate(href) });
|
|
16
16
|
}
|
package/lib/mu/MoreFab.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { Divider, Fab, IconButton, ListItemIcon, ListItemText, Menu, MenuItem } from '@mui/material';
|
|
4
|
-
import { Link } from '
|
|
4
|
+
import { Link } from 'react-router-dom';
|
|
5
5
|
function getActions(input) {
|
|
6
6
|
// Actions
|
|
7
7
|
const actions = [];
|
package/lib/mu/RLink.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { LinkProps } from '@mui/material';
|
|
3
|
-
import { LinkProps as RouterLinkProps } from '
|
|
3
|
+
import { LinkProps as RouterLinkProps } from 'react-router-dom';
|
|
4
4
|
/**
|
|
5
5
|
* Router Link props
|
|
6
6
|
*/
|
|
7
|
-
export declare type RLinkProps = LinkProps & RouterLinkProps
|
|
7
|
+
export declare type RLinkProps = LinkProps & RouterLinkProps;
|
|
8
8
|
/**
|
|
9
9
|
* Router Link
|
|
10
10
|
* @param props Props
|
package/lib/mu/RLink.js
CHANGED
package/lib/mu/TabBox.js
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DomUtils } from '@etsoo/shared';
|
|
2
|
+
import { useParams } from 'react-router-dom';
|
|
3
|
+
/**
|
|
4
|
+
* Extended useParams of react-router-dom
|
|
5
|
+
* Provide exact type data
|
|
6
|
+
*/
|
|
7
|
+
export function useParamsEx(template) {
|
|
8
|
+
// Get parameters
|
|
9
|
+
const params = useParams();
|
|
10
|
+
// Return
|
|
11
|
+
return DomUtils.dataAs(params, template, false);
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/react",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.36",
|
|
4
4
|
"description": "TypeScript ReactJs framework",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -55,10 +55,8 @@
|
|
|
55
55
|
"@etsoo/shared": "^1.1.38",
|
|
56
56
|
"@mui/icons-material": "^5.8.0",
|
|
57
57
|
"@mui/material": "^5.8.1",
|
|
58
|
-
"@reach/router": "^1.3.4",
|
|
59
58
|
"@types/pica": "^9.0.0",
|
|
60
59
|
"@types/pulltorefreshjs": "^0.1.5",
|
|
61
|
-
"@types/reach__router": "^1.3.10",
|
|
62
60
|
"@types/react": "^18.0.9",
|
|
63
61
|
"@types/react-avatar-editor": "^12.0.0",
|
|
64
62
|
"@types/react-beautiful-dnd": "^13.1.2",
|
|
@@ -73,14 +71,15 @@
|
|
|
73
71
|
"react-dom": "^18.1.0",
|
|
74
72
|
"react-draggable": "^4.4.5",
|
|
75
73
|
"react-imask": "^6.4.2",
|
|
74
|
+
"react-router-dom": "^6.3.0",
|
|
76
75
|
"react-window": "^1.8.7"
|
|
77
76
|
},
|
|
78
77
|
"devDependencies": {
|
|
79
78
|
"@babel/cli": "^7.17.10",
|
|
80
|
-
"@babel/core": "^7.18.
|
|
81
|
-
"@babel/plugin-transform-runtime": "^7.18.
|
|
82
|
-
"@babel/preset-env": "^7.18.
|
|
83
|
-
"@babel/runtime-corejs3": "^7.18.
|
|
79
|
+
"@babel/core": "^7.18.2",
|
|
80
|
+
"@babel/plugin-transform-runtime": "^7.18.2",
|
|
81
|
+
"@babel/preset-env": "^7.18.2",
|
|
82
|
+
"@babel/runtime-corejs3": "^7.18.3",
|
|
84
83
|
"@types/jest": "^27.5.1",
|
|
85
84
|
"@types/react-test-renderer": "^18.0.0",
|
|
86
85
|
"@typescript-eslint/eslint-plugin": "^5.26.0",
|
package/src/app/ReactApp.ts
CHANGED
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
NotificationReturn
|
|
16
16
|
} from '@etsoo/notificationbase';
|
|
17
17
|
import { DataTypes, WindowStorage } from '@etsoo/shared';
|
|
18
|
-
import { History } from '@reach/router';
|
|
19
18
|
import React from 'react';
|
|
20
19
|
import { NotifierMU } from '../mu/NotifierMU';
|
|
21
20
|
import { ProgressCount } from '../mu/ProgressCount';
|
|
@@ -36,7 +35,7 @@ import {
|
|
|
36
35
|
} from '../states/UserState';
|
|
37
36
|
import { InputDialogProps } from './InputDialogProps';
|
|
38
37
|
import { Labels } from './Labels';
|
|
39
|
-
import {
|
|
38
|
+
import { createBrowserHistory, createMemoryHistory, History } from 'history';
|
|
40
39
|
|
|
41
40
|
/**
|
|
42
41
|
* Global application
|
|
@@ -101,7 +100,7 @@ export interface IReactApp<
|
|
|
101
100
|
/**
|
|
102
101
|
* Router history
|
|
103
102
|
*/
|
|
104
|
-
readonly history
|
|
103
|
+
readonly history: History;
|
|
105
104
|
|
|
106
105
|
/**
|
|
107
106
|
* Is screen size down 'sm'
|
|
@@ -175,7 +174,7 @@ export class ReactApp<
|
|
|
175
174
|
/**
|
|
176
175
|
* Router history
|
|
177
176
|
*/
|
|
178
|
-
readonly history
|
|
177
|
+
readonly history: History;
|
|
179
178
|
|
|
180
179
|
/**
|
|
181
180
|
* Page state
|
|
@@ -221,12 +220,12 @@ export class ReactApp<
|
|
|
221
220
|
name
|
|
222
221
|
);
|
|
223
222
|
|
|
224
|
-
this.history =
|
|
225
|
-
BridgeUtils.host == null
|
|
226
|
-
? undefined
|
|
227
|
-
: ReactUtils.getMemoryHistory(BridgeUtils.host.getStartUrl());
|
|
228
|
-
|
|
229
223
|
if (BridgeUtils.host) {
|
|
224
|
+
const startUrl = BridgeUtils.host.getStartUrl();
|
|
225
|
+
this.history = createMemoryHistory({
|
|
226
|
+
initialEntries: startUrl == null ? undefined : [startUrl]
|
|
227
|
+
});
|
|
228
|
+
|
|
230
229
|
BridgeUtils.host.onUpdate((app, version) => {
|
|
231
230
|
this.notifier.message(
|
|
232
231
|
NotificationMessageType.Success,
|
|
@@ -234,6 +233,8 @@ export class ReactApp<
|
|
|
234
233
|
this.get('updateReady')
|
|
235
234
|
);
|
|
236
235
|
});
|
|
236
|
+
} else {
|
|
237
|
+
this.history = createBrowserHistory();
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
this.cultureState = new CultureState(settings.currentCulture);
|
|
@@ -381,8 +382,7 @@ export class ReactApp<
|
|
|
381
382
|
* @param url Url
|
|
382
383
|
*/
|
|
383
384
|
override redirectTo(url: string) {
|
|
384
|
-
|
|
385
|
-
navigate(url);
|
|
385
|
+
this.history.push(url);
|
|
386
386
|
}
|
|
387
387
|
|
|
388
388
|
/**
|
package/src/app/ReactUtils.ts
CHANGED
|
@@ -1,98 +1,9 @@
|
|
|
1
|
-
import { createHistory, History, HistorySource, navigate } from '@reach/router';
|
|
2
1
|
import React from 'react';
|
|
3
2
|
|
|
4
|
-
type MemoryHistorySource = HistorySource & {
|
|
5
|
-
history: {
|
|
6
|
-
get entries(): any;
|
|
7
|
-
get index(): number;
|
|
8
|
-
go(to: number): void;
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
|
|
12
3
|
/**
|
|
13
4
|
* React utils
|
|
14
5
|
*/
|
|
15
6
|
export namespace ReactUtils {
|
|
16
|
-
// Memory history
|
|
17
|
-
// https://github.com/reach/router/issues/225
|
|
18
|
-
let memoryHistory: History | null;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Cretae memory source to fix go back bug
|
|
22
|
-
* @param initialPath Initial path
|
|
23
|
-
*/
|
|
24
|
-
export function createMemorySource(
|
|
25
|
-
initialPath: string = '/'
|
|
26
|
-
): MemoryHistorySource {
|
|
27
|
-
const searchIndex = initialPath.indexOf('?');
|
|
28
|
-
const pathname =
|
|
29
|
-
searchIndex > -1
|
|
30
|
-
? initialPath.substring(0, searchIndex)
|
|
31
|
-
: initialPath;
|
|
32
|
-
|
|
33
|
-
const initialLocation: any = {
|
|
34
|
-
pathname,
|
|
35
|
-
search: searchIndex > -1 ? initialPath.substring(searchIndex) : ''
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
let index = 0;
|
|
39
|
-
|
|
40
|
-
const stack = [initialLocation];
|
|
41
|
-
const states = [null];
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
get location() {
|
|
45
|
-
return stack[index];
|
|
46
|
-
},
|
|
47
|
-
addEventListener(name, fn) {},
|
|
48
|
-
removeEventListener(name, fn) {},
|
|
49
|
-
history: {
|
|
50
|
-
get entries() {
|
|
51
|
-
return stack;
|
|
52
|
-
},
|
|
53
|
-
get index() {
|
|
54
|
-
return index;
|
|
55
|
-
},
|
|
56
|
-
get state() {
|
|
57
|
-
return states[index];
|
|
58
|
-
},
|
|
59
|
-
pushState(state, _, uri) {
|
|
60
|
-
const [pathname, search = ''] = uri.split('?');
|
|
61
|
-
index++;
|
|
62
|
-
|
|
63
|
-
// View a, index = 0
|
|
64
|
-
// View b, index = 1
|
|
65
|
-
// Go(-1), a, index = 0
|
|
66
|
-
// View c, index = 1, directly push is wrong
|
|
67
|
-
if (index < stack.length) {
|
|
68
|
-
stack.splice(index);
|
|
69
|
-
states.splice(index);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
stack.push({
|
|
73
|
-
pathname,
|
|
74
|
-
search: search.length ? `?${search}` : search
|
|
75
|
-
});
|
|
76
|
-
states.push(state);
|
|
77
|
-
},
|
|
78
|
-
replaceState(state, _, uri) {
|
|
79
|
-
const [pathname, search = ''] = uri.split('?');
|
|
80
|
-
stack[index] = { pathname, search };
|
|
81
|
-
states[index] = state;
|
|
82
|
-
},
|
|
83
|
-
go(to: number) {
|
|
84
|
-
const newIndex = index + to;
|
|
85
|
-
|
|
86
|
-
if (newIndex < 0 || newIndex > states.length - 1) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
index = newIndex;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
7
|
/**
|
|
97
8
|
* Format input value
|
|
98
9
|
* @param value Input value
|
|
@@ -110,29 +21,6 @@ export namespace ReactUtils {
|
|
|
110
21
|
return String(value);
|
|
111
22
|
}
|
|
112
23
|
|
|
113
|
-
/**
|
|
114
|
-
* Get memory history
|
|
115
|
-
* @param initialPath Initial path
|
|
116
|
-
* @returns History
|
|
117
|
-
*/
|
|
118
|
-
export function getMemoryHistory(initialPath?: string | null) {
|
|
119
|
-
if (memoryHistory == null) {
|
|
120
|
-
memoryHistory = createHistory(
|
|
121
|
-
createMemorySource(initialPath ?? '/')
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
return memoryHistory;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Get navigate function, works with memory history
|
|
129
|
-
* @returns NavigateFn
|
|
130
|
-
*/
|
|
131
|
-
export function getNavigateFn() {
|
|
132
|
-
if (memoryHistory == null) return navigate;
|
|
133
|
-
return memoryHistory.navigate;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
24
|
/**
|
|
137
25
|
* Is safe click
|
|
138
26
|
* @param event Mouse event
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { HistoryRouterProps, Router } from 'react-router-dom';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Open to use HistoryRouter of react-router-dom
|
|
6
|
+
* @param History router properties
|
|
7
|
+
* @returns Component
|
|
8
|
+
*/
|
|
9
|
+
export function HRouter({ basename, children, history }: HistoryRouterProps) {
|
|
10
|
+
const [state, setState] = React.useState({
|
|
11
|
+
action: history.action,
|
|
12
|
+
location: history.location
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
React.useLayoutEffect(() => history.listen(setState), [history]);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Router
|
|
19
|
+
basename={basename}
|
|
20
|
+
children={children}
|
|
21
|
+
location={state.location}
|
|
22
|
+
navigationType={state.action}
|
|
23
|
+
navigator={history}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from './app/ServiceApp';
|
|
|
14
14
|
// components
|
|
15
15
|
export * from './components/GridColumn';
|
|
16
16
|
export * from './components/GridLoader';
|
|
17
|
+
export * from './components/HRouter';
|
|
17
18
|
export * from './components/ListItemReact';
|
|
18
19
|
export * from './components/ScrollerGrid';
|
|
19
20
|
export * from './components/ScrollerList';
|
|
@@ -95,7 +96,6 @@ export * from '@etsoo/notificationbase';
|
|
|
95
96
|
export * from './states/CultureState';
|
|
96
97
|
export * from './states/IState';
|
|
97
98
|
export * from './states/PageState';
|
|
98
|
-
export * from './states/RouterProps';
|
|
99
99
|
export * from './states/State';
|
|
100
100
|
export * from './states/UserState';
|
|
101
101
|
|
|
@@ -103,5 +103,6 @@ export * from './states/UserState';
|
|
|
103
103
|
export * from './uses/useCombinedRefs';
|
|
104
104
|
export * from './uses/useDelayedExecutor';
|
|
105
105
|
export * from './uses/useDimensions';
|
|
106
|
+
export * from './uses/useParamsEx';
|
|
106
107
|
export * from './uses/useTimeout';
|
|
107
108
|
export * from './uses/useWindowSize';
|
package/src/mu/BackButton.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IconButton, IconButtonProps, useTheme } from '@mui/material';
|
|
2
2
|
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { useNavigate } from 'react-router-dom';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* BackButton props
|
|
@@ -20,6 +20,9 @@ export function BackButton(props: BackButtonProps) {
|
|
|
20
20
|
// Theme
|
|
21
21
|
const theme = useTheme();
|
|
22
22
|
|
|
23
|
+
// Navigate
|
|
24
|
+
const navigate = useNavigate();
|
|
25
|
+
|
|
23
26
|
// Color
|
|
24
27
|
const pColor =
|
|
25
28
|
color != 'inherit' && color != 'default' && color in theme.palette
|
|
@@ -31,8 +34,7 @@ export function BackButton(props: BackButtonProps) {
|
|
|
31
34
|
if (onClick) onClick(event);
|
|
32
35
|
|
|
33
36
|
// Navigate
|
|
34
|
-
|
|
35
|
-
await navigate(-1);
|
|
37
|
+
navigate(-1);
|
|
36
38
|
};
|
|
37
39
|
|
|
38
40
|
return (
|
package/src/mu/ButtonLink.tsx
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Button, ButtonProps } from '@mui/material';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { useNavigate } from 'react-router-dom';
|
|
5
4
|
/**
|
|
6
5
|
* ButtonLink props
|
|
7
6
|
*/
|
|
@@ -22,7 +21,7 @@ export function ButtonLink(props: ButtonLinkProps) {
|
|
|
22
21
|
const { href, ...rest } = props;
|
|
23
22
|
|
|
24
23
|
// Navigate
|
|
25
|
-
const navigate =
|
|
24
|
+
const navigate = useNavigate();
|
|
26
25
|
|
|
27
26
|
const onClick = href.includes('://')
|
|
28
27
|
? () => window.open(href, '_blank')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IconButton, IconButtonProps } from '@mui/material';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { useNavigate } from 'react-router-dom';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* IconButtonLink props
|
|
@@ -22,7 +22,7 @@ export function IconButtonLink(props: IconButtonLinkProps) {
|
|
|
22
22
|
const { href, ...rest } = props;
|
|
23
23
|
|
|
24
24
|
// Navigate
|
|
25
|
-
const navigate =
|
|
25
|
+
const navigate = useNavigate();
|
|
26
26
|
|
|
27
27
|
// Layout
|
|
28
28
|
return <IconButton {...rest} onClick={() => navigate(href)} />;
|
package/src/mu/MoreFab.tsx
CHANGED
package/src/mu/RLink.tsx
CHANGED
|
@@ -2,13 +2,13 @@ import { Link, LinkProps } from '@mui/material';
|
|
|
2
2
|
import {
|
|
3
3
|
Link as RouterLink,
|
|
4
4
|
LinkProps as RouterLinkProps
|
|
5
|
-
} from '
|
|
5
|
+
} from 'react-router-dom';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Router Link props
|
|
10
10
|
*/
|
|
11
|
-
export type RLinkProps = LinkProps & RouterLinkProps
|
|
11
|
+
export type RLinkProps = LinkProps & RouterLinkProps;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Router Link
|
package/src/mu/TabBox.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Utils } from '@etsoo/shared';
|
|
2
2
|
import { Box, BoxProps, Tab, TabProps, Tabs, TabsProps } from '@mui/material';
|
|
3
|
-
import { Link } from '@reach/router';
|
|
4
3
|
import React from 'react';
|
|
4
|
+
import { Link } from 'react-router-dom';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Tab with box panel props
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DataTypes, DomUtils } from '@etsoo/shared';
|
|
2
|
+
import { useParams } from 'react-router-dom';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Extended useParams of react-router-dom
|
|
6
|
+
* Provide exact type data
|
|
7
|
+
*/
|
|
8
|
+
export function useParamsEx<T extends DataTypes.BasicTemplate>(template: T) {
|
|
9
|
+
// Get parameters
|
|
10
|
+
const params = useParams<{ [K in keyof T]: string }>();
|
|
11
|
+
|
|
12
|
+
// Return
|
|
13
|
+
return DomUtils.dataAs(params, template, false);
|
|
14
|
+
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { DataTypes } from '@etsoo/shared';
|
|
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 = IdRouterProps & WildcardRouterProps;
|
|
7
|
-
/**
|
|
8
|
-
* Get edit page id
|
|
9
|
-
* @param props Route props
|
|
10
|
-
* @param type Target data type
|
|
11
|
-
* @returns Data
|
|
12
|
-
*/
|
|
13
|
-
export declare function getEditPageId<T extends DataTypes.BasicNames>(props: EditPageRouterProps, type: T): DataTypes.BasicConditional<T> | undefined;
|
|
14
|
-
/**
|
|
15
|
-
* Id router props, include 'id' (/:id) query parameter
|
|
16
|
-
*/
|
|
17
|
-
export declare type IdRouterProps = RouteComponentProps<{
|
|
18
|
-
id: string;
|
|
19
|
-
}>;
|
|
20
|
-
/**
|
|
21
|
-
* Wildcard router props, (/*) query parameter
|
|
22
|
-
*/
|
|
23
|
-
export declare type WildcardRouterProps = RouteComponentProps<{
|
|
24
|
-
'*': string;
|
|
25
|
-
}>;
|
|
26
|
-
/**
|
|
27
|
-
* Id state router props, include 'id' in location.state
|
|
28
|
-
*/
|
|
29
|
-
export declare type IdStateRouterProps<T extends DataTypes.IdType = number> = StateRouterProps<{
|
|
30
|
-
id: T;
|
|
31
|
-
}>;
|
|
32
|
-
/**
|
|
33
|
-
* State router props, include data in location.state
|
|
34
|
-
*/
|
|
35
|
-
export declare type StateRouterProps<T extends Readonly<DataTypes.StringRecord>> = RouteComponentProps<{
|
|
36
|
-
location: {
|
|
37
|
-
state: T;
|
|
38
|
-
};
|
|
39
|
-
}>;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { DataTypes } from '@etsoo/shared';
|
|
2
|
-
/**
|
|
3
|
-
* Get edit page id
|
|
4
|
-
* @param props Route props
|
|
5
|
-
* @param type Target data type
|
|
6
|
-
* @returns Data
|
|
7
|
-
*/
|
|
8
|
-
export function getEditPageId(props, type) {
|
|
9
|
-
var _a;
|
|
10
|
-
const id = (_a = props.id) !== null && _a !== void 0 ? _a : props['*'];
|
|
11
|
-
if (id == null || id === '')
|
|
12
|
-
return undefined;
|
|
13
|
-
return DataTypes.convertByType(id, type);
|
|
14
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { DataTypes } from '@etsoo/shared';
|
|
2
|
-
import { RouteComponentProps } from '@reach/router';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Add / Edit page router props, include 'id' (/:id) or none when adding query parameter
|
|
6
|
-
*/
|
|
7
|
-
export type EditPageRouterProps = IdRouterProps & WildcardRouterProps;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Get edit page id
|
|
11
|
-
* @param props Route props
|
|
12
|
-
* @param type Target data type
|
|
13
|
-
* @returns Data
|
|
14
|
-
*/
|
|
15
|
-
export function getEditPageId<T extends DataTypes.BasicNames>(
|
|
16
|
-
props: EditPageRouterProps,
|
|
17
|
-
type: T
|
|
18
|
-
): DataTypes.BasicConditional<T> | undefined {
|
|
19
|
-
const id = props.id ?? props['*'];
|
|
20
|
-
if (id == null || id === '') return undefined;
|
|
21
|
-
return DataTypes.convertByType(id, type);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Id router props, include 'id' (/:id) query parameter
|
|
26
|
-
*/
|
|
27
|
-
export type IdRouterProps = RouteComponentProps<{ id: string }>;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Wildcard router props, (/*) query parameter
|
|
31
|
-
*/
|
|
32
|
-
export type WildcardRouterProps = RouteComponentProps<{ '*': string }>;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Id state router props, include 'id' in location.state
|
|
36
|
-
*/
|
|
37
|
-
export type IdStateRouterProps<T extends DataTypes.IdType = number> =
|
|
38
|
-
StateRouterProps<{ id: T }>;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* State router props, include data in location.state
|
|
42
|
-
*/
|
|
43
|
-
export type StateRouterProps<T extends Readonly<DataTypes.StringRecord>> =
|
|
44
|
-
RouteComponentProps<{
|
|
45
|
-
location: { state: T };
|
|
46
|
-
}>;
|