@etsoo/materialui 1.2.30 → 1.2.32
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/ComboBoxPro.js +5 -2
- package/lib/PullToRefreshUI.d.ts +2 -2
- package/lib/PullToRefreshUI.js +8 -4
- package/lib/UserAvatarEditor.d.ts +1 -1
- package/lib/UserAvatarEditor.js +18 -15
- package/lib/app/CommonApp.d.ts +3 -3
- package/lib/app/CommonApp.js +10 -10
- package/lib/app/IServiceApp.d.ts +5 -5
- package/lib/app/ReactApp.js +14 -13
- package/lib/app/ServiceApp.d.ts +2 -2
- package/lib/app/ServiceApp.js +2 -4
- package/package.json +7 -7
- package/src/ComboBoxPro.tsx +5 -2
- package/src/PullToRefreshUI.tsx +17 -10
- package/src/UserAvatarEditor.tsx +251 -251
- package/src/app/CommonApp.ts +189 -201
- package/src/app/IServiceApp.ts +37 -37
- package/src/app/ReactApp.ts +14 -14
- package/src/app/ServiceApp.ts +5 -6
package/src/app/CommonApp.ts
CHANGED
|
@@ -1,224 +1,212 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from
|
|
10
|
-
import { CoreConstants, IPageData } from
|
|
11
|
-
import { ReactApp } from
|
|
2
|
+
IActionResult,
|
|
3
|
+
IApiPayload,
|
|
4
|
+
IAppSettings,
|
|
5
|
+
IUser,
|
|
6
|
+
RefreshTokenProps,
|
|
7
|
+
RefreshTokenResult,
|
|
8
|
+
RefreshTokenRQ
|
|
9
|
+
} from "@etsoo/appscript";
|
|
10
|
+
import { CoreConstants, IPageData } from "@etsoo/react";
|
|
11
|
+
import { ReactApp } from "./ReactApp";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Common independent application
|
|
15
15
|
* 通用独立程序
|
|
16
16
|
*/
|
|
17
17
|
export abstract class CommonApp<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
U extends IUser = IUser,
|
|
19
|
+
P extends IPageData = IPageData,
|
|
20
|
+
S extends IAppSettings = IAppSettings
|
|
21
21
|
> extends ReactApp<S, U, P> {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Override persistedFields
|
|
24
|
+
*/
|
|
25
|
+
protected override get persistedFields() {
|
|
26
|
+
return [...super.persistedFields, CoreConstants.FieldUserIdSaved];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Init call update fields in local storage
|
|
31
|
+
* @returns Fields
|
|
32
|
+
*/
|
|
33
|
+
protected override initCallEncryptedUpdateFields(): string[] {
|
|
34
|
+
const fields = super.initCallEncryptedUpdateFields();
|
|
35
|
+
fields.push(CoreConstants.FieldUserIdSaved);
|
|
36
|
+
return fields;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Do user login
|
|
41
|
+
* @param data User data
|
|
42
|
+
* @param refreshToken Refresh token
|
|
43
|
+
* @param keep Keep login
|
|
44
|
+
* @returns Success data
|
|
45
|
+
*/
|
|
46
|
+
protected doUserLogin(
|
|
47
|
+
data: U,
|
|
48
|
+
refreshToken: string,
|
|
49
|
+
keep: boolean
|
|
50
|
+
): string | undefined {
|
|
51
|
+
this.userLogin(data, refreshToken, keep);
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Refresh token
|
|
57
|
+
* @param props Props
|
|
58
|
+
*/
|
|
59
|
+
override async refreshToken<D extends object = RefreshTokenRQ>(
|
|
60
|
+
props?: RefreshTokenProps<D>
|
|
61
|
+
) {
|
|
62
|
+
// Destruct
|
|
63
|
+
const {
|
|
64
|
+
callback,
|
|
65
|
+
data,
|
|
66
|
+
relogin = false,
|
|
67
|
+
showLoading = false
|
|
68
|
+
} = props ?? {};
|
|
69
|
+
|
|
70
|
+
// Token
|
|
71
|
+
const token = this.getCacheToken();
|
|
72
|
+
if (token == null || token === "") {
|
|
73
|
+
if (callback) callback(false);
|
|
74
|
+
return false;
|
|
27
75
|
}
|
|
28
76
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// Success callback
|
|
101
|
-
const success = (
|
|
102
|
-
result: LoginResult,
|
|
103
|
-
failCallback?: (
|
|
104
|
-
result: RefreshTokenResult,
|
|
105
|
-
serviceToken?: string
|
|
106
|
-
) => void
|
|
107
|
-
) => {
|
|
108
|
-
// Token
|
|
109
|
-
const refreshToken = this.getResponseToken(payload.response);
|
|
110
|
-
if (refreshToken == null || result.data == null) {
|
|
111
|
-
if (failCallback) failCallback(this.get('noData')!);
|
|
112
|
-
return false;
|
|
77
|
+
// Reqest data
|
|
78
|
+
const rq: RefreshTokenRQ = {
|
|
79
|
+
deviceId: this.deviceId,
|
|
80
|
+
timezone: this.getTimeZone(),
|
|
81
|
+
...data
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Login result type
|
|
85
|
+
type LoginResult = IActionResult<U>;
|
|
86
|
+
|
|
87
|
+
// Payload
|
|
88
|
+
const payload: IApiPayload<LoginResult, any> = {
|
|
89
|
+
// No loading bar needed to avoid screen flicks
|
|
90
|
+
showLoading,
|
|
91
|
+
config: { headers: { [CoreConstants.TokenHeaderRefresh]: token } },
|
|
92
|
+
onError: (error) => {
|
|
93
|
+
if (callback) callback(error);
|
|
94
|
+
|
|
95
|
+
// Prevent further processing
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// Success callback
|
|
101
|
+
const success = (
|
|
102
|
+
result: LoginResult,
|
|
103
|
+
failCallback?: (result: RefreshTokenResult, serviceToken?: string) => void
|
|
104
|
+
) => {
|
|
105
|
+
// Token
|
|
106
|
+
const refreshToken = this.getResponseToken(payload.response);
|
|
107
|
+
if (refreshToken == null || result.data == null) {
|
|
108
|
+
if (failCallback) failCallback(this.get("noData")!);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Keep
|
|
113
|
+
const keep = this.storage.getData(CoreConstants.FieldLoginKeep, false);
|
|
114
|
+
|
|
115
|
+
// User login
|
|
116
|
+
var successData = this.doUserLogin(result.data, refreshToken, keep);
|
|
117
|
+
|
|
118
|
+
// Callback
|
|
119
|
+
if (failCallback) failCallback(true, successData);
|
|
120
|
+
|
|
121
|
+
return true;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// Call API
|
|
125
|
+
const result = await this.api.put<LoginResult>(
|
|
126
|
+
"Auth/RefreshToken",
|
|
127
|
+
rq,
|
|
128
|
+
payload
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
if (result == null) return false;
|
|
132
|
+
|
|
133
|
+
if (!result.ok) {
|
|
134
|
+
if (result.type === "TokenExpired" && relogin) {
|
|
135
|
+
// Try login
|
|
136
|
+
// Dialog to receive password
|
|
137
|
+
var labels = this.getLabels("reloginTip", "login");
|
|
138
|
+
this.notifier.prompt(
|
|
139
|
+
labels.reloginTip,
|
|
140
|
+
async (pwd) => {
|
|
141
|
+
if (pwd == null) {
|
|
142
|
+
this.toLoginPage();
|
|
143
|
+
return;
|
|
113
144
|
}
|
|
114
145
|
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
CoreConstants.FieldLoginKeep,
|
|
118
|
-
false
|
|
119
|
-
);
|
|
146
|
+
// Set password for the action
|
|
147
|
+
rq.pwd = await this.encrypt(await this.hash(pwd));
|
|
120
148
|
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
149
|
+
// Submit again
|
|
150
|
+
const result = await this.api.put<LoginResult>(
|
|
151
|
+
"Auth/RefreshToken",
|
|
152
|
+
rq,
|
|
153
|
+
payload
|
|
154
|
+
);
|
|
126
155
|
|
|
127
|
-
return
|
|
128
|
-
};
|
|
156
|
+
if (result == null) return;
|
|
129
157
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
158
|
+
if (result.ok) {
|
|
159
|
+
success(result, (loginResult: RefreshTokenResult) => {
|
|
160
|
+
if (loginResult === true) {
|
|
161
|
+
if (callback) callback(true);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
136
164
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
// Try login
|
|
142
|
-
// Dialog to receive password
|
|
143
|
-
var labels = this.getLabels('reloginTip', 'login');
|
|
144
|
-
this.notifier.prompt(
|
|
145
|
-
labels.reloginTip,
|
|
146
|
-
async (pwd) => {
|
|
147
|
-
if (pwd == null) {
|
|
148
|
-
this.toLoginPage();
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Set password for the action
|
|
153
|
-
rq.pwd = this.encrypt(this.hash(pwd));
|
|
154
|
-
|
|
155
|
-
// Submit again
|
|
156
|
-
const result = await this.api.put<LoginResult>(
|
|
157
|
-
'Auth/RefreshToken',
|
|
158
|
-
rq,
|
|
159
|
-
payload
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
if (result == null) return;
|
|
163
|
-
|
|
164
|
-
if (result.ok) {
|
|
165
|
-
success(
|
|
166
|
-
result,
|
|
167
|
-
(loginResult: RefreshTokenResult) => {
|
|
168
|
-
if (loginResult === true) {
|
|
169
|
-
if (callback) callback(true);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const message =
|
|
174
|
-
this.formatRefreshTokenResult(
|
|
175
|
-
loginResult
|
|
176
|
-
);
|
|
177
|
-
if (message) this.notifier.alert(message);
|
|
178
|
-
}
|
|
179
|
-
);
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Popup message
|
|
184
|
-
this.alertResult(result);
|
|
185
|
-
return false;
|
|
186
|
-
},
|
|
187
|
-
labels.login,
|
|
188
|
-
{ type: 'password' }
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
// Fake truth to avoid reloading
|
|
192
|
-
return true;
|
|
165
|
+
const message = this.formatRefreshTokenResult(loginResult);
|
|
166
|
+
if (message) this.notifier.alert(message);
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
193
169
|
}
|
|
194
170
|
|
|
195
|
-
|
|
171
|
+
// Popup message
|
|
172
|
+
this.alertResult(result);
|
|
196
173
|
return false;
|
|
197
|
-
|
|
174
|
+
},
|
|
175
|
+
labels.login,
|
|
176
|
+
{ type: "password" }
|
|
177
|
+
);
|
|
198
178
|
|
|
199
|
-
|
|
200
|
-
|
|
179
|
+
// Fake truth to avoid reloading
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
201
182
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
* @param data Additional data
|
|
205
|
-
* @param showLoading Show loading bar or not
|
|
206
|
-
* @returns Result
|
|
207
|
-
*/
|
|
208
|
-
override async tryLogin<D extends object = RefreshTokenRQ>(
|
|
209
|
-
data?: D,
|
|
210
|
-
showLoading?: boolean
|
|
211
|
-
) {
|
|
212
|
-
// Reset user state
|
|
213
|
-
const result = await super.tryLogin(data);
|
|
214
|
-
if (!result) return false;
|
|
215
|
-
|
|
216
|
-
// Refresh token
|
|
217
|
-
return await this.refreshToken({
|
|
218
|
-
callback: (result) => this.doRefreshTokenResult(result),
|
|
219
|
-
data,
|
|
220
|
-
showLoading,
|
|
221
|
-
relogin: true
|
|
222
|
-
});
|
|
183
|
+
if (callback) callback(result);
|
|
184
|
+
return false;
|
|
223
185
|
}
|
|
186
|
+
|
|
187
|
+
return success(result, callback);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Try login
|
|
192
|
+
* @param data Additional data
|
|
193
|
+
* @param showLoading Show loading bar or not
|
|
194
|
+
* @returns Result
|
|
195
|
+
*/
|
|
196
|
+
override async tryLogin<D extends object = RefreshTokenRQ>(
|
|
197
|
+
data?: D,
|
|
198
|
+
showLoading?: boolean
|
|
199
|
+
) {
|
|
200
|
+
// Reset user state
|
|
201
|
+
const result = await super.tryLogin(data);
|
|
202
|
+
if (!result) return false;
|
|
203
|
+
|
|
204
|
+
// Refresh token
|
|
205
|
+
return await this.refreshToken({
|
|
206
|
+
callback: (result) => this.doRefreshTokenResult(result),
|
|
207
|
+
data,
|
|
208
|
+
showLoading,
|
|
209
|
+
relogin: true
|
|
210
|
+
});
|
|
211
|
+
}
|
|
224
212
|
}
|
package/src/app/IServiceApp.ts
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import { IApi } from
|
|
2
|
-
import { IServiceUser } from
|
|
3
|
-
import { ReactAppType } from
|
|
1
|
+
import { IApi } from "@etsoo/appscript";
|
|
2
|
+
import { IServiceUser } from "./IServiceUser";
|
|
3
|
+
import { ReactAppType } from "./ReactApp";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Service application interface
|
|
7
7
|
*/
|
|
8
8
|
export interface IServiceApp extends ReactAppType {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Service API
|
|
11
|
+
*/
|
|
12
|
+
readonly serviceApi: IApi;
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Service user
|
|
16
|
+
*/
|
|
17
|
+
readonly serviceUser?: IServiceUser;
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Load SmartERP core
|
|
21
|
+
*/
|
|
22
|
+
loadSmartERP(): void;
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Service decrypt message
|
|
26
|
+
* @param messageEncrypted Encrypted message
|
|
27
|
+
* @param passphrase Secret passphrase
|
|
28
|
+
* @returns Pure text
|
|
29
|
+
*/
|
|
30
|
+
serviceDecrypt(
|
|
31
|
+
messageEncrypted: string,
|
|
32
|
+
passphrase?: string
|
|
33
|
+
): Promise<string | undefined>;
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Service encrypt message
|
|
37
|
+
* @param message Message
|
|
38
|
+
* @param passphrase Secret passphrase
|
|
39
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
40
|
+
* @returns Result
|
|
41
|
+
*/
|
|
42
|
+
serviceEncrypt(
|
|
43
|
+
message: string,
|
|
44
|
+
passphrase?: string,
|
|
45
|
+
iterations?: number
|
|
46
|
+
): Promise<string | undefined>;
|
|
47
47
|
}
|
package/src/app/ReactApp.ts
CHANGED
|
@@ -312,20 +312,20 @@ export class ReactApp<
|
|
|
312
312
|
*/
|
|
313
313
|
override changeCulture(culture: DataTypes.CultureDefinition) {
|
|
314
314
|
// Super call to update cultrue
|
|
315
|
-
super.changeCulture(culture)
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
315
|
+
super.changeCulture(culture, (resources) => {
|
|
316
|
+
// Update component labels
|
|
317
|
+
Labels.setLabels(resources, {
|
|
318
|
+
notificationMU: {
|
|
319
|
+
alertTitle: "warning",
|
|
320
|
+
alertOK: "ok",
|
|
321
|
+
confirmTitle: "confirm",
|
|
322
|
+
confirmYes: "ok",
|
|
323
|
+
confirmNo: "cancel",
|
|
324
|
+
promptTitle: "prompt",
|
|
325
|
+
promptCancel: "cancel",
|
|
326
|
+
promptOK: "ok"
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
329
|
});
|
|
330
330
|
|
|
331
331
|
// Document title
|
package/src/app/ServiceApp.ts
CHANGED
|
@@ -226,7 +226,7 @@ export class ServiceApp<
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
// Set password for the action
|
|
229
|
-
rq.pwd = this.encrypt(this.hash(pwd));
|
|
229
|
+
rq.pwd = await this.encrypt(await this.hash(pwd));
|
|
230
230
|
|
|
231
231
|
// Submit again
|
|
232
232
|
const result = await this.api.put<LoginResult>(
|
|
@@ -325,11 +325,10 @@ export class ServiceApp<
|
|
|
325
325
|
*/
|
|
326
326
|
userLoginEx(user: ISmartERPUser, refreshToken: string, serviceUser: U) {
|
|
327
327
|
// Service user login
|
|
328
|
-
this.
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
) ?? "";
|
|
328
|
+
this.decrypt(
|
|
329
|
+
serviceUser.servicePassphrase,
|
|
330
|
+
this.settings.serviceId.toString()
|
|
331
|
+
).then((result) => (this.servicePassphrase = result ?? ""));
|
|
333
332
|
|
|
334
333
|
// Service user
|
|
335
334
|
this.serviceUser = serviceUser;
|