@etsoo/react 1.5.79 → 1.5.82
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/README.md +7 -2
- package/__tests__/ReactUtils.ts +6 -0
- package/lib/{mu → components}/DnDList.d.ts +1 -14
- package/lib/{mu → components}/DnDList.js +1 -24
- package/lib/components/GridMethodRef.d.ts +11 -0
- package/lib/{mu → components}/GridMethodRef.js +0 -0
- package/lib/components/ScrollerGrid.d.ts +3 -3
- package/lib/components/ScrollerList.d.ts +3 -3
- package/lib/index.d.ts +2 -74
- package/lib/index.js +2 -75
- package/lib/notifier/Notifier.d.ts +2 -3
- package/lib/uses/useWindowScroll.d.ts +10 -0
- package/lib/uses/useWindowScroll.js +46 -0
- package/lib/uses/useWindowSize.js +11 -5
- package/package.json +9 -21
- package/src/{mu → components}/DnDList.tsx +11 -34
- package/src/components/GridMethodRef.ts +12 -0
- package/src/components/ScrollerGrid.tsx +3 -3
- package/src/components/ScrollerList.tsx +5 -3
- package/src/index.ts +2 -78
- package/src/notifier/Notifier.ts +2 -3
- package/src/uses/useWindowScroll.ts +60 -0
- package/src/uses/useWindowSize.ts +14 -5
- package/__tests__/mu/MUGlobalTests.tsx +0 -58
- package/__tests__/mu/NotifierMUTests.tsx +0 -213
- package/lib/app/CommonApp.d.ts +0 -39
- package/lib/app/CommonApp.js +0 -149
- package/lib/app/IServiceAppSettings.d.ts +0 -11
- package/lib/app/IServiceAppSettings.js +0 -1
- package/lib/app/IServicePage.d.ts +0 -6
- package/lib/app/IServicePage.js +0 -1
- package/lib/app/IServiceUser.d.ts +0 -14
- package/lib/app/IServiceUser.js +0 -1
- package/lib/app/ISmartERPUser.d.ts +0 -14
- package/lib/app/ISmartERPUser.js +0 -1
- package/lib/app/Labels.d.ts +0 -65
- package/lib/app/Labels.js +0 -62
- package/lib/app/ReactApp.d.ts +0 -194
- package/lib/app/ReactApp.js +0 -298
- package/lib/app/ServiceApp.d.ts +0 -78
- package/lib/app/ServiceApp.js +0 -244
- package/lib/components/ShowDataComparison.d.ts +0 -20
- package/lib/components/ShowDataComparison.js +0 -60
- package/lib/mu/AuditDisplay.d.ts +0 -33
- package/lib/mu/AuditDisplay.js +0 -52
- package/lib/mu/AutocompleteExtendedProps.d.ts +0 -64
- package/lib/mu/AutocompleteExtendedProps.js +0 -1
- package/lib/mu/BackButton.d.ts +0 -13
- package/lib/mu/BackButton.js +0 -33
- package/lib/mu/BridgeCloseButton.d.ts +0 -23
- package/lib/mu/BridgeCloseButton.js +0 -32
- package/lib/mu/ButtonLink.d.ts +0 -17
- package/lib/mu/ButtonLink.js +0 -19
- package/lib/mu/ComboBox.d.ts +0 -38
- package/lib/mu/ComboBox.js +0 -108
- package/lib/mu/CountdownButton.d.ts +0 -23
- package/lib/mu/CountdownButton.js +0 -81
- package/lib/mu/CustomFabProps.d.ts +0 -27
- package/lib/mu/CustomFabProps.js +0 -1
- package/lib/mu/DataGridEx.d.ts +0 -96
- package/lib/mu/DataGridEx.js +0 -331
- package/lib/mu/DataGridRenderers.d.ts +0 -22
- package/lib/mu/DataGridRenderers.js +0 -99
- package/lib/mu/DialogButton.d.ts +0 -54
- package/lib/mu/DialogButton.js +0 -45
- package/lib/mu/DraggablePaperComponent.d.ts +0 -8
- package/lib/mu/DraggablePaperComponent.js +0 -12
- package/lib/mu/EmailInput.d.ts +0 -11
- package/lib/mu/EmailInput.js +0 -15
- package/lib/mu/FabBox.d.ts +0 -21
- package/lib/mu/FabBox.js +0 -31
- package/lib/mu/FlexBox.d.ts +0 -14
- package/lib/mu/FlexBox.js +0 -18
- package/lib/mu/GridDataFormat.d.ts +0 -10
- package/lib/mu/GridDataFormat.js +0 -43
- package/lib/mu/GridMethodRef.d.ts +0 -11
- package/lib/mu/IconButtonLink.d.ts +0 -17
- package/lib/mu/IconButtonLink.js +0 -16
- package/lib/mu/InputField.d.ts +0 -21
- package/lib/mu/InputField.js +0 -39
- package/lib/mu/ItemList.d.ts +0 -56
- package/lib/mu/ItemList.js +0 -69
- package/lib/mu/ListItemRightIcon.d.ts +0 -4
- package/lib/mu/ListItemRightIcon.js +0 -8
- package/lib/mu/ListMoreDisplay.d.ts +0 -35
- package/lib/mu/ListMoreDisplay.js +0 -99
- package/lib/mu/LoadingButton.d.ts +0 -16
- package/lib/mu/LoadingButton.js +0 -41
- package/lib/mu/MUGlobal.d.ts +0 -102
- package/lib/mu/MUGlobal.js +0 -184
- package/lib/mu/MaskInput.d.ts +0 -34
- package/lib/mu/MaskInput.js +0 -43
- package/lib/mu/MobileListItemRenderer.d.ts +0 -17
- package/lib/mu/MobileListItemRenderer.js +0 -35
- package/lib/mu/MoreFab.d.ts +0 -45
- package/lib/mu/MoreFab.js +0 -95
- package/lib/mu/NotifierMU.d.ts +0 -47
- package/lib/mu/NotifierMU.js +0 -387
- package/lib/mu/NotifierPromptProps.d.ts +0 -22
- package/lib/mu/NotifierPromptProps.js +0 -1
- package/lib/mu/OptionGroup.d.ts +0 -58
- package/lib/mu/OptionGroup.js +0 -81
- package/lib/mu/PList.d.ts +0 -15
- package/lib/mu/PList.js +0 -12
- package/lib/mu/ProgressCount.d.ts +0 -44
- package/lib/mu/ProgressCount.js +0 -79
- package/lib/mu/PullToRefreshUI.d.ts +0 -9
- package/lib/mu/PullToRefreshUI.js +0 -18
- package/lib/mu/RLink.d.ts +0 -14
- package/lib/mu/RLink.js +0 -37
- package/lib/mu/ResponsibleContainer.d.ts +0 -89
- package/lib/mu/ResponsibleContainer.js +0 -159
- package/lib/mu/ScrollTopFab.d.ts +0 -7
- package/lib/mu/ScrollTopFab.js +0 -25
- package/lib/mu/ScrollerListEx.d.ts +0 -81
- package/lib/mu/ScrollerListEx.js +0 -167
- package/lib/mu/SearchBar.d.ts +0 -29
- package/lib/mu/SearchBar.js +0 -262
- package/lib/mu/SearchField.d.ts +0 -21
- package/lib/mu/SearchField.js +0 -39
- package/lib/mu/SearchOptionGroup.d.ts +0 -9
- package/lib/mu/SearchOptionGroup.js +0 -14
- package/lib/mu/SelectBool.d.ts +0 -13
- package/lib/mu/SelectBool.js +0 -22
- package/lib/mu/SelectEx.d.ts +0 -50
- package/lib/mu/SelectEx.js +0 -156
- package/lib/mu/Switch.d.ts +0 -29
- package/lib/mu/Switch.js +0 -34
- package/lib/mu/SwitchAnt.d.ts +0 -25
- package/lib/mu/SwitchAnt.js +0 -40
- package/lib/mu/TabBox.d.ts +0 -54
- package/lib/mu/TabBox.js +0 -31
- package/lib/mu/TableEx.d.ts +0 -66
- package/lib/mu/TableEx.js +0 -271
- package/lib/mu/TextFieldEx.d.ts +0 -101
- package/lib/mu/TextFieldEx.js +0 -127
- package/lib/mu/Tiplist.d.ts +0 -18
- package/lib/mu/Tiplist.js +0 -158
- package/lib/mu/TooltipClick.d.ts +0 -15
- package/lib/mu/TooltipClick.js +0 -40
- package/lib/mu/UserAvatar.d.ts +0 -24
- package/lib/mu/UserAvatar.js +0 -25
- package/lib/mu/UserAvatarEditor.d.ts +0 -53
- package/lib/mu/UserAvatarEditor.js +0 -129
- package/lib/mu/pages/CommonPage.d.ts +0 -11
- package/lib/mu/pages/CommonPage.js +0 -60
- package/lib/mu/pages/CommonPageProps.d.ts +0 -60
- package/lib/mu/pages/CommonPageProps.js +0 -1
- package/lib/mu/pages/DataGridPage.d.ts +0 -9
- package/lib/mu/pages/DataGridPage.js +0 -81
- package/lib/mu/pages/DataGridPageProps.d.ts +0 -17
- package/lib/mu/pages/DataGridPageProps.js +0 -1
- package/lib/mu/pages/EditPage.d.ts +0 -33
- package/lib/mu/pages/EditPage.js +0 -29
- package/lib/mu/pages/FixedListPage.d.ts +0 -15
- package/lib/mu/pages/FixedListPage.js +0 -72
- package/lib/mu/pages/ListPage.d.ts +0 -9
- package/lib/mu/pages/ListPage.js +0 -51
- package/lib/mu/pages/ListPageProps.d.ts +0 -7
- package/lib/mu/pages/ListPageProps.js +0 -1
- package/lib/mu/pages/ResponsivePage.d.ts +0 -9
- package/lib/mu/pages/ResponsivePage.js +0 -45
- package/lib/mu/pages/ResponsivePageProps.d.ts +0 -39
- package/lib/mu/pages/ResponsivePageProps.js +0 -1
- package/lib/mu/pages/SearchPageProps.d.ts +0 -30
- package/lib/mu/pages/SearchPageProps.js +0 -1
- package/lib/mu/pages/TablePage.d.ts +0 -9
- package/lib/mu/pages/TablePage.js +0 -71
- package/lib/mu/pages/TablePageProps.d.ts +0 -7
- package/lib/mu/pages/TablePageProps.js +0 -1
- package/lib/mu/pages/ViewPage.d.ts +0 -66
- package/lib/mu/pages/ViewPage.js +0 -105
- package/lib/mu/texts/DateText.d.ts +0 -34
- package/lib/mu/texts/DateText.js +0 -25
- package/lib/mu/texts/MoneyText.d.ts +0 -21
- package/lib/mu/texts/MoneyText.js +0 -14
- package/lib/mu/texts/NumberText.d.ts +0 -25
- package/lib/mu/texts/NumberText.js +0 -14
- package/src/app/CommonApp.ts +0 -225
- package/src/app/IServiceAppSettings.ts +0 -13
- package/src/app/IServicePage.ts +0 -6
- package/src/app/IServiceUser.ts +0 -17
- package/src/app/ISmartERPUser.ts +0 -16
- package/src/app/Labels.ts +0 -77
- package/src/app/ReactApp.ts +0 -500
- package/src/app/ServiceApp.ts +0 -353
- package/src/components/ShowDataComparison.tsx +0 -108
- package/src/mu/AuditDisplay.tsx +0 -117
- package/src/mu/AutocompleteExtendedProps.ts +0 -83
- package/src/mu/BackButton.tsx +0 -55
- package/src/mu/BridgeCloseButton.tsx +0 -69
- package/src/mu/ButtonLink.tsx +0 -32
- package/src/mu/ComboBox.tsx +0 -251
- package/src/mu/CountdownButton.tsx +0 -119
- package/src/mu/CustomFabProps.ts +0 -32
- package/src/mu/DataGridEx.tsx +0 -712
- package/src/mu/DataGridRenderers.tsx +0 -140
- package/src/mu/DialogButton.tsx +0 -163
- package/src/mu/DraggablePaperComponent.tsx +0 -19
- package/src/mu/EmailInput.tsx +0 -24
- package/src/mu/FabBox.tsx +0 -51
- package/src/mu/FlexBox.tsx +0 -20
- package/src/mu/GridDataFormat.tsx +0 -77
- package/src/mu/GridMethodRef.ts +0 -12
- package/src/mu/IconButtonLink.tsx +0 -29
- package/src/mu/InputField.tsx +0 -82
- package/src/mu/ItemList.tsx +0 -204
- package/src/mu/ListItemRightIcon.tsx +0 -9
- package/src/mu/ListMoreDisplay.tsx +0 -205
- package/src/mu/LoadingButton.tsx +0 -75
- package/src/mu/MUGlobal.ts +0 -220
- package/src/mu/MaskInput.tsx +0 -107
- package/src/mu/MobileListItemRenderer.tsx +0 -79
- package/src/mu/MoreFab.tsx +0 -211
- package/src/mu/NotifierMU.tsx +0 -654
- package/src/mu/NotifierPromptProps.ts +0 -26
- package/src/mu/OptionGroup.tsx +0 -223
- package/src/mu/PList.tsx +0 -27
- package/src/mu/ProgressCount.tsx +0 -166
- package/src/mu/PullToRefreshUI.tsx +0 -21
- package/src/mu/RLink.tsx +0 -64
- package/src/mu/ResponsibleContainer.tsx +0 -394
- package/src/mu/ScrollTopFab.tsx +0 -34
- package/src/mu/ScrollerListEx.tsx +0 -387
- package/src/mu/SearchBar.tsx +0 -398
- package/src/mu/SearchField.tsx +0 -82
- package/src/mu/SearchOptionGroup.tsx +0 -31
- package/src/mu/SelectBool.tsx +0 -33
- package/src/mu/SelectEx.tsx +0 -290
- package/src/mu/Switch.tsx +0 -94
- package/src/mu/SwitchAnt.tsx +0 -95
- package/src/mu/TabBox.tsx +0 -118
- package/src/mu/TableEx.tsx +0 -560
- package/src/mu/TextFieldEx.tsx +0 -250
- package/src/mu/Tiplist.tsx +0 -304
- package/src/mu/TooltipClick.tsx +0 -84
- package/src/mu/UserAvatar.tsx +0 -64
- package/src/mu/UserAvatarEditor.tsx +0 -287
- package/src/mu/pages/CommonPage.tsx +0 -128
- package/src/mu/pages/CommonPageProps.ts +0 -71
- package/src/mu/pages/DataGridPage.tsx +0 -137
- package/src/mu/pages/DataGridPageProps.ts +0 -24
- package/src/mu/pages/EditPage.tsx +0 -114
- package/src/mu/pages/FixedListPage.tsx +0 -135
- package/src/mu/pages/ListPage.tsx +0 -87
- package/src/mu/pages/ListPageProps.ts +0 -12
- package/src/mu/pages/ResponsivePage.tsx +0 -68
- package/src/mu/pages/ResponsivePageProps.ts +0 -57
- package/src/mu/pages/SearchPageProps.ts +0 -39
- package/src/mu/pages/TablePage.tsx +0 -120
- package/src/mu/pages/TablePageProps.ts +0 -12
- package/src/mu/pages/ViewPage.tsx +0 -285
- package/src/mu/texts/DateText.tsx +0 -74
- package/src/mu/texts/MoneyText.tsx +0 -49
- package/src/mu/texts/NumberText.tsx +0 -40
package/src/app/ServiceApp.ts
DELETED
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BridgeUtils,
|
|
3
|
-
createClient,
|
|
4
|
-
IActionResult,
|
|
5
|
-
IApi,
|
|
6
|
-
IApiPayload,
|
|
7
|
-
RefreshTokenProps,
|
|
8
|
-
RefreshTokenResult
|
|
9
|
-
} from '@etsoo/appscript';
|
|
10
|
-
import { DomUtils } from '@etsoo/shared';
|
|
11
|
-
import { CoreConstants } from './CoreConstants';
|
|
12
|
-
import { IServiceAppSettings } from './IServiceAppSettings';
|
|
13
|
-
import { IServicePageData } from './IServicePage';
|
|
14
|
-
import { IServiceUser, ServiceLoginResult } from './IServiceUser';
|
|
15
|
-
import { ISmartERPUser } from './ISmartERPUser';
|
|
16
|
-
import { ReactApp } from './ReactApp';
|
|
17
|
-
import { RefreshTokenRQ } from './RefreshTokenRQ';
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Core Service App
|
|
21
|
-
* Service login to core system, get the refesh token and access token
|
|
22
|
-
* Use the acess token to the service api, get a service access token
|
|
23
|
-
* Use the new acess token and refresh token to login
|
|
24
|
-
*/
|
|
25
|
-
export class ServiceApp<
|
|
26
|
-
U extends IServiceUser = IServiceUser,
|
|
27
|
-
P extends IServicePageData = IServicePageData,
|
|
28
|
-
S extends IServiceAppSettings = IServiceAppSettings
|
|
29
|
-
> extends ReactApp<S, ISmartERPUser, P> {
|
|
30
|
-
/**
|
|
31
|
-
* Service API
|
|
32
|
-
*/
|
|
33
|
-
readonly serviceApi: IApi;
|
|
34
|
-
|
|
35
|
-
private _serviceUser?: U;
|
|
36
|
-
/**
|
|
37
|
-
* Service user
|
|
38
|
-
*/
|
|
39
|
-
get serviceUser() {
|
|
40
|
-
return this._serviceUser;
|
|
41
|
-
}
|
|
42
|
-
protected set serviceUser(value: U | undefined) {
|
|
43
|
-
this._serviceUser = value;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Service passphrase
|
|
48
|
-
*/
|
|
49
|
-
protected servicePassphrase: string = '';
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Constructor
|
|
53
|
-
* @param settings Settings
|
|
54
|
-
* @param name Application name
|
|
55
|
-
*/
|
|
56
|
-
constructor(settings: S, name: string) {
|
|
57
|
-
super(settings, name);
|
|
58
|
-
|
|
59
|
-
// Check
|
|
60
|
-
if (settings.serviceId == null || settings.serviceEndpoint == null) {
|
|
61
|
-
throw new Error('No service settings');
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Service API
|
|
65
|
-
const api = createClient();
|
|
66
|
-
api.baseUrl = settings.serviceEndpoint;
|
|
67
|
-
|
|
68
|
-
this.setApi(api);
|
|
69
|
-
this.serviceApi = api;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Load SmartERP core
|
|
74
|
-
*/
|
|
75
|
-
loadSmartERP() {
|
|
76
|
-
if (BridgeUtils.host == null) {
|
|
77
|
-
window.location.href = this.settings.webUrl;
|
|
78
|
-
} else {
|
|
79
|
-
BridgeUtils.host.loadApp('core');
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Go to the login page
|
|
85
|
-
* @param tryLogin Try to login again
|
|
86
|
-
*/
|
|
87
|
-
override toLoginPage(tryLogin?: boolean) {
|
|
88
|
-
const parameters = `?serviceId=${this.settings.serviceId}&${
|
|
89
|
-
DomUtils.CultureField
|
|
90
|
-
}=${this.culture}${tryLogin ? '' : '&tryLogin=false'}`;
|
|
91
|
-
|
|
92
|
-
if (BridgeUtils.host == null) {
|
|
93
|
-
const coreUrl = this.settings.webUrl;
|
|
94
|
-
window.location.href = coreUrl + parameters;
|
|
95
|
-
} else {
|
|
96
|
-
BridgeUtils.host.loadApp('core', parameters);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Refresh token
|
|
102
|
-
* @param props Props
|
|
103
|
-
*/
|
|
104
|
-
override async refreshToken<D extends object = RefreshTokenRQ>(
|
|
105
|
-
props?: RefreshTokenProps<D>
|
|
106
|
-
) {
|
|
107
|
-
// Destruct
|
|
108
|
-
const {
|
|
109
|
-
callback,
|
|
110
|
-
data,
|
|
111
|
-
relogin = false,
|
|
112
|
-
showLoading = false
|
|
113
|
-
} = props ?? {};
|
|
114
|
-
|
|
115
|
-
// Token
|
|
116
|
-
const token = this.getCacheToken();
|
|
117
|
-
if (token == null || token === '') {
|
|
118
|
-
if (callback) callback(false);
|
|
119
|
-
return false;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Reqest data
|
|
123
|
-
// Merge additional data passed
|
|
124
|
-
const rq: RefreshTokenRQ = {
|
|
125
|
-
deviceId: this.deviceId,
|
|
126
|
-
timezone: this.getTimeZone(),
|
|
127
|
-
...data
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
// Login result type
|
|
131
|
-
type LoginResult = IActionResult<U>;
|
|
132
|
-
|
|
133
|
-
// Payload
|
|
134
|
-
const payload: IApiPayload<LoginResult, any> = {
|
|
135
|
-
showLoading,
|
|
136
|
-
config: { headers: { [CoreConstants.TokenHeaderRefresh]: token } },
|
|
137
|
-
onError: (error) => {
|
|
138
|
-
if (callback) callback(error);
|
|
139
|
-
|
|
140
|
-
// Prevent further processing
|
|
141
|
-
return false;
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
// Success callback
|
|
146
|
-
const success = async (
|
|
147
|
-
result: LoginResult,
|
|
148
|
-
failCallback?: (result: RefreshTokenResult) => void
|
|
149
|
-
) => {
|
|
150
|
-
// Token
|
|
151
|
-
const refreshToken = this.getResponseToken(payload.response);
|
|
152
|
-
if (refreshToken == null || result.data == null) {
|
|
153
|
-
if (failCallback) failCallback(this.get('noData')!);
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// User data
|
|
158
|
-
const userData = result.data;
|
|
159
|
-
|
|
160
|
-
// Use core system access token to service api to exchange service access token
|
|
161
|
-
const serviceResult = await this.serviceApi.put<
|
|
162
|
-
ServiceLoginResult<U>
|
|
163
|
-
>(
|
|
164
|
-
'Auth/ExchangeToken',
|
|
165
|
-
{
|
|
166
|
-
token: this.encryptEnhanced(
|
|
167
|
-
userData.token,
|
|
168
|
-
this.settings.serviceId.toString()
|
|
169
|
-
)
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
showLoading,
|
|
173
|
-
onError: (error) => {
|
|
174
|
-
if (failCallback) failCallback(error);
|
|
175
|
-
|
|
176
|
-
// Prevent further processing
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
if (serviceResult == null) return false;
|
|
183
|
-
|
|
184
|
-
if (!serviceResult.ok) {
|
|
185
|
-
if (failCallback) failCallback(serviceResult);
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (serviceResult.data == null) {
|
|
190
|
-
if (failCallback) failCallback(this.get('noData')!);
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Login
|
|
195
|
-
this.userLoginEx(userData, refreshToken, serviceResult.data);
|
|
196
|
-
|
|
197
|
-
// Success callback
|
|
198
|
-
if (failCallback) failCallback(true);
|
|
199
|
-
|
|
200
|
-
return true;
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
// Call API
|
|
204
|
-
const result = await this.api.put<LoginResult>(
|
|
205
|
-
'Auth/RefreshToken',
|
|
206
|
-
rq,
|
|
207
|
-
payload
|
|
208
|
-
);
|
|
209
|
-
if (result == null) return false;
|
|
210
|
-
|
|
211
|
-
if (!result.ok) {
|
|
212
|
-
if (result.type === 'TokenExpired' && relogin) {
|
|
213
|
-
// Try login
|
|
214
|
-
// Dialog to receive password
|
|
215
|
-
var labels = this.getLabels('reloginTip', 'login');
|
|
216
|
-
this.notifier.prompt(
|
|
217
|
-
labels.reloginTip,
|
|
218
|
-
async (pwd) => {
|
|
219
|
-
if (pwd == null) {
|
|
220
|
-
this.toLoginPage();
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Set password for the action
|
|
225
|
-
rq.pwd = this.encrypt(this.hash(pwd));
|
|
226
|
-
|
|
227
|
-
// Submit again
|
|
228
|
-
const result = await this.api.put<LoginResult>(
|
|
229
|
-
'Auth/RefreshToken',
|
|
230
|
-
rq,
|
|
231
|
-
payload
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
if (result == null) return;
|
|
235
|
-
|
|
236
|
-
if (result.ok) {
|
|
237
|
-
await success(
|
|
238
|
-
result,
|
|
239
|
-
(loginResult: RefreshTokenResult) => {
|
|
240
|
-
if (loginResult === true) {
|
|
241
|
-
if (callback) callback(true);
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const message =
|
|
246
|
-
this.formatRefreshTokenResult(
|
|
247
|
-
loginResult
|
|
248
|
-
);
|
|
249
|
-
if (message) this.notifier.alert(message);
|
|
250
|
-
}
|
|
251
|
-
);
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// Popup message
|
|
256
|
-
this.alertResult(result);
|
|
257
|
-
return false;
|
|
258
|
-
},
|
|
259
|
-
labels.login,
|
|
260
|
-
{ type: 'password' }
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
// Fake truth to avoid reloading
|
|
264
|
-
return true;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (callback) callback(result);
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
return await success(result, callback);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Service decrypt message
|
|
276
|
-
* @param messageEncrypted Encrypted message
|
|
277
|
-
* @param passphrase Secret passphrase
|
|
278
|
-
* @returns Pure text
|
|
279
|
-
*/
|
|
280
|
-
serviceDecrypt(messageEncrypted: string, passphrase?: string) {
|
|
281
|
-
return this.decrypt(
|
|
282
|
-
messageEncrypted,
|
|
283
|
-
passphrase ?? this.servicePassphrase
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Service encrypt message
|
|
289
|
-
* @param message Message
|
|
290
|
-
* @param passphrase Secret passphrase
|
|
291
|
-
* @param iterations Iterations, 1000 times, 1 - 99
|
|
292
|
-
* @returns Result
|
|
293
|
-
*/
|
|
294
|
-
serviceEncrypt(message: string, passphrase?: string, iterations?: number) {
|
|
295
|
-
return this.encrypt(
|
|
296
|
-
message,
|
|
297
|
-
passphrase ?? this.servicePassphrase,
|
|
298
|
-
iterations
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Try login
|
|
304
|
-
* @param data Additional data
|
|
305
|
-
* @param showLoading Show loading bar or not
|
|
306
|
-
* @returns Result
|
|
307
|
-
*/
|
|
308
|
-
override async tryLogin<D extends object = {}>(
|
|
309
|
-
data?: D,
|
|
310
|
-
showLoading?: boolean
|
|
311
|
-
) {
|
|
312
|
-
// Reset user state
|
|
313
|
-
const result = await super.tryLogin(data, showLoading);
|
|
314
|
-
if (!result) return false;
|
|
315
|
-
|
|
316
|
-
// Refresh token
|
|
317
|
-
return await this.refreshToken({
|
|
318
|
-
callback: (result) => this.doRefreshTokenResult(result),
|
|
319
|
-
data,
|
|
320
|
-
showLoading,
|
|
321
|
-
relogin: true
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* User login extended
|
|
327
|
-
* @param user Core system user
|
|
328
|
-
* @param refreshToken Refresh token
|
|
329
|
-
* @param serviceUser Service user
|
|
330
|
-
*/
|
|
331
|
-
userLoginEx(
|
|
332
|
-
user: ISmartERPUser,
|
|
333
|
-
refreshToken: string,
|
|
334
|
-
serviceUser: U
|
|
335
|
-
): void {
|
|
336
|
-
// Service user login
|
|
337
|
-
this.servicePassphrase =
|
|
338
|
-
this.decrypt(
|
|
339
|
-
serviceUser.serviceDeviceId,
|
|
340
|
-
this.settings.serviceId.toString()
|
|
341
|
-
) ?? '';
|
|
342
|
-
|
|
343
|
-
// Service user
|
|
344
|
-
this.serviceUser = serviceUser;
|
|
345
|
-
|
|
346
|
-
// Service API token
|
|
347
|
-
this.serviceApi.authorize(this.settings.authScheme, serviceUser.token);
|
|
348
|
-
|
|
349
|
-
// Keep = true, means service could hold the refresh token for long access
|
|
350
|
-
// Trigger Context change and serviceUser is ready then
|
|
351
|
-
super.userLogin(user, refreshToken, true);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { NotificationMessageType } from '@etsoo/notificationbase';
|
|
2
|
-
import { Utils } from '@etsoo/shared';
|
|
3
|
-
import {
|
|
4
|
-
Table,
|
|
5
|
-
TableBody,
|
|
6
|
-
TableCell,
|
|
7
|
-
TableHead,
|
|
8
|
-
TableRow
|
|
9
|
-
} from '@mui/material';
|
|
10
|
-
import React from 'react';
|
|
11
|
-
import { globalApp } from '../app/ReactApp';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Audit line update data model
|
|
15
|
-
*/
|
|
16
|
-
export interface AuditLineUpdateData {
|
|
17
|
-
oldData: Record<string, unknown>;
|
|
18
|
-
newData: Record<string, unknown>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Check obj is instance of AuditLineUpdateData
|
|
23
|
-
* @param obj Input
|
|
24
|
-
* @returns Result
|
|
25
|
-
*/
|
|
26
|
-
export function IsAuditLineUpdateData(obj: any): obj is AuditLineUpdateData {
|
|
27
|
-
return (
|
|
28
|
-
typeof obj === 'object' &&
|
|
29
|
-
'oldData' in obj &&
|
|
30
|
-
typeof obj.oldData === 'object' &&
|
|
31
|
-
'newData' in obj &&
|
|
32
|
-
typeof obj.newData === 'object'
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Format value
|
|
37
|
-
const formatValue = (value: unknown) => {
|
|
38
|
-
if (value == null) return '';
|
|
39
|
-
if (value instanceof Date && typeof globalApp !== 'undefined')
|
|
40
|
-
return globalApp.formatDate(value, 'ds');
|
|
41
|
-
return `${value}`;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Show data comparison
|
|
46
|
-
* @param data Data
|
|
47
|
-
* @param modelTitle Model window title
|
|
48
|
-
* @param getLabel Get label callback
|
|
49
|
-
*/
|
|
50
|
-
export const ShowDataComparison = (
|
|
51
|
-
data: AuditLineUpdateData,
|
|
52
|
-
modelTitle?: string,
|
|
53
|
-
getLabel?: (field: string) => string
|
|
54
|
-
) => {
|
|
55
|
-
if (typeof globalApp === 'undefined') return;
|
|
56
|
-
|
|
57
|
-
modelTitle ??= globalApp.get<string>('dataComparison');
|
|
58
|
-
getLabel ??= (key) => {
|
|
59
|
-
return globalApp.get(Utils.formatInitial(key)) ?? key;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const keys = new Set([
|
|
63
|
-
...Object.keys(data.oldData),
|
|
64
|
-
...Object.keys(data.newData)
|
|
65
|
-
]);
|
|
66
|
-
|
|
67
|
-
const rows = Array.from(keys).map((field) => ({
|
|
68
|
-
field,
|
|
69
|
-
oldValue: data.oldData[field],
|
|
70
|
-
newValue: data.newData[field]
|
|
71
|
-
}));
|
|
72
|
-
|
|
73
|
-
const inputs = (
|
|
74
|
-
<Table>
|
|
75
|
-
<TableHead>
|
|
76
|
-
<TableRow>
|
|
77
|
-
<TableCell width="18%">{getLabel('field')}</TableCell>
|
|
78
|
-
<TableCell width="41%" align="right">
|
|
79
|
-
{getLabel('oldValue')}
|
|
80
|
-
</TableCell>
|
|
81
|
-
<TableCell width="41%" align="right">
|
|
82
|
-
{getLabel('newValue')}
|
|
83
|
-
</TableCell>
|
|
84
|
-
</TableRow>
|
|
85
|
-
</TableHead>
|
|
86
|
-
<TableBody>
|
|
87
|
-
{rows.map((row) => (
|
|
88
|
-
<TableRow key={row.field}>
|
|
89
|
-
<TableCell>{getLabel!(row.field)}</TableCell>
|
|
90
|
-
<TableCell align="right">
|
|
91
|
-
{formatValue(row.oldValue)}
|
|
92
|
-
</TableCell>
|
|
93
|
-
<TableCell align="right">
|
|
94
|
-
{formatValue(row.newValue)}
|
|
95
|
-
</TableCell>
|
|
96
|
-
</TableRow>
|
|
97
|
-
))}
|
|
98
|
-
</TableBody>
|
|
99
|
-
</Table>
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
globalApp.notifier.alert(
|
|
103
|
-
[undefined, modelTitle],
|
|
104
|
-
undefined,
|
|
105
|
-
NotificationMessageType.Info,
|
|
106
|
-
{ fullScreen: globalApp.smDown, inputs }
|
|
107
|
-
);
|
|
108
|
-
};
|
package/src/mu/AuditDisplay.tsx
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { Utils } from '@etsoo/shared';
|
|
2
|
-
import { Button, Divider, Theme, Typography, useTheme } from '@mui/material';
|
|
3
|
-
import React, { CSSProperties } from 'react';
|
|
4
|
-
import { globalApp } from '..';
|
|
5
|
-
import {
|
|
6
|
-
AuditLineUpdateData,
|
|
7
|
-
ShowDataComparison
|
|
8
|
-
} from '../components/ShowDataComparison';
|
|
9
|
-
import { ListMoreDisplay, ListMoreDisplayProps } from './ListMoreDisplay';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Audit line data model
|
|
13
|
-
*/
|
|
14
|
-
export interface AuditLine {
|
|
15
|
-
id: number;
|
|
16
|
-
creation: Date;
|
|
17
|
-
user: string;
|
|
18
|
-
action: string;
|
|
19
|
-
changes?: AuditLineUpdateData;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Audit display props
|
|
24
|
-
*/
|
|
25
|
-
export interface AuditDisplayProps
|
|
26
|
-
extends Omit<ListMoreDisplayProps<AuditLine>, 'children'> {
|
|
27
|
-
/**
|
|
28
|
-
* Get list item style callback
|
|
29
|
-
*/
|
|
30
|
-
getItemStyle?: (index: number, theme: Theme) => CSSProperties;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Item/line renderer
|
|
34
|
-
*/
|
|
35
|
-
itemRenderer?: (data: AuditLine, index: number) => React.ReactNode;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Get label
|
|
39
|
-
const getLabel = (key: string) => {
|
|
40
|
-
return globalApp.get(Utils.formatInitial(key)) ?? key;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Format date
|
|
44
|
-
const formatDate = (date: Date) => {
|
|
45
|
-
if (typeof globalApp === 'undefined') return date.toUTCString();
|
|
46
|
-
return globalApp.formatDate(date, 'ds');
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Audit display
|
|
51
|
-
* @param props Props
|
|
52
|
-
* @returns Component
|
|
53
|
-
*/
|
|
54
|
-
export function AuditDisplay(props: AuditDisplayProps) {
|
|
55
|
-
// Theme
|
|
56
|
-
const theme = useTheme();
|
|
57
|
-
|
|
58
|
-
// Title
|
|
59
|
-
var title = getLabel('dataComparison');
|
|
60
|
-
|
|
61
|
-
// Destruct
|
|
62
|
-
const {
|
|
63
|
-
getItemStyle = (index, theme) => ({
|
|
64
|
-
padding: [theme.spacing(1.5), theme.spacing(1)].join(' '),
|
|
65
|
-
background:
|
|
66
|
-
index % 2 === 0
|
|
67
|
-
? theme.palette.grey[100]
|
|
68
|
-
: theme.palette.grey[50]
|
|
69
|
-
}),
|
|
70
|
-
itemRenderer = (data) => {
|
|
71
|
-
const changes = data.changes;
|
|
72
|
-
return (
|
|
73
|
-
<React.Fragment>
|
|
74
|
-
{changes != null && (
|
|
75
|
-
<Button
|
|
76
|
-
variant="outlined"
|
|
77
|
-
size="small"
|
|
78
|
-
onClick={() => ShowDataComparison(changes, title)}
|
|
79
|
-
sx={{
|
|
80
|
-
marginLeft: theme.spacing(1),
|
|
81
|
-
marginTop: theme.spacing(-0.5),
|
|
82
|
-
float: 'right'
|
|
83
|
-
}}
|
|
84
|
-
>
|
|
85
|
-
{title}
|
|
86
|
-
</Button>
|
|
87
|
-
)}
|
|
88
|
-
<Typography>
|
|
89
|
-
{formatDate(data.creation) +
|
|
90
|
-
', [' +
|
|
91
|
-
getLabel(data.action) +
|
|
92
|
-
'], ' +
|
|
93
|
-
data.user}
|
|
94
|
-
</Typography>
|
|
95
|
-
</React.Fragment>
|
|
96
|
-
);
|
|
97
|
-
},
|
|
98
|
-
headerTitle = (
|
|
99
|
-
<React.Fragment>
|
|
100
|
-
<Typography>{getLabel('audits')}</Typography>
|
|
101
|
-
<Divider />
|
|
102
|
-
</React.Fragment>
|
|
103
|
-
),
|
|
104
|
-
...rest
|
|
105
|
-
} = props;
|
|
106
|
-
|
|
107
|
-
// Layout
|
|
108
|
-
return (
|
|
109
|
-
<ListMoreDisplay headerTitle={headerTitle} {...rest}>
|
|
110
|
-
{(data, index) => (
|
|
111
|
-
<div key={data.id} style={getItemStyle(index, theme)}>
|
|
112
|
-
{itemRenderer(data, index)}
|
|
113
|
-
</div>
|
|
114
|
-
)}
|
|
115
|
-
</ListMoreDisplay>
|
|
116
|
-
);
|
|
117
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { DataTypes } from '@etsoo/shared';
|
|
2
|
-
import { AutocompleteProps } from '@mui/material';
|
|
3
|
-
import { ChangeEventHandler } from 'react';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Autocomplete extended props
|
|
7
|
-
*/
|
|
8
|
-
export type AutocompleteExtendedProps<
|
|
9
|
-
T extends object,
|
|
10
|
-
D extends DataTypes.Keys<T>
|
|
11
|
-
> = Omit<
|
|
12
|
-
AutocompleteProps<T, undefined, false, false>,
|
|
13
|
-
'renderInput' | 'options'
|
|
14
|
-
> & {
|
|
15
|
-
/**
|
|
16
|
-
* Id field
|
|
17
|
-
*/
|
|
18
|
-
idField?: D;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Id value
|
|
22
|
-
*/
|
|
23
|
-
idValue?: T[D];
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Autocomplete for the input
|
|
27
|
-
*/
|
|
28
|
-
inputAutoComplete?: string;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* If `true`, the label is displayed in an error state.
|
|
32
|
-
* @default false
|
|
33
|
-
*/
|
|
34
|
-
inputError?: boolean;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* The helper text content.
|
|
38
|
-
*/
|
|
39
|
-
inputHelperText?: React.ReactNode;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* If `dense` or `normal`, will adjust vertical spacing of this and contained components.
|
|
43
|
-
* @default 'none'
|
|
44
|
-
*/
|
|
45
|
-
inputMargin?: 'dense' | 'normal' | 'none';
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Input onChange hanlder
|
|
49
|
-
*/
|
|
50
|
-
inputOnChange?: ChangeEventHandler<HTMLInputElement> | undefined;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* If `true`, the label will indicate that the `input` is required.
|
|
54
|
-
* @default false
|
|
55
|
-
*/
|
|
56
|
-
inputRequired?: boolean;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* The variant to use.
|
|
60
|
-
* @default 'outlined'
|
|
61
|
-
*/
|
|
62
|
-
inputVariant?: 'standard' | 'outlined' | 'filled';
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Label of the field
|
|
66
|
-
*/
|
|
67
|
-
label: string;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Name of the field
|
|
71
|
-
*/
|
|
72
|
-
name: string;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Is the field read only?
|
|
76
|
-
*/
|
|
77
|
-
readOnly?: boolean;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Is search field?
|
|
81
|
-
*/
|
|
82
|
-
search?: boolean;
|
|
83
|
-
};
|
package/src/mu/BackButton.tsx
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { IconButton, IconButtonProps, useTheme } from '@mui/material';
|
|
2
|
-
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { useNavigate } from 'react-router-dom';
|
|
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
|
-
// Theme
|
|
21
|
-
const theme = useTheme();
|
|
22
|
-
|
|
23
|
-
// Navigate
|
|
24
|
-
const navigate = useNavigate();
|
|
25
|
-
|
|
26
|
-
// Color
|
|
27
|
-
const pColor =
|
|
28
|
-
color != 'inherit' && color != 'default' && color in theme.palette
|
|
29
|
-
? theme.palette[color]
|
|
30
|
-
: theme.palette.primary;
|
|
31
|
-
|
|
32
|
-
// Click handler
|
|
33
|
-
const onClickLocal = async (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
34
|
-
if (onClick) onClick(event);
|
|
35
|
-
|
|
36
|
-
// Navigate
|
|
37
|
-
navigate(-1);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<IconButton
|
|
42
|
-
aria-label="Back"
|
|
43
|
-
color={color}
|
|
44
|
-
size={size}
|
|
45
|
-
onClick={onClickLocal}
|
|
46
|
-
sx={{
|
|
47
|
-
backgroundColor: pColor.contrastText,
|
|
48
|
-
border: `1px solid ${pColor.light}`
|
|
49
|
-
}}
|
|
50
|
-
{...rest}
|
|
51
|
-
>
|
|
52
|
-
<ArrowBackIcon />
|
|
53
|
-
</IconButton>
|
|
54
|
-
);
|
|
55
|
-
}
|