nfx-ui 0.34.0 → 0.36.0
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.en.md +1 -1
- package/README.md +1 -1
- package/dist/events/system.d.ts +9 -0
- package/dist/events/system.d.ts.map +1 -1
- package/dist/events/system.js +9 -1
- package/dist/events/system.js.map +1 -1
- package/dist/hooks/auth.d.ts +33 -30
- package/dist/hooks/auth.d.ts.map +1 -1
- package/dist/hooks/auth.js +234 -227
- package/dist/hooks/auth.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +9 -8
- package/dist/hooks/toast.d.ts +12 -0
- package/dist/hooks/toast.d.ts.map +1 -0
- package/dist/hooks/toast.js +13 -0
- package/dist/hooks/toast.js.map +1 -0
- package/dist/languages/hooks/useLanguageLabel.d.ts.map +1 -1
- package/dist/languages/hooks/useLanguageLabel.js +11 -10
- package/dist/languages/hooks/useLanguageLabel.js.map +1 -1
- package/dist/languages/index.d.ts +0 -1
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js +9 -10
- package/dist/languages/languages/i18n.d.ts.map +1 -1
- package/dist/languages/languages/i18n.js +30 -41
- package/dist/languages/languages/i18n.js.map +1 -1
- package/dist/schemas/loginSchema.d.ts +3 -3
- package/dist/schemas/loginSchema.d.ts.map +1 -1
- package/dist/schemas/loginSchema.js +22 -23
- package/dist/schemas/loginSchema.js.map +1 -1
- package/dist/schemas/profileEditSchema.d.ts +1 -1
- package/dist/schemas/profileEditSchema.d.ts.map +1 -1
- package/dist/schemas/profileEditSchema.js +18 -19
- package/dist/schemas/profileEditSchema.js.map +1 -1
- package/dist/schemas/signupSchema.d.ts +2 -2
- package/dist/schemas/signupSchema.d.ts.map +1 -1
- package/dist/schemas/signupSchema.js +16 -17
- package/dist/schemas/signupSchema.js.map +1 -1
- package/package.json +1 -1
- package/src/events/system.ts +16 -0
- package/src/hooks/auth.ts +100 -109
- package/src/hooks/index.ts +1 -0
- package/src/hooks/toast.ts +23 -0
- package/src/languages/hooks/useLanguageLabel.ts +2 -3
- package/src/languages/index.ts +0 -1
- package/src/languages/languages/i18n.ts +3 -17
- package/src/schemas/loginSchema.ts +3 -6
- package/src/schemas/profileEditSchema.ts +1 -3
- package/src/schemas/signupSchema.ts +2 -4
- package/dist/languages/resources/en/language.js +0 -52
- package/dist/languages/resources/en/language.js.map +0 -1
- package/dist/languages/resources/en/language.json.d.ts +0 -49
- package/dist/languages/resources/en/layout.js +0 -9
- package/dist/languages/resources/en/layout.js.map +0 -1
- package/dist/languages/resources/en/layout.json.d.ts +0 -9
- package/dist/languages/resources/en/preference.js +0 -50
- package/dist/languages/resources/en/preference.js.map +0 -1
- package/dist/languages/resources/en/preference.json.d.ts +0 -51
- package/dist/languages/resources/en/theme.js +0 -19
- package/dist/languages/resources/en/theme.js.map +0 -1
- package/dist/languages/resources/en/theme.json.d.ts +0 -17
- package/dist/languages/resources/fr/language.js +0 -52
- package/dist/languages/resources/fr/language.js.map +0 -1
- package/dist/languages/resources/fr/language.json.d.ts +0 -49
- package/dist/languages/resources/fr/layout.js +0 -9
- package/dist/languages/resources/fr/layout.js.map +0 -1
- package/dist/languages/resources/fr/layout.json.d.ts +0 -9
- package/dist/languages/resources/fr/preference.js +0 -50
- package/dist/languages/resources/fr/preference.js.map +0 -1
- package/dist/languages/resources/fr/preference.json.d.ts +0 -51
- package/dist/languages/resources/fr/theme.js +0 -19
- package/dist/languages/resources/fr/theme.js.map +0 -1
- package/dist/languages/resources/fr/theme.json.d.ts +0 -17
- package/dist/languages/resources/index.d.ts +0 -9
- package/dist/languages/resources/index.d.ts.map +0 -1
- package/dist/languages/resources/index.js +0 -54
- package/dist/languages/resources/index.js.map +0 -1
- package/dist/languages/resources/zh/language.js +0 -52
- package/dist/languages/resources/zh/language.js.map +0 -1
- package/dist/languages/resources/zh/language.json.d.ts +0 -49
- package/dist/languages/resources/zh/layout.js +0 -9
- package/dist/languages/resources/zh/layout.js.map +0 -1
- package/dist/languages/resources/zh/layout.json.d.ts +0 -9
- package/dist/languages/resources/zh/preference.js +0 -50
- package/dist/languages/resources/zh/preference.js.map +0 -1
- package/dist/languages/resources/zh/preference.json.d.ts +0 -51
- package/dist/languages/resources/zh/theme.js +0 -19
- package/dist/languages/resources/zh/theme.js.map +0 -1
- package/dist/languages/resources/zh/theme.json.d.ts +0 -17
- package/src/languages/resources/en/language.json +0 -47
- package/src/languages/resources/en/layout.json +0 -6
- package/src/languages/resources/en/preference.json +0 -49
- package/src/languages/resources/en/theme.json +0 -14
- package/src/languages/resources/fr/language.json +0 -47
- package/src/languages/resources/fr/layout.json +0 -6
- package/src/languages/resources/fr/preference.json +0 -49
- package/src/languages/resources/fr/theme.json +0 -14
- package/src/languages/resources/index.ts +0 -62
- package/src/languages/resources/zh/language.json +0 -47
- package/src/languages/resources/zh/layout.json +0 -6
- package/src/languages/resources/zh/preference.json +0 -49
- package/src/languages/resources/zh/theme.json +0 -14
package/src/hooks/auth.ts
CHANGED
|
@@ -25,11 +25,11 @@ import {
|
|
|
25
25
|
useAuthStore,
|
|
26
26
|
} from "nfx-ui/stores/auth";
|
|
27
27
|
import { ensureDeviceIdStorage } from "nfx-ui/stores/system";
|
|
28
|
-
import { getApiErrorMessage } from "nfx-ui/utils/apiError";
|
|
29
28
|
import { pickProfile } from "nfx-ui/utils/domain/account";
|
|
30
29
|
import { useUnifiedQuery } from "nfx-ui/utils/factory";
|
|
31
30
|
import { safeOr, safeStringable } from "nfx-ui/utils/safe";
|
|
32
|
-
|
|
31
|
+
|
|
32
|
+
import { emitHookError, emitHookSuccess, type HookToastMessages } from "./toast";
|
|
33
33
|
|
|
34
34
|
export function useAuthQueryScope() {
|
|
35
35
|
const aID = useAuthStore((s) => s.currentAccountId);
|
|
@@ -68,21 +68,20 @@ export function useCurrentProfile(): CurrentProfileResult {
|
|
|
68
68
|
} as CurrentProfileResult;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
export const useSendVerificationCode = () => {
|
|
71
|
+
export const useSendVerificationCode = (options?: HookToastMessages) => {
|
|
72
72
|
const auth = useAuthRepository();
|
|
73
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
74
73
|
return useMutation({
|
|
75
74
|
mutationFn: (params: Signup.Request.SendVerificationCode) => auth.SendVerificationCode(params),
|
|
76
75
|
onSuccess: () => {
|
|
77
|
-
|
|
76
|
+
emitHookSuccess(options);
|
|
78
77
|
},
|
|
79
78
|
onError: (error: AxiosError) => {
|
|
80
|
-
|
|
79
|
+
emitHookError(error, options, "[useSendVerificationCode] error");
|
|
81
80
|
},
|
|
82
81
|
});
|
|
83
82
|
};
|
|
84
83
|
|
|
85
|
-
export const useSignupWithEmail = () => {
|
|
84
|
+
export const useSignupWithEmail = (options?: HookToastMessages) => {
|
|
86
85
|
const auth = useAuthRepository();
|
|
87
86
|
return useMutation({
|
|
88
87
|
mutationFn: async ({
|
|
@@ -117,12 +116,12 @@ export const useSignupWithEmail = () => {
|
|
|
117
116
|
}
|
|
118
117
|
},
|
|
119
118
|
onError: (error: AxiosError) => {
|
|
120
|
-
|
|
119
|
+
emitHookError(error, options, "[useSignup] error");
|
|
121
120
|
},
|
|
122
121
|
});
|
|
123
122
|
};
|
|
124
123
|
|
|
125
|
-
export const useLoginWithEmail = () => {
|
|
124
|
+
export const useLoginWithEmail = (options?: HookToastMessages) => {
|
|
126
125
|
const auth = useAuthRepository();
|
|
127
126
|
return useMutation({
|
|
128
127
|
mutationFn: async ({ rememberMe, ...params }: { email: string; password: string; rememberMe: boolean }) =>
|
|
@@ -144,12 +143,12 @@ export const useLoginWithEmail = () => {
|
|
|
144
143
|
if (result.accountId) setCurrentAccountId(result.accountId);
|
|
145
144
|
},
|
|
146
145
|
onError: (error: AxiosError) => {
|
|
147
|
-
|
|
146
|
+
emitHookError(error, options, "[useLogin] error");
|
|
148
147
|
},
|
|
149
148
|
});
|
|
150
149
|
};
|
|
151
150
|
|
|
152
|
-
export const useLoginWithPhone = () => {
|
|
151
|
+
export const useLoginWithPhone = (options?: HookToastMessages) => {
|
|
153
152
|
const auth = useAuthRepository();
|
|
154
153
|
return useMutation({
|
|
155
154
|
mutationFn: async ({ rememberMe, ...params }: { phone: string; password: string; rememberMe: boolean }) =>
|
|
@@ -171,12 +170,14 @@ export const useLoginWithPhone = () => {
|
|
|
171
170
|
if (result.accountId) setCurrentAccountId(result.accountId);
|
|
172
171
|
},
|
|
173
172
|
onError: (error: AxiosError) => {
|
|
174
|
-
|
|
173
|
+
emitHookError(error, options, "[useLoginWithPhone] error");
|
|
175
174
|
},
|
|
176
175
|
});
|
|
177
176
|
};
|
|
178
177
|
|
|
179
|
-
export type SelectProfileOptions = {
|
|
178
|
+
export type SelectProfileOptions = HookToastMessages & {
|
|
179
|
+
/** 已翻译的加载文案。Host-translated loading copy. */
|
|
180
|
+
switchingMsg?: string;
|
|
180
181
|
/** 与 token、档案同一次提交里执行(例如跳到该档案的首页)。Runs in the same commit as the token and profile. */
|
|
181
182
|
onCommit?: () => void;
|
|
182
183
|
};
|
|
@@ -191,68 +192,74 @@ export const useSelectProfile = (options?: SelectProfileOptions) => {
|
|
|
191
192
|
kind,
|
|
192
193
|
deviceId: await ensureDeviceIdStorage(),
|
|
193
194
|
}),
|
|
195
|
+
onMutate: () => {
|
|
196
|
+
if (options?.switchingMsg) systemEventEmitter.showLoading(options.switchingMsg);
|
|
197
|
+
},
|
|
194
198
|
onSuccess: (result, variables) => {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
try {
|
|
200
|
+
if (!result?.accessToken) return;
|
|
201
|
+
// 同一次提交写入新 token 和档案,旧角色的请求在重拉前先停用。
|
|
202
|
+
flushSync(() => {
|
|
203
|
+
setTokens({
|
|
204
|
+
accessToken: result.accessToken,
|
|
205
|
+
refreshToken: safeStringable(result.refreshToken),
|
|
206
|
+
});
|
|
207
|
+
setCurrentProfileKind(variables.kind);
|
|
208
|
+
if (result.profileId) setCurrentProfileId(result.profileId);
|
|
209
|
+
options?.onCommit?.();
|
|
201
210
|
});
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
authEventEmitter.emit(authEvents.LOGIN_SUCCESS, result.accountId);
|
|
211
|
+
authEventEmitter.emit(authEvents.LOGIN_SUCCESS, result.accountId);
|
|
212
|
+
} finally {
|
|
213
|
+
systemEventEmitter.hideLoading();
|
|
214
|
+
}
|
|
207
215
|
},
|
|
208
216
|
onError: (error: AxiosError) => {
|
|
209
|
-
systemEventEmitter.
|
|
217
|
+
systemEventEmitter.hideLoading();
|
|
218
|
+
emitHookError(error, options, "[useSelectProfile] error");
|
|
210
219
|
},
|
|
211
220
|
});
|
|
212
221
|
};
|
|
213
222
|
|
|
214
|
-
export const usePatchProfile = (options?: { silent?: boolean }) => {
|
|
223
|
+
export const usePatchProfile = (options?: { silent?: boolean } & HookToastMessages) => {
|
|
215
224
|
const auth = useAuthRepository();
|
|
216
225
|
const { kind } = useAuthQueryScope();
|
|
217
226
|
const silent = safeOr(options?.silent, false);
|
|
218
|
-
const { t } = useTranslation("pages.User.Profile.Edit");
|
|
219
227
|
return useMutation({
|
|
220
228
|
mutationFn: (body: Profile.Request.PatchProfile) => auth.PatchProfile(kind, body),
|
|
221
229
|
onSuccess: () => {
|
|
222
|
-
if (!silent)
|
|
230
|
+
if (!silent) emitHookSuccess(options);
|
|
223
231
|
const aID = AuthStore.getState().currentAccountId;
|
|
224
232
|
authEventEmitter.invalidateProfiles({ aID, kind });
|
|
225
233
|
},
|
|
226
234
|
onError: (error: AxiosError) => {
|
|
227
|
-
|
|
235
|
+
emitHookError(error, options, "[usePatchProfile] error", silent);
|
|
228
236
|
},
|
|
229
237
|
});
|
|
230
238
|
};
|
|
231
239
|
|
|
232
|
-
export const useUpdateProfileSettings = () => {
|
|
240
|
+
export const useUpdateProfileSettings = (options?: HookToastMessages) => {
|
|
233
241
|
const auth = useAuthRepository();
|
|
234
242
|
const { kind } = useAuthQueryScope();
|
|
235
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
236
243
|
return useMutation({
|
|
237
244
|
mutationFn: (body: Profile.Request.PatchProfileSettings) => auth.PatchProfileSettings(kind, body),
|
|
238
245
|
onSuccess: () => {
|
|
239
246
|
const aID = AuthStore.getState().currentAccountId;
|
|
240
247
|
authEventEmitter.emit(authEvents.UPDATE_ACCOUNT_SUCCESS, aID);
|
|
241
|
-
|
|
248
|
+
emitHookSuccess(options);
|
|
242
249
|
},
|
|
243
250
|
onError: (error: AxiosError) => {
|
|
244
|
-
|
|
251
|
+
emitHookError(error, options, "[useUpdateProfileSettings] error");
|
|
245
252
|
},
|
|
246
253
|
});
|
|
247
254
|
};
|
|
248
255
|
|
|
249
|
-
export const useUpdatePreference = () => {
|
|
256
|
+
export const useUpdatePreference = (options?: HookToastMessages) => {
|
|
250
257
|
const auth = useAuthRepository();
|
|
251
258
|
const { kind } = useAuthQueryScope();
|
|
252
259
|
return useMutation({
|
|
253
260
|
mutationFn: (preference: string) => auth.UpdatePreference(kind, preference),
|
|
254
261
|
onError: (error: AxiosError) => {
|
|
255
|
-
|
|
262
|
+
emitHookError(error, options, "[useUpdatePreference] error");
|
|
256
263
|
},
|
|
257
264
|
});
|
|
258
265
|
};
|
|
@@ -268,7 +275,7 @@ export const useListProfiles = <K extends ProfileKindEnum>(kind: K) => {
|
|
|
268
275
|
);
|
|
269
276
|
};
|
|
270
277
|
|
|
271
|
-
export const useCreateForgerProfile = () => {
|
|
278
|
+
export const useCreateForgerProfile = (options?: HookToastMessages) => {
|
|
272
279
|
const auth = useAuthRepository();
|
|
273
280
|
return useMutation({
|
|
274
281
|
mutationFn: (body: Login.Request.CreateForgerProfile) => auth.CreateForgerProfile(body),
|
|
@@ -277,12 +284,12 @@ export const useCreateForgerProfile = () => {
|
|
|
277
284
|
authEventEmitter.invalidateProfiles({ aID, kind: ProfileKindEnum.COMMUNITY });
|
|
278
285
|
},
|
|
279
286
|
onError: (error: AxiosError) => {
|
|
280
|
-
|
|
287
|
+
emitHookError(error, options, "[useCreateForgerProfile] error");
|
|
281
288
|
},
|
|
282
289
|
});
|
|
283
290
|
};
|
|
284
291
|
|
|
285
|
-
export const useCreateAuthorityProfile = () => {
|
|
292
|
+
export const useCreateAuthorityProfile = (options?: HookToastMessages) => {
|
|
286
293
|
const auth = useAuthRepository();
|
|
287
294
|
return useMutation({
|
|
288
295
|
mutationFn: (body: Login.Request.CreateAuthorityProfile) => auth.CreateAuthorityProfile(body),
|
|
@@ -291,12 +298,12 @@ export const useCreateAuthorityProfile = () => {
|
|
|
291
298
|
authEventEmitter.invalidateProfiles({ aID, kind: ProfileKindEnum.AUTHORITY });
|
|
292
299
|
},
|
|
293
300
|
onError: (error: AxiosError) => {
|
|
294
|
-
|
|
301
|
+
emitHookError(error, options, "[useCreateAuthorityProfile] error");
|
|
295
302
|
},
|
|
296
303
|
});
|
|
297
304
|
};
|
|
298
305
|
|
|
299
|
-
export const useDeleteProfile = () => {
|
|
306
|
+
export const useDeleteProfile = (options?: HookToastMessages) => {
|
|
300
307
|
const auth = useAuthRepository();
|
|
301
308
|
return useMutation({
|
|
302
309
|
mutationFn: ({ kind, profileId }: { kind: ProfileKindEnum; profileId: string }) => auth.DeleteProfile(kind, profileId),
|
|
@@ -305,12 +312,12 @@ export const useDeleteProfile = () => {
|
|
|
305
312
|
authEventEmitter.invalidateProfiles({ aID, kind: variables.kind });
|
|
306
313
|
},
|
|
307
314
|
onError: (error: AxiosError) => {
|
|
308
|
-
|
|
315
|
+
emitHookError(error, options, "[useDeleteProfile] error");
|
|
309
316
|
},
|
|
310
317
|
});
|
|
311
318
|
};
|
|
312
319
|
|
|
313
|
-
export const useConfirmProfileAvatar = () => {
|
|
320
|
+
export const useConfirmProfileAvatar = (options?: HookToastMessages) => {
|
|
314
321
|
const auth = useAuthRepository();
|
|
315
322
|
const { kind } = useAuthQueryScope();
|
|
316
323
|
return useMutation({
|
|
@@ -320,24 +327,23 @@ export const useConfirmProfileAvatar = () => {
|
|
|
320
327
|
authEventEmitter.emit(authEvents.UPDATE_ACCOUNT_SUCCESS, aID);
|
|
321
328
|
},
|
|
322
329
|
onError: (error: AxiosError) => {
|
|
323
|
-
|
|
330
|
+
emitHookError(error, options, "[useConfirmProfileAvatar] error");
|
|
324
331
|
},
|
|
325
332
|
});
|
|
326
333
|
};
|
|
327
334
|
|
|
328
|
-
export const useClearProfileAvatar = () => {
|
|
335
|
+
export const useClearProfileAvatar = (options?: HookToastMessages) => {
|
|
329
336
|
const auth = useAuthRepository();
|
|
330
337
|
const { kind } = useAuthQueryScope();
|
|
331
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
332
338
|
return useMutation({
|
|
333
339
|
mutationFn: () => auth.ClearProfileAvatar(kind),
|
|
334
340
|
onSuccess: () => {
|
|
335
341
|
const aID = AuthStore.getState().currentAccountId;
|
|
336
342
|
authEventEmitter.emit(authEvents.UPDATE_ACCOUNT_SUCCESS, aID);
|
|
337
|
-
|
|
343
|
+
emitHookSuccess(options);
|
|
338
344
|
},
|
|
339
345
|
onError: (error: AxiosError) => {
|
|
340
|
-
|
|
346
|
+
emitHookError(error, options, "[useClearProfileAvatar] error");
|
|
341
347
|
},
|
|
342
348
|
});
|
|
343
349
|
};
|
|
@@ -358,131 +364,123 @@ export const useListPhones = () => {
|
|
|
358
364
|
});
|
|
359
365
|
};
|
|
360
366
|
|
|
361
|
-
export const useCreateEmail = () => {
|
|
367
|
+
export const useCreateEmail = (options?: HookToastMessages) => {
|
|
362
368
|
const auth = useAuthRepository();
|
|
363
369
|
const accountId = AuthStore.getState().currentAccountId;
|
|
364
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
365
370
|
return useMutation({
|
|
366
371
|
mutationFn: (body: Login.Request.CreateEmail) => auth.CreateEmail(body),
|
|
367
372
|
onSuccess: () => {
|
|
368
373
|
authEventEmitter.invalidateEmails(accountId);
|
|
369
|
-
|
|
374
|
+
emitHookSuccess(options);
|
|
370
375
|
},
|
|
371
376
|
onError: (error: AxiosError) => {
|
|
372
|
-
|
|
377
|
+
emitHookError(error, options, "[useCreateEmail] error");
|
|
373
378
|
},
|
|
374
379
|
});
|
|
375
380
|
};
|
|
376
381
|
|
|
377
|
-
export const useSendEmailVerificationCode = () => {
|
|
382
|
+
export const useSendEmailVerificationCode = (options?: HookToastMessages) => {
|
|
378
383
|
const auth = useAuthRepository();
|
|
379
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
380
384
|
return useMutation({
|
|
381
385
|
mutationFn: ({ emailId, lang }: { emailId: string; lang?: LanguageEnum }) => auth.SendEmailVerificationCode(emailId, { lang }),
|
|
382
386
|
onSuccess: () => {
|
|
383
|
-
|
|
387
|
+
emitHookSuccess(options);
|
|
384
388
|
},
|
|
385
389
|
onError: (error: AxiosError) => {
|
|
386
|
-
|
|
390
|
+
emitHookError(error, options, "[useSendEmailVerificationCode] error");
|
|
387
391
|
},
|
|
388
392
|
});
|
|
389
393
|
};
|
|
390
394
|
|
|
391
|
-
export const useVerifyEmail = () => {
|
|
395
|
+
export const useVerifyEmail = (options?: HookToastMessages) => {
|
|
392
396
|
const auth = useAuthRepository();
|
|
393
397
|
const accountId = AuthStore.getState().currentAccountId;
|
|
394
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
395
398
|
return useMutation({
|
|
396
399
|
mutationFn: ({ emailId, verificationCode }: { emailId: string; verificationCode: string }) =>
|
|
397
400
|
auth.VerifyEmail(emailId, { verificationCode }),
|
|
398
401
|
onSuccess: () => {
|
|
399
402
|
authEventEmitter.invalidateEmails(accountId);
|
|
400
|
-
|
|
403
|
+
emitHookSuccess(options);
|
|
401
404
|
},
|
|
402
405
|
onError: (error: AxiosError) => {
|
|
403
|
-
|
|
406
|
+
emitHookError(error, options, "[useVerifyEmail] error");
|
|
404
407
|
},
|
|
405
408
|
});
|
|
406
409
|
};
|
|
407
410
|
|
|
408
|
-
export const useUpdateEmail = () => {
|
|
411
|
+
export const useUpdateEmail = (options?: HookToastMessages) => {
|
|
409
412
|
const auth = useAuthRepository();
|
|
410
413
|
const accountId = AuthStore.getState().currentAccountId;
|
|
411
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
412
414
|
return useMutation({
|
|
413
415
|
mutationFn: ({ emailId, email }: { emailId: string; email: string }) => auth.UpdateEmail(emailId, { email }),
|
|
414
416
|
onSuccess: () => {
|
|
415
417
|
authEventEmitter.invalidateEmails(accountId);
|
|
416
|
-
|
|
418
|
+
emitHookSuccess(options);
|
|
417
419
|
},
|
|
418
420
|
onError: (error: AxiosError) => {
|
|
419
|
-
|
|
421
|
+
emitHookError(error, options, "[useUpdateEmail] error");
|
|
420
422
|
},
|
|
421
423
|
});
|
|
422
424
|
};
|
|
423
425
|
|
|
424
|
-
export const useSetPrimaryEmail = () => {
|
|
426
|
+
export const useSetPrimaryEmail = (options?: HookToastMessages) => {
|
|
425
427
|
const auth = useAuthRepository();
|
|
426
428
|
const accountId = AuthStore.getState().currentAccountId;
|
|
427
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
428
429
|
return useMutation({
|
|
429
430
|
mutationFn: (emailId: string) => auth.SetPrimaryEmail(emailId),
|
|
430
431
|
onSuccess: () => {
|
|
431
432
|
authEventEmitter.invalidateEmails(accountId);
|
|
432
433
|
authEventEmitter.emit(authEvents.UPDATE_ACCOUNT_SUCCESS, accountId);
|
|
433
|
-
|
|
434
|
+
emitHookSuccess(options);
|
|
434
435
|
},
|
|
435
436
|
onError: (error: AxiosError) => {
|
|
436
|
-
|
|
437
|
+
emitHookError(error, options, "[useSetPrimaryEmail] error");
|
|
437
438
|
},
|
|
438
439
|
});
|
|
439
440
|
};
|
|
440
441
|
|
|
441
|
-
export const useDeleteEmail = () => {
|
|
442
|
+
export const useDeleteEmail = (options?: HookToastMessages) => {
|
|
442
443
|
const auth = useAuthRepository();
|
|
443
444
|
const accountId = AuthStore.getState().currentAccountId;
|
|
444
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
445
445
|
return useMutation({
|
|
446
446
|
mutationFn: (emailId: string) => auth.DeleteEmail(emailId),
|
|
447
447
|
onSuccess: () => {
|
|
448
448
|
authEventEmitter.invalidateEmails(accountId);
|
|
449
|
-
|
|
449
|
+
emitHookSuccess(options);
|
|
450
450
|
},
|
|
451
451
|
onError: (error: AxiosError) => {
|
|
452
|
-
|
|
452
|
+
emitHookError(error, options, "[useDeleteEmail] error");
|
|
453
453
|
},
|
|
454
454
|
});
|
|
455
455
|
};
|
|
456
456
|
|
|
457
|
-
export const useSendChangePasswordVerificationCode = () => {
|
|
457
|
+
export const useSendChangePasswordVerificationCode = (options?: HookToastMessages) => {
|
|
458
458
|
const auth = useAuthRepository();
|
|
459
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
460
459
|
return useMutation({
|
|
461
460
|
mutationFn: (body: Login.Request.SendChangePasswordVerificationCode = {}) => auth.SendChangePasswordVerificationCode(body),
|
|
462
461
|
onSuccess: () => {
|
|
463
|
-
|
|
462
|
+
emitHookSuccess(options);
|
|
464
463
|
},
|
|
465
464
|
onError: (error: AxiosError) => {
|
|
466
|
-
|
|
465
|
+
emitHookError(error, options, "[useSendChangePasswordVerificationCode] error");
|
|
467
466
|
},
|
|
468
467
|
});
|
|
469
468
|
};
|
|
470
469
|
|
|
471
|
-
export const useChangePassword = () => {
|
|
470
|
+
export const useChangePassword = (options?: HookToastMessages) => {
|
|
472
471
|
const auth = useAuthRepository();
|
|
473
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
474
472
|
return useMutation({
|
|
475
473
|
mutationFn: (body: Login.Request.ChangePassword) => auth.ChangePassword(body),
|
|
476
474
|
onSuccess: () => {
|
|
477
|
-
|
|
475
|
+
emitHookSuccess(options);
|
|
478
476
|
},
|
|
479
477
|
onError: (error: AxiosError) => {
|
|
480
|
-
|
|
478
|
+
emitHookError(error, options, "[useChangePassword] error");
|
|
481
479
|
},
|
|
482
480
|
});
|
|
483
481
|
};
|
|
484
482
|
|
|
485
|
-
export const useConfirmProfileBackgrounds = () => {
|
|
483
|
+
export const useConfirmProfileBackgrounds = (options?: HookToastMessages) => {
|
|
486
484
|
const auth = useAuthRepository();
|
|
487
485
|
const { kind } = useAuthQueryScope();
|
|
488
486
|
return useMutation({
|
|
@@ -492,103 +490,97 @@ export const useConfirmProfileBackgrounds = () => {
|
|
|
492
490
|
authEventEmitter.emit(authEvents.UPDATE_ACCOUNT_SUCCESS, aID);
|
|
493
491
|
},
|
|
494
492
|
onError: (error: AxiosError) => {
|
|
495
|
-
|
|
493
|
+
emitHookError(error, options, "[useConfirmProfileBackgrounds] error");
|
|
496
494
|
},
|
|
497
495
|
});
|
|
498
496
|
};
|
|
499
497
|
|
|
500
|
-
export const useCreatePhone = () => {
|
|
498
|
+
export const useCreatePhone = (options?: HookToastMessages) => {
|
|
501
499
|
const auth = useAuthRepository();
|
|
502
500
|
const accountId = AuthStore.getState().currentAccountId;
|
|
503
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
504
501
|
return useMutation({
|
|
505
502
|
mutationFn: (body: Login.Request.CreatePhone) => auth.CreatePhone(body),
|
|
506
503
|
onSuccess: () => {
|
|
507
504
|
authEventEmitter.invalidatePhones(accountId);
|
|
508
|
-
|
|
505
|
+
emitHookSuccess(options);
|
|
509
506
|
},
|
|
510
507
|
onError: (error: AxiosError) => {
|
|
511
|
-
|
|
508
|
+
emitHookError(error, options, "[useCreatePhone] error");
|
|
512
509
|
},
|
|
513
510
|
});
|
|
514
511
|
};
|
|
515
512
|
|
|
516
|
-
export const useSendPhoneVerificationCode = () => {
|
|
513
|
+
export const useSendPhoneVerificationCode = (options?: HookToastMessages) => {
|
|
517
514
|
const auth = useAuthRepository();
|
|
518
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
519
515
|
return useMutation({
|
|
520
516
|
mutationFn: (phoneId: string) => auth.SendPhoneVerificationCode(phoneId),
|
|
521
517
|
onSuccess: () => {
|
|
522
|
-
|
|
518
|
+
emitHookSuccess(options);
|
|
523
519
|
},
|
|
524
520
|
onError: (error: AxiosError) => {
|
|
525
|
-
|
|
521
|
+
emitHookError(error, options, "[useSendPhoneVerificationCode] error");
|
|
526
522
|
},
|
|
527
523
|
});
|
|
528
524
|
};
|
|
529
525
|
|
|
530
|
-
export const useVerifyPhone = () => {
|
|
526
|
+
export const useVerifyPhone = (options?: HookToastMessages) => {
|
|
531
527
|
const auth = useAuthRepository();
|
|
532
528
|
const accountId = AuthStore.getState().currentAccountId;
|
|
533
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
534
529
|
return useMutation({
|
|
535
530
|
mutationFn: ({ phoneId, verificationCode }: { phoneId: string; verificationCode: string }) =>
|
|
536
531
|
auth.VerifyPhone(phoneId, { verificationCode }),
|
|
537
532
|
onSuccess: () => {
|
|
538
533
|
authEventEmitter.invalidatePhones(accountId);
|
|
539
|
-
|
|
534
|
+
emitHookSuccess(options);
|
|
540
535
|
},
|
|
541
536
|
onError: (error: AxiosError) => {
|
|
542
|
-
|
|
537
|
+
emitHookError(error, options, "[useVerifyPhone] error");
|
|
543
538
|
},
|
|
544
539
|
});
|
|
545
540
|
};
|
|
546
541
|
|
|
547
|
-
export const useUpdatePhone = () => {
|
|
542
|
+
export const useUpdatePhone = (options?: HookToastMessages) => {
|
|
548
543
|
const auth = useAuthRepository();
|
|
549
544
|
const accountId = AuthStore.getState().currentAccountId;
|
|
550
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
551
545
|
return useMutation({
|
|
552
546
|
mutationFn: ({ phoneId, phone }: { phoneId: string; phone: string }) => auth.UpdatePhone(phoneId, { phone }),
|
|
553
547
|
onSuccess: () => {
|
|
554
548
|
authEventEmitter.invalidatePhones(accountId);
|
|
555
|
-
|
|
549
|
+
emitHookSuccess(options);
|
|
556
550
|
},
|
|
557
551
|
onError: (error: AxiosError) => {
|
|
558
|
-
|
|
552
|
+
emitHookError(error, options, "[useUpdatePhone] error");
|
|
559
553
|
},
|
|
560
554
|
});
|
|
561
555
|
};
|
|
562
556
|
|
|
563
|
-
export const useSetPrimaryPhone = () => {
|
|
557
|
+
export const useSetPrimaryPhone = (options?: HookToastMessages) => {
|
|
564
558
|
const auth = useAuthRepository();
|
|
565
559
|
const accountId = AuthStore.getState().currentAccountId;
|
|
566
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
567
560
|
return useMutation({
|
|
568
561
|
mutationFn: (phoneId: string) => auth.SetPrimaryPhone(phoneId),
|
|
569
562
|
onSuccess: () => {
|
|
570
563
|
authEventEmitter.invalidatePhones(accountId);
|
|
571
564
|
authEventEmitter.emit(authEvents.UPDATE_ACCOUNT_SUCCESS, accountId);
|
|
572
|
-
|
|
565
|
+
emitHookSuccess(options);
|
|
573
566
|
},
|
|
574
567
|
onError: (error: AxiosError) => {
|
|
575
|
-
|
|
568
|
+
emitHookError(error, options, "[useSetPrimaryPhone] error");
|
|
576
569
|
},
|
|
577
570
|
});
|
|
578
571
|
};
|
|
579
572
|
|
|
580
|
-
export const useDeletePhone = () => {
|
|
573
|
+
export const useDeletePhone = (options?: HookToastMessages) => {
|
|
581
574
|
const auth = useAuthRepository();
|
|
582
575
|
const accountId = AuthStore.getState().currentAccountId;
|
|
583
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
584
576
|
return useMutation({
|
|
585
577
|
mutationFn: (phoneId: string) => auth.DeletePhone(phoneId),
|
|
586
578
|
onSuccess: () => {
|
|
587
579
|
authEventEmitter.invalidatePhones(accountId);
|
|
588
|
-
|
|
580
|
+
emitHookSuccess(options);
|
|
589
581
|
},
|
|
590
582
|
onError: (error: AxiosError) => {
|
|
591
|
-
|
|
583
|
+
emitHookError(error, options, "[useDeletePhone] error");
|
|
592
584
|
},
|
|
593
585
|
});
|
|
594
586
|
};
|
|
@@ -652,19 +644,18 @@ export const useListOwnerAuthorityProfiles = (query = "") => {
|
|
|
652
644
|
);
|
|
653
645
|
};
|
|
654
646
|
|
|
655
|
-
export const useUpdateAuthorityProfileRoles = () => {
|
|
647
|
+
export const useUpdateAuthorityProfileRoles = (options?: HookToastMessages) => {
|
|
656
648
|
const auth = useAuthRepository();
|
|
657
649
|
const accountId = AuthStore.getState().currentAccountId;
|
|
658
|
-
const { t } = useTranslation("hooks", { keyPrefix: "account" });
|
|
659
650
|
return useMutation({
|
|
660
651
|
mutationFn: ({ profileId, authorityRoles }: { profileId: string; authorityRoles: Profile.Request.UpdateAuthorityProfileRoles["authorityRoles"] }) =>
|
|
661
652
|
auth.UpdateAuthorityProfileRoles(profileId, { authorityRoles }),
|
|
662
653
|
onSuccess: () => {
|
|
663
654
|
authEventEmitter.invalidateOwner(accountId);
|
|
664
|
-
|
|
655
|
+
emitHookSuccess(options);
|
|
665
656
|
},
|
|
666
657
|
onError: (error: AxiosError) => {
|
|
667
|
-
|
|
658
|
+
emitHookError(error, options, "[useUpdateAuthorityProfileRoles] error");
|
|
668
659
|
},
|
|
669
660
|
});
|
|
670
661
|
};
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AxiosError } from "axios";
|
|
2
|
+
|
|
3
|
+
import { systemEventEmitter } from "nfx-ui/events/system";
|
|
4
|
+
import { getApiErrorMessage } from "nfx-ui/utils/apiError";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Host resolves copy with its own `t`, then passes ready-to-show strings.
|
|
8
|
+
* Package mutation hooks never call `useTranslation`.
|
|
9
|
+
*/
|
|
10
|
+
export type HookToastMessages = {
|
|
11
|
+
successMsg?: string;
|
|
12
|
+
failMsg?: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function emitHookSuccess(toasts?: HookToastMessages, silent = false) {
|
|
16
|
+
if (silent || !toasts?.successMsg) return;
|
|
17
|
+
systemEventEmitter.showSuccess(toasts.successMsg);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function emitHookError(error: AxiosError, toasts?: HookToastMessages, fallback = "Request failed", silent = false) {
|
|
21
|
+
if (silent) return;
|
|
22
|
+
systemEventEmitter.showError(getApiErrorMessage(error, toasts?.failMsg ?? fallback));
|
|
23
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import i18n from "i18next";
|
|
2
|
-
import { useTranslation } from "react-i18next";
|
|
3
2
|
|
|
4
3
|
import { BaseEnum } from "nfx-ui/enums/theme";
|
|
5
4
|
import { LanguageEnum } from "../types";
|
|
@@ -16,9 +15,9 @@ function getLanguageI18nKey(lang: LanguageEnum): string {
|
|
|
16
15
|
export function useLanguageLabel(): {
|
|
17
16
|
getLanguageDisplayName: (lang: LanguageEnum) => string;
|
|
18
17
|
} {
|
|
19
|
-
const { t } = useTranslation("language");
|
|
20
18
|
const getLanguageDisplayName = (lang: LanguageEnum): string =>
|
|
21
|
-
t(getLanguageI18nKey(lang), {
|
|
19
|
+
i18n.t(getLanguageI18nKey(lang), {
|
|
20
|
+
ns: "language",
|
|
22
21
|
defaultValue: lang,
|
|
23
22
|
});
|
|
24
23
|
|
package/src/languages/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* i18n
|
|
3
|
-
*
|
|
2
|
+
* Shared i18n init — host injects builtin bundles via `getBuiltinBundles`.
|
|
3
|
+
* Product JSON stays in each console's language folder.
|
|
4
4
|
*/
|
|
5
5
|
import type { CreateI18nResourcesResult, ExtraBundleItem, InitI18nOptions } from "../types";
|
|
6
6
|
|
|
@@ -12,8 +12,6 @@ import { LanguageEnum, LANGUAGE_VALUES } from "nfx-ui/enums/language";
|
|
|
12
12
|
import { PreferenceStore, setPreference } from "nfx-ui/stores/preference";
|
|
13
13
|
import { safeEnum, safeStringable } from "nfx-ui/utils/safe";
|
|
14
14
|
|
|
15
|
-
import { getDefaultNfxBundles } from "../resources";
|
|
16
|
-
|
|
17
15
|
export function toSupportedLanguage(lng: string, fallbackLng: LanguageEnum): LanguageEnum {
|
|
18
16
|
const prefix = safeStringable(lng.split("-")[0]?.toLowerCase());
|
|
19
17
|
return safeEnum<LanguageEnum>(prefix || undefined, LANGUAGE_VALUES, fallbackLng);
|
|
@@ -43,19 +41,7 @@ export function initI18n(options: InitI18nOptions): void {
|
|
|
43
41
|
return;
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
const
|
|
47
|
-
const user: CreateI18nResourcesResult = options.getBuiltinBundles();
|
|
48
|
-
const RESOURCES = ([LanguageEnum.EN, LanguageEnum.ZH, LanguageEnum.FR] as const).reduce(
|
|
49
|
-
(acc, lang) => ({
|
|
50
|
-
...acc,
|
|
51
|
-
[lang]: {
|
|
52
|
-
...(nfx.RESOURCES[lang] ?? {}),
|
|
53
|
-
...(user.RESOURCES[lang] ?? {}),
|
|
54
|
-
},
|
|
55
|
-
}),
|
|
56
|
-
{} as typeof user.RESOURCES,
|
|
57
|
-
);
|
|
58
|
-
const NAME_SPACES = [...user.NAME_SPACES, ...nfx.NAME_SPACES.filter((n) => !user.NAME_SPACES.includes(n))];
|
|
44
|
+
const { RESOURCES, NAME_SPACES }: CreateI18nResourcesResult = options.getBuiltinBundles();
|
|
59
45
|
const initialLng = PreferenceStore.getState().language;
|
|
60
46
|
|
|
61
47
|
const persistLanguage = (lng: string) => {
|