@famgia/omnify-react-sso 2.2.2 → 2.2.3

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/dist/index.cjs CHANGED
@@ -34,16 +34,20 @@ __export(src_exports, {
34
34
  BranchContext: () => BranchContext,
35
35
  BranchGate: () => BranchGate,
36
36
  BranchProvider: () => BranchProvider,
37
+ I18nProvider: () => I18nProvider,
37
38
  OrgBranchSelectorModal: () => OrgBranchSelectorModal,
38
39
  OrganizationSwitcher: () => OrganizationSwitcher,
39
40
  ProtectedRoute: () => ProtectedRoute,
40
41
  SsoCallback: () => SsoCallback,
41
42
  SsoContext: () => SsoContext,
42
43
  SsoProvider: () => SsoProvider,
44
+ UserForm: () => UserForm,
45
+ UserTable: () => UserTable,
43
46
  branchCacheCreateSchema: () => branchCacheCreateSchema,
44
47
  branchCacheI18n: () => branchCacheI18n,
45
48
  branchCacheSchemas: () => branchCacheSchemas,
46
49
  branchCacheUpdateSchema: () => branchCacheUpdateSchema,
50
+ changeLanguage: () => changeLanguage,
47
51
  createAuthService: () => createAuthService,
48
52
  createBranchHeaderSetter: () => createBranchHeaderSetter,
49
53
  createBranchService: () => createBranchService,
@@ -53,11 +57,14 @@ __export(src_exports, {
53
57
  createTeamService: () => createTeamService,
54
58
  createTokenService: () => createTokenService,
55
59
  createUserRoleService: () => createUserRoleService,
56
- defaultLocale: () => defaultLocale,
60
+ createUserService: () => createUserService,
61
+ defaultLocale: () => defaultLocale2,
62
+ defaultTranslations: () => defaultTranslations,
57
63
  fallbackLocale: () => fallbackLocale,
58
64
  getBranchCacheFieldLabel: () => getBranchCacheFieldLabel,
59
65
  getBranchCacheFieldPlaceholder: () => getBranchCacheFieldPlaceholder,
60
66
  getBranchCacheLabel: () => getBranchCacheLabel,
67
+ getCurrentLocale: () => getCurrentLocale,
61
68
  getEffectivePermissions: () => getEffectivePermissions,
62
69
  getMessage: () => getMessage,
63
70
  getMessages: () => getMessages,
@@ -83,6 +90,8 @@ __export(src_exports, {
83
90
  getUserCacheFieldLabel: () => getUserCacheFieldLabel,
84
91
  getUserCacheFieldPlaceholder: () => getUserCacheFieldPlaceholder,
85
92
  getUserCacheLabel: () => getUserCacheLabel,
93
+ localeNames: () => localeNames,
94
+ locales: () => locales,
86
95
  organizationCacheCreateSchema: () => organizationCacheCreateSchema,
87
96
  organizationCacheI18n: () => organizationCacheI18n,
88
97
  organizationCacheSchemas: () => organizationCacheSchemas,
@@ -100,6 +109,7 @@ __export(src_exports, {
100
109
  roleSchemas: () => roleSchemas,
101
110
  roleUpdateSchema: () => roleUpdateSchema,
102
111
  setBranchHeaders: () => setBranchHeaders,
112
+ ssoNamespace: () => ssoNamespace,
103
113
  ssoQueryKeys: () => ssoQueryKeys,
104
114
  supportedLocales: () => supportedLocales,
105
115
  teamCacheCreateSchema: () => teamCacheCreateSchema,
@@ -113,8 +123,11 @@ __export(src_exports, {
113
123
  useAuth: () => useAuth,
114
124
  useBranch: () => useBranch,
115
125
  useBranchGate: () => useBranchGate,
126
+ useLocale: () => useLocale,
116
127
  useOrganization: () => useOrganization,
117
128
  useSso: () => useSso,
129
+ useSsoTranslation: () => useSsoTranslation,
130
+ useTranslations: () => useTranslations,
118
131
  userCacheCreateSchema: () => userCacheCreateSchema,
119
132
  userCacheI18n: () => userCacheI18n,
120
133
  userCacheSchemas: () => userCacheSchemas,
@@ -182,26 +195,26 @@ function getMessages(locale) {
182
195
  var import_zod = require("zod");
183
196
  var branchCacheI18n = {
184
197
  /** Model display name */
185
- label: { "en": "Branch Cache" },
198
+ label: { "ja": "\u652F\u5E97\u30AD\u30E3\u30C3\u30B7\u30E5", "en": "Branch Cache" },
186
199
  /** Field labels and placeholders */
187
200
  fields: {
188
201
  console_branch_id: {
189
- label: { "en": "Console Branch ID" }
202
+ label: { "ja": "Console Branch ID", "en": "Console Branch ID" }
190
203
  },
191
204
  console_org_id: {
192
- label: { "en": "Console Organization ID" }
205
+ label: { "ja": "Console Organization ID", "en": "Console Organization ID" }
193
206
  },
194
207
  code: {
195
- label: { "en": "Branch Code" }
208
+ label: { "ja": "\u652F\u5E97\u30B3\u30FC\u30C9", "en": "Branch Code" }
196
209
  },
197
210
  name: {
198
- label: { "en": "Branch Name" }
211
+ label: { "ja": "\u652F\u5E97\u540D", "en": "Branch Name" }
199
212
  },
200
213
  is_headquarters: {
201
- label: { "en": "Is Headquarters" }
214
+ label: { "ja": "\u672C\u793E", "en": "Is Headquarters" }
202
215
  },
203
216
  is_active: {
204
- label: { "en": "Active" }
217
+ label: { "ja": "\u6709\u52B9", "en": "Active" }
205
218
  }
206
219
  }
207
220
  };
@@ -246,20 +259,20 @@ var branchCacheUpdateSchema = baseBranchCacheUpdateSchema;
246
259
  var import_zod2 = require("zod");
247
260
  var organizationCacheI18n = {
248
261
  /** Model display name */
249
- label: { "en": "Organization Cache" },
262
+ label: { "ja": "\u7D44\u7E54\u30AD\u30E3\u30C3\u30B7\u30E5", "en": "Organization Cache" },
250
263
  /** Field labels and placeholders */
251
264
  fields: {
252
265
  console_org_id: {
253
- label: { "en": "Console Organization ID" }
266
+ label: { "ja": "Console Organization ID", "en": "Console Organization ID" }
254
267
  },
255
268
  name: {
256
- label: { "en": "Organization Name" }
269
+ label: { "ja": "\u7D44\u7E54\u540D", "en": "Organization Name" }
257
270
  },
258
271
  code: {
259
- label: { "en": "Organization Code" }
272
+ label: { "ja": "\u7D44\u7E54\u30B3\u30FC\u30C9", "en": "Organization Code" }
260
273
  },
261
274
  is_active: {
262
- label: { "en": "Active" }
275
+ label: { "ja": "\u6709\u52B9", "en": "Active" }
263
276
  }
264
277
  }
265
278
  };
@@ -300,20 +313,20 @@ var organizationCacheUpdateSchema = baseOrganizationCacheUpdateSchema;
300
313
  var import_zod3 = require("zod");
301
314
  var permissionI18n = {
302
315
  /** Model display name */
303
- label: { "en": "Permission" },
316
+ label: { "ja": "\u6A29\u9650", "en": "Permission" },
304
317
  /** Field labels and placeholders */
305
318
  fields: {
306
319
  name: {
307
- label: { "en": "Permission Name" }
320
+ label: { "ja": "\u6A29\u9650\u540D", "en": "Permission Name" }
308
321
  },
309
322
  slug: {
310
- label: { "en": "Slug" }
323
+ label: { "ja": "\u30B9\u30E9\u30C3\u30B0", "en": "Slug" }
311
324
  },
312
325
  group: {
313
- label: { "en": "Group" }
326
+ label: { "ja": "\u30B0\u30EB\u30FC\u30D7", "en": "Group" }
314
327
  },
315
328
  roles: {
316
- label: { "en": "Roles" }
329
+ label: { "ja": "\u30ED\u30FC\u30EB", "en": "Roles" }
317
330
  }
318
331
  }
319
332
  };
@@ -352,33 +365,38 @@ var permissionUpdateSchema = basePermissionUpdateSchema;
352
365
  var import_zod4 = require("zod");
353
366
  var roleI18n = {
354
367
  /** Model display name */
355
- label: { "en": "Role" },
368
+ label: { "ja": "\u30ED\u30FC\u30EB", "en": "Role" },
356
369
  /** Field labels and placeholders */
357
370
  fields: {
371
+ console_org_id: {
372
+ label: { "ja": "\u7D44\u7E54ID", "en": "Organization ID" }
373
+ },
358
374
  name: {
359
- label: { "en": "Role Name" }
375
+ label: { "ja": "\u30ED\u30FC\u30EB\u540D", "en": "Role Name" }
360
376
  },
361
377
  slug: {
362
- label: { "en": "Slug" }
378
+ label: { "ja": "\u30B9\u30E9\u30C3\u30B0", "en": "Slug" }
363
379
  },
364
380
  description: {
365
- label: { "en": "Description" }
381
+ label: { "ja": "\u8AAC\u660E", "en": "Description" }
366
382
  },
367
383
  level: {
368
- label: { "en": "Level" }
384
+ label: { "ja": "\u30EC\u30D9\u30EB", "en": "Level" }
369
385
  },
370
386
  permissions: {
371
- label: { "en": "Permissions" }
387
+ label: { "ja": "\u6A29\u9650", "en": "Permissions" }
372
388
  }
373
389
  }
374
390
  };
375
391
  var baseRoleSchemas = {
392
+ console_org_id: import_zod4.z.string().max(36).optional().nullable(),
376
393
  name: import_zod4.z.string().min(1).max(100),
377
394
  slug: import_zod4.z.string().min(1).max(100),
378
395
  description: import_zod4.z.string().optional().nullable(),
379
396
  level: import_zod4.z.number().int()
380
397
  };
381
398
  var baseRoleCreateSchema = import_zod4.z.object({
399
+ console_org_id: baseRoleSchemas.console_org_id,
382
400
  name: baseRoleSchemas.name,
383
401
  slug: baseRoleSchemas.slug,
384
402
  description: baseRoleSchemas.description,
@@ -409,14 +427,14 @@ var roleUpdateSchema = baseRoleUpdateSchema;
409
427
  var import_zod5 = require("zod");
410
428
  var rolePermissionI18n = {
411
429
  /** Model display name */
412
- label: { "en": "Role Permission" },
430
+ label: { "ja": "\u30ED\u30FC\u30EB\u6A29\u9650", "en": "Role Permission" },
413
431
  /** Field labels and placeholders */
414
432
  fields: {
415
433
  role: {
416
- label: { "en": "Role" }
434
+ label: { "ja": "\u30ED\u30FC\u30EB", "en": "Role" }
417
435
  },
418
436
  permission: {
419
- label: { "en": "Permission" }
437
+ label: { "ja": "\u6A29\u9650", "en": "Permission" }
420
438
  }
421
439
  }
422
440
  };
@@ -447,17 +465,17 @@ var rolePermissionUpdateSchema = baseRolePermissionUpdateSchema;
447
465
  var import_zod6 = require("zod");
448
466
  var teamCacheI18n = {
449
467
  /** Model display name */
450
- label: { "en": "Team Cache" },
468
+ label: { "ja": "\u30C1\u30FC\u30E0\u30AD\u30E3\u30C3\u30B7\u30E5", "en": "Team Cache" },
451
469
  /** Field labels and placeholders */
452
470
  fields: {
453
471
  console_team_id: {
454
- label: { "en": "Console Team ID" }
472
+ label: { "ja": "Console Team ID", "en": "Console Team ID" }
455
473
  },
456
474
  console_org_id: {
457
- label: { "en": "Console Organization ID" }
475
+ label: { "ja": "Console Organization ID", "en": "Console Organization ID" }
458
476
  },
459
477
  name: {
460
- label: { "en": "Team Name" }
478
+ label: { "ja": "\u30C1\u30FC\u30E0\u540D", "en": "Team Name" }
461
479
  }
462
480
  }
463
481
  };
@@ -496,17 +514,17 @@ var teamCacheUpdateSchema = baseTeamCacheUpdateSchema;
496
514
  var import_zod7 = require("zod");
497
515
  var teamPermissionI18n = {
498
516
  /** Model display name */
499
- label: { "en": "Team Permission" },
517
+ label: { "ja": "\u30C1\u30FC\u30E0\u6A29\u9650", "en": "Team Permission" },
500
518
  /** Field labels and placeholders */
501
519
  fields: {
502
520
  console_org_id: {
503
- label: { "en": "Console Organization ID" }
521
+ label: { "ja": "Console Organization ID", "en": "Console Organization ID" }
504
522
  },
505
523
  console_team_id: {
506
- label: { "en": "Console Team ID" }
524
+ label: { "ja": "Console Team ID", "en": "Console Team ID" }
507
525
  },
508
526
  permission: {
509
- label: { "en": "Permission" }
527
+ label: { "ja": "\u6A29\u9650", "en": "Permission" }
510
528
  }
511
529
  }
512
530
  };
@@ -543,29 +561,32 @@ var teamPermissionUpdateSchema = baseTeamPermissionUpdateSchema;
543
561
  var import_zod8 = require("zod");
544
562
  var userCacheI18n = {
545
563
  /** Model display name */
546
- label: { "en": "User Cache" },
564
+ label: { "ja": "\u30E6\u30FC\u30B6\u30FC\u30AD\u30E3\u30C3\u30B7\u30E5", "en": "User Cache" },
547
565
  /** Field labels and placeholders */
548
566
  fields: {
549
567
  name: {
550
- label: { "en": "Name" }
568
+ label: { "ja": "\u540D\u524D", "en": "Name" }
551
569
  },
552
570
  email: {
553
- label: { "en": "Email" }
571
+ label: { "ja": "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9", "en": "Email" }
554
572
  },
555
573
  console_user_id: {
556
- label: { "en": "Console User ID" }
574
+ label: { "ja": "Console User ID", "en": "Console User ID" }
575
+ },
576
+ console_org_id: {
577
+ label: { "ja": "\u6240\u5C5E\u7D44\u7E54ID", "en": "Organization ID" }
557
578
  },
558
579
  console_access_token: {
559
- label: { "en": "Console Access Token" }
580
+ label: { "ja": "Console Access Token", "en": "Console Access Token" }
560
581
  },
561
582
  console_refresh_token: {
562
- label: { "en": "Console Refresh Token" }
583
+ label: { "ja": "Console Refresh Token", "en": "Console Refresh Token" }
563
584
  },
564
585
  console_token_expires_at: {
565
- label: { "en": "Console Token Expiry" }
586
+ label: { "ja": "Console Token\u6709\u52B9\u671F\u9650", "en": "Console Token Expiry" }
566
587
  },
567
588
  roles: {
568
- label: { "en": "Roles" }
589
+ label: { "ja": "\u30ED\u30FC\u30EB", "en": "Roles" }
569
590
  }
570
591
  }
571
592
  };
@@ -573,6 +594,7 @@ var baseUserCacheSchemas = {
573
594
  name: import_zod8.z.string().min(1),
574
595
  email: import_zod8.z.string().min(1),
575
596
  console_user_id: import_zod8.z.string().optional().nullable(),
597
+ console_org_id: import_zod8.z.string().optional().nullable(),
576
598
  console_access_token: import_zod8.z.string().optional().nullable(),
577
599
  console_refresh_token: import_zod8.z.string().optional().nullable(),
578
600
  console_token_expires_at: import_zod8.z.string().datetime({ offset: true }).optional().nullable()
@@ -581,6 +603,7 @@ var baseUserCacheCreateSchema = import_zod8.z.object({
581
603
  name: baseUserCacheSchemas.name,
582
604
  email: baseUserCacheSchemas.email,
583
605
  console_user_id: baseUserCacheSchemas.console_user_id,
606
+ console_org_id: baseUserCacheSchemas.console_org_id,
584
607
  console_access_token: baseUserCacheSchemas.console_access_token,
585
608
  console_refresh_token: baseUserCacheSchemas.console_refresh_token,
586
609
  console_token_expires_at: baseUserCacheSchemas.console_token_expires_at
@@ -842,8 +865,114 @@ function useBranchContext() {
842
865
  }
843
866
 
844
867
  // src/context/BranchProvider.tsx
845
- var import_react4 = require("react");
846
868
  var import_react_query = require("@tanstack/react-query");
869
+ var import_react4 = require("react");
870
+
871
+ // src/queryKeys.ts
872
+ var ssoQueryKeys = {
873
+ all: ["sso"],
874
+ // =========================================================================
875
+ // Auth (authService)
876
+ // =========================================================================
877
+ auth: {
878
+ all: () => [...ssoQueryKeys.all, "auth"],
879
+ user: () => [...ssoQueryKeys.auth.all(), "user"],
880
+ globalLogoutUrl: (redirectUri) => [...ssoQueryKeys.auth.all(), "global-logout-url", redirectUri]
881
+ },
882
+ // =========================================================================
883
+ // Tokens (tokenService)
884
+ // =========================================================================
885
+ tokens: {
886
+ all: () => [...ssoQueryKeys.all, "tokens"],
887
+ list: () => [...ssoQueryKeys.tokens.all(), "list"]
888
+ },
889
+ // =========================================================================
890
+ // Roles (roleService)
891
+ // =========================================================================
892
+ roles: {
893
+ all: () => [...ssoQueryKeys.all, "roles"],
894
+ list: () => [...ssoQueryKeys.roles.all(), "list"],
895
+ detail: (id) => [...ssoQueryKeys.roles.all(), "detail", id],
896
+ permissions: (id) => [...ssoQueryKeys.roles.all(), id, "permissions"]
897
+ },
898
+ // =========================================================================
899
+ // Permissions (permissionService)
900
+ // =========================================================================
901
+ permissions: {
902
+ all: () => [...ssoQueryKeys.all, "permissions"],
903
+ list: (params) => [...ssoQueryKeys.permissions.all(), "list", params],
904
+ detail: (id) => [...ssoQueryKeys.permissions.all(), "detail", id],
905
+ matrix: () => [...ssoQueryKeys.permissions.all(), "matrix"]
906
+ },
907
+ // =========================================================================
908
+ // Teams (teamService)
909
+ // =========================================================================
910
+ teams: {
911
+ all: () => [...ssoQueryKeys.all, "teams"],
912
+ list: () => [...ssoQueryKeys.teams.all(), "list"],
913
+ permissions: (teamId) => [...ssoQueryKeys.teams.all(), teamId, "permissions"],
914
+ orphaned: () => [...ssoQueryKeys.teams.all(), "orphaned"]
915
+ },
916
+ // =========================================================================
917
+ // User Roles (userRoleService) - Scoped Role Assignments
918
+ // =========================================================================
919
+ userRoles: {
920
+ all: () => [...ssoQueryKeys.all, "user-roles"],
921
+ list: (userId) => [...ssoQueryKeys.userRoles.all(), userId],
922
+ byBranch: (userId, orgId, branchId) => [...ssoQueryKeys.userRoles.all(), userId, orgId, branchId]
923
+ },
924
+ // =========================================================================
925
+ // Users (userService)
926
+ // =========================================================================
927
+ users: {
928
+ all: () => [...ssoQueryKeys.all, "users"],
929
+ list: (params) => [...ssoQueryKeys.users.all(), "list", params],
930
+ detail: (id) => [...ssoQueryKeys.users.all(), "detail", id]
931
+ },
932
+ // =========================================================================
933
+ // Branches (branchService)
934
+ // =========================================================================
935
+ branches: {
936
+ all: () => [...ssoQueryKeys.all, "branches"],
937
+ list: (orgSlug) => [...ssoQueryKeys.branches.all(), "list", orgSlug],
938
+ detail: (branchId) => [...ssoQueryKeys.branches.all(), "detail", branchId],
939
+ headquarters: (orgSlug) => [...ssoQueryKeys.branches.all(), "headquarters", orgSlug],
940
+ primary: (orgSlug) => [...ssoQueryKeys.branches.all(), "primary", orgSlug]
941
+ },
942
+ // =========================================================================
943
+ // Admin variants (with org context)
944
+ // =========================================================================
945
+ admin: {
946
+ users: {
947
+ all: (orgSlug) => [...ssoQueryKeys.all, "admin", orgSlug, "users"],
948
+ list: (orgSlug, params) => [...ssoQueryKeys.admin.users.all(orgSlug), "list", params],
949
+ detail: (orgSlug, id) => [...ssoQueryKeys.admin.users.all(orgSlug), "detail", id]
950
+ },
951
+ roles: {
952
+ all: (orgSlug) => [...ssoQueryKeys.all, "admin", orgSlug, "roles"],
953
+ list: (orgSlug) => [...ssoQueryKeys.admin.roles.all(orgSlug), "list"],
954
+ detail: (orgSlug, id) => [...ssoQueryKeys.admin.roles.all(orgSlug), "detail", id],
955
+ permissions: (orgSlug, id) => [...ssoQueryKeys.admin.roles.all(orgSlug), id, "permissions"]
956
+ },
957
+ permissions: {
958
+ all: (orgSlug) => [...ssoQueryKeys.all, "admin", orgSlug, "permissions"],
959
+ list: (orgSlug, params) => [...ssoQueryKeys.admin.permissions.all(orgSlug), "list", params],
960
+ detail: (orgSlug, id) => [...ssoQueryKeys.admin.permissions.all(orgSlug), "detail", id],
961
+ matrix: (orgSlug) => [...ssoQueryKeys.admin.permissions.all(orgSlug), "matrix"]
962
+ },
963
+ teams: {
964
+ all: (orgSlug) => [...ssoQueryKeys.all, "admin", orgSlug, "teams"],
965
+ list: (orgSlug) => [...ssoQueryKeys.admin.teams.all(orgSlug), "list"],
966
+ permissions: (orgSlug, teamId) => [...ssoQueryKeys.admin.teams.all(orgSlug), teamId, "permissions"],
967
+ orphaned: (orgSlug) => [...ssoQueryKeys.admin.teams.all(orgSlug), "orphaned"]
968
+ },
969
+ userRoles: {
970
+ all: (orgSlug) => [...ssoQueryKeys.all, "admin", orgSlug, "user-roles"],
971
+ list: (orgSlug, userId) => [...ssoQueryKeys.admin.userRoles.all(orgSlug), userId],
972
+ byBranch: (orgSlug, userId, orgId, branchId) => [...ssoQueryKeys.admin.userRoles.all(orgSlug), userId, orgId, branchId]
973
+ }
974
+ }
975
+ };
847
976
 
848
977
  // src/services/utils.ts
849
978
  function getXsrfToken2() {
@@ -860,7 +989,7 @@ function buildHeaders(orgSlug) {
860
989
  headers["X-XSRF-TOKEN"] = decodeURIComponent(xsrfToken);
861
990
  }
862
991
  if (orgSlug) {
863
- headers["X-Org-Slug"] = orgSlug;
992
+ headers["X-Org-Id"] = orgSlug;
864
993
  }
865
994
  return headers;
866
995
  }
@@ -948,99 +1077,6 @@ function createBranchService(config) {
948
1077
  };
949
1078
  }
950
1079
 
951
- // src/queryKeys.ts
952
- var ssoQueryKeys = {
953
- all: ["sso"],
954
- // =========================================================================
955
- // Auth (authService)
956
- // =========================================================================
957
- auth: {
958
- all: () => [...ssoQueryKeys.all, "auth"],
959
- user: () => [...ssoQueryKeys.auth.all(), "user"],
960
- globalLogoutUrl: (redirectUri) => [...ssoQueryKeys.auth.all(), "global-logout-url", redirectUri]
961
- },
962
- // =========================================================================
963
- // Tokens (tokenService)
964
- // =========================================================================
965
- tokens: {
966
- all: () => [...ssoQueryKeys.all, "tokens"],
967
- list: () => [...ssoQueryKeys.tokens.all(), "list"]
968
- },
969
- // =========================================================================
970
- // Roles (roleService)
971
- // =========================================================================
972
- roles: {
973
- all: () => [...ssoQueryKeys.all, "roles"],
974
- list: () => [...ssoQueryKeys.roles.all(), "list"],
975
- detail: (id) => [...ssoQueryKeys.roles.all(), "detail", id],
976
- permissions: (id) => [...ssoQueryKeys.roles.all(), id, "permissions"]
977
- },
978
- // =========================================================================
979
- // Permissions (permissionService)
980
- // =========================================================================
981
- permissions: {
982
- all: () => [...ssoQueryKeys.all, "permissions"],
983
- list: (params) => [...ssoQueryKeys.permissions.all(), "list", params],
984
- detail: (id) => [...ssoQueryKeys.permissions.all(), "detail", id],
985
- matrix: () => [...ssoQueryKeys.permissions.all(), "matrix"]
986
- },
987
- // =========================================================================
988
- // Teams (teamService)
989
- // =========================================================================
990
- teams: {
991
- all: () => [...ssoQueryKeys.all, "teams"],
992
- list: () => [...ssoQueryKeys.teams.all(), "list"],
993
- permissions: (teamId) => [...ssoQueryKeys.teams.all(), teamId, "permissions"],
994
- orphaned: () => [...ssoQueryKeys.teams.all(), "orphaned"]
995
- },
996
- // =========================================================================
997
- // User Roles (userRoleService) - Scoped Role Assignments
998
- // =========================================================================
999
- userRoles: {
1000
- all: () => [...ssoQueryKeys.all, "user-roles"],
1001
- list: (userId) => [...ssoQueryKeys.userRoles.all(), userId],
1002
- byBranch: (userId, orgId, branchId) => [...ssoQueryKeys.userRoles.all(), userId, orgId, branchId]
1003
- },
1004
- // =========================================================================
1005
- // Branches (branchService)
1006
- // =========================================================================
1007
- branches: {
1008
- all: () => [...ssoQueryKeys.all, "branches"],
1009
- list: (orgSlug) => [...ssoQueryKeys.branches.all(), "list", orgSlug],
1010
- detail: (branchId) => [...ssoQueryKeys.branches.all(), "detail", branchId],
1011
- headquarters: (orgSlug) => [...ssoQueryKeys.branches.all(), "headquarters", orgSlug],
1012
- primary: (orgSlug) => [...ssoQueryKeys.branches.all(), "primary", orgSlug]
1013
- },
1014
- // =========================================================================
1015
- // Admin variants (with org context)
1016
- // =========================================================================
1017
- admin: {
1018
- roles: {
1019
- all: (orgSlug) => [...ssoQueryKeys.all, "admin", orgSlug, "roles"],
1020
- list: (orgSlug) => [...ssoQueryKeys.admin.roles.all(orgSlug), "list"],
1021
- detail: (orgSlug, id) => [...ssoQueryKeys.admin.roles.all(orgSlug), "detail", id],
1022
- permissions: (orgSlug, id) => [...ssoQueryKeys.admin.roles.all(orgSlug), id, "permissions"]
1023
- },
1024
- permissions: {
1025
- all: (orgSlug) => [...ssoQueryKeys.all, "admin", orgSlug, "permissions"],
1026
- list: (orgSlug, params) => [...ssoQueryKeys.admin.permissions.all(orgSlug), "list", params],
1027
- detail: (orgSlug, id) => [...ssoQueryKeys.admin.permissions.all(orgSlug), "detail", id],
1028
- matrix: (orgSlug) => [...ssoQueryKeys.admin.permissions.all(orgSlug), "matrix"]
1029
- },
1030
- teams: {
1031
- all: (orgSlug) => [...ssoQueryKeys.all, "admin", orgSlug, "teams"],
1032
- list: (orgSlug) => [...ssoQueryKeys.admin.teams.all(orgSlug), "list"],
1033
- permissions: (orgSlug, teamId) => [...ssoQueryKeys.admin.teams.all(orgSlug), teamId, "permissions"],
1034
- orphaned: (orgSlug) => [...ssoQueryKeys.admin.teams.all(orgSlug), "orphaned"]
1035
- },
1036
- userRoles: {
1037
- all: (orgSlug) => [...ssoQueryKeys.all, "admin", orgSlug, "user-roles"],
1038
- list: (orgSlug, userId) => [...ssoQueryKeys.admin.userRoles.all(orgSlug), userId],
1039
- byBranch: (orgSlug, userId, orgId, branchId) => [...ssoQueryKeys.admin.userRoles.all(orgSlug), userId, orgId, branchId]
1040
- }
1041
- }
1042
- };
1043
-
1044
1080
  // src/context/BranchProvider.tsx
1045
1081
  var import_jsx_runtime2 = require("react/jsx-runtime");
1046
1082
  var DEFAULT_STORAGE_KEY = "omnify_selected_branch";
@@ -1375,9 +1411,9 @@ function SsoCallback({
1375
1411
  }
1376
1412
 
1377
1413
  // src/components/OrganizationSwitcher.tsx
1378
- var import_react9 = __toESM(require("react"), 1);
1379
- var import_antd = require("antd");
1380
1414
  var import_icons = require("@ant-design/icons");
1415
+ var import_antd = require("antd");
1416
+ var import_react9 = __toESM(require("react"), 1);
1381
1417
  var import_jsx_runtime4 = require("react/jsx-runtime");
1382
1418
  var { Text } = import_antd.Typography;
1383
1419
  function OrganizationSwitcher({
@@ -1541,10 +1577,10 @@ function ProtectedRoute({
1541
1577
  }
1542
1578
 
1543
1579
  // src/components/OrgBranchSelectorModal.tsx
1544
- var import_react11 = require("react");
1545
- var import_antd2 = require("antd");
1546
1580
  var import_icons2 = require("@ant-design/icons");
1547
1581
  var import_react_query2 = require("@tanstack/react-query");
1582
+ var import_antd2 = require("antd");
1583
+ var import_react11 = require("react");
1548
1584
  var import_jsx_runtime6 = require("react/jsx-runtime");
1549
1585
  var { Text: Text2, Title } = import_antd2.Typography;
1550
1586
  function OrgBranchSelectorModal({
@@ -1557,6 +1593,7 @@ function OrgBranchSelectorModal({
1557
1593
  }) {
1558
1594
  const { config } = useSsoContext();
1559
1595
  const { organizations, currentOrg, hasMultipleOrgs } = useOrganization();
1596
+ const { currentBranch } = useBranch();
1560
1597
  const [form] = import_antd2.Form.useForm();
1561
1598
  const [selectedOrgSlug, setSelectedOrgSlug] = (0, import_react11.useState)(
1562
1599
  currentOrg?.slug ?? null
@@ -1577,17 +1614,26 @@ function OrgBranchSelectorModal({
1577
1614
  const branches = branchesData?.branches ?? [];
1578
1615
  const hasMultipleBranches = branches.length > 1;
1579
1616
  const selectedOrg = (0, import_react11.useMemo)(
1580
- () => organizations.find((o) => o.slug === selectedOrgSlug) ?? null,
1617
+ () => {
1618
+ if (selectedOrgSlug) {
1619
+ return organizations.find((o) => o.slug === selectedOrgSlug) ?? null;
1620
+ }
1621
+ if (organizations.length === 1) {
1622
+ return organizations[0];
1623
+ }
1624
+ return null;
1625
+ },
1581
1626
  [organizations, selectedOrgSlug]
1582
1627
  );
1583
1628
  (0, import_react11.useEffect)(() => {
1584
1629
  if (!open) return;
1585
- if (organizations.length === 1 && !selectedOrgSlug) {
1586
- setSelectedOrgSlug(organizations[0].slug);
1587
- form.setFieldValue("organization_id", organizations[0].id);
1588
- } else if (currentOrg && !selectedOrgSlug) {
1630
+ if (selectedOrgSlug && form.getFieldValue("organization_id")) return;
1631
+ if (currentOrg) {
1589
1632
  setSelectedOrgSlug(currentOrg.slug);
1590
1633
  form.setFieldValue("organization_id", currentOrg.id);
1634
+ } else if (organizations.length === 1) {
1635
+ setSelectedOrgSlug(organizations[0].slug);
1636
+ form.setFieldValue("organization_id", organizations[0].id);
1591
1637
  }
1592
1638
  }, [open, organizations, currentOrg, selectedOrgSlug, form]);
1593
1639
  (0, import_react11.useEffect)(() => {
@@ -1595,17 +1641,21 @@ function OrgBranchSelectorModal({
1595
1641
  if (branches.length === 1) {
1596
1642
  form.setFieldValue("branch_id", branches[0].id);
1597
1643
  } else if (branches.length > 0) {
1598
- const primaryId = branchesData?.primary_branch_id;
1599
- if (primaryId) {
1600
- form.setFieldValue("branch_id", primaryId);
1644
+ if (currentBranch && branches.some((b) => b.id === currentBranch.id)) {
1645
+ form.setFieldValue("branch_id", currentBranch.id);
1601
1646
  } else {
1602
- const hq = branches.find((b) => b.is_headquarters);
1603
- if (hq) {
1604
- form.setFieldValue("branch_id", hq.id);
1647
+ const primaryId = branchesData?.primary_branch_id;
1648
+ if (primaryId) {
1649
+ form.setFieldValue("branch_id", primaryId);
1650
+ } else {
1651
+ const hq = branches.find((b) => b.is_headquarters);
1652
+ if (hq) {
1653
+ form.setFieldValue("branch_id", hq.id);
1654
+ }
1605
1655
  }
1606
1656
  }
1607
1657
  }
1608
- }, [open, branches, branchesLoading, branchesData, form]);
1658
+ }, [open, branches, branchesLoading, branchesData, currentBranch, form]);
1609
1659
  (0, import_react11.useEffect)(() => {
1610
1660
  if (!open || branchesLoading) return;
1611
1661
  const orgId = form.getFieldValue("organization_id");
@@ -1808,10 +1858,10 @@ function OrgBranchSelectorModal({
1808
1858
  }
1809
1859
 
1810
1860
  // src/components/BranchGate.tsx
1811
- var import_react12 = __toESM(require("react"), 1);
1812
- var import_antd3 = require("antd");
1813
1861
  var import_icons3 = require("@ant-design/icons");
1814
1862
  var import_react_query3 = require("@tanstack/react-query");
1863
+ var import_antd3 = require("antd");
1864
+ var import_react12 = __toESM(require("react"), 1);
1815
1865
  var import_jsx_runtime7 = require("react/jsx-runtime");
1816
1866
  var { Text: Text3, Title: Title2 } = import_antd3.Typography;
1817
1867
  var DEFAULT_STORAGE_KEY2 = "omnify_branch_gate_selection";
@@ -2107,6 +2157,453 @@ function useBranchGate(storageKey = DEFAULT_STORAGE_KEY2) {
2107
2157
  };
2108
2158
  }
2109
2159
 
2160
+ // src/components/admin/UserTable.tsx
2161
+ var import_icons4 = require("@ant-design/icons");
2162
+ var import_antd4 = require("antd");
2163
+
2164
+ // src/i18n/translations.ts
2165
+ var ssoNamespace = "sso";
2166
+ var defaultTranslations = {
2167
+ en: {
2168
+ // Common
2169
+ actions: "Actions",
2170
+ save: "Save",
2171
+ cancel: "Cancel",
2172
+ delete: "Delete",
2173
+ edit: "Edit",
2174
+ search: "Search",
2175
+ loading: "Loading...",
2176
+ yes: "Yes",
2177
+ no: "No",
2178
+ confirmDelete: "Are you sure you want to delete?",
2179
+ // Users
2180
+ users: "Users",
2181
+ user: "User",
2182
+ name: "Name",
2183
+ email: "Email",
2184
+ ssoUser: "SSO User",
2185
+ localUser: "Local User",
2186
+ userList: "User List",
2187
+ userDetails: "User Details",
2188
+ editUser: "Edit User",
2189
+ deleteUser: "Delete User",
2190
+ searchUsers: "Search users...",
2191
+ noUsersFound: "No users found",
2192
+ userDeleted: "User deleted successfully",
2193
+ userUpdated: "User updated successfully",
2194
+ // Roles
2195
+ roles: "Roles",
2196
+ role: "Role",
2197
+ roleName: "Role Name",
2198
+ roleDescription: "Description",
2199
+ permissions: "Permissions",
2200
+ assignRole: "Assign Role",
2201
+ removeRole: "Remove Role",
2202
+ // Permissions
2203
+ permission: "Permission",
2204
+ permissionName: "Permission Name",
2205
+ permissionDescription: "Description",
2206
+ // Validation
2207
+ required: "{{field}} is required",
2208
+ maxLength: "{{field}} must be at most {{max}} characters",
2209
+ invalidEmail: "Please enter a valid email address",
2210
+ // Pagination
2211
+ total: "Total {{count}} items",
2212
+ page: "Page {{current}} of {{total}}"
2213
+ },
2214
+ ja: {
2215
+ // Common
2216
+ actions: "\u64CD\u4F5C",
2217
+ save: "\u4FDD\u5B58",
2218
+ cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB",
2219
+ delete: "\u524A\u9664",
2220
+ edit: "\u7DE8\u96C6",
2221
+ search: "\u691C\u7D22",
2222
+ loading: "\u8AAD\u307F\u8FBC\u307F\u4E2D...",
2223
+ yes: "\u306F\u3044",
2224
+ no: "\u3044\u3044\u3048",
2225
+ confirmDelete: "\u672C\u5F53\u306B\u524A\u9664\u3057\u307E\u3059\u304B\uFF1F",
2226
+ // Users
2227
+ users: "\u30E6\u30FC\u30B6\u30FC",
2228
+ user: "\u30E6\u30FC\u30B6\u30FC",
2229
+ name: "\u540D\u524D",
2230
+ email: "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9",
2231
+ ssoUser: "SSO\u30E6\u30FC\u30B6\u30FC",
2232
+ localUser: "\u30ED\u30FC\u30AB\u30EB\u30E6\u30FC\u30B6\u30FC",
2233
+ userList: "\u30E6\u30FC\u30B6\u30FC\u4E00\u89A7",
2234
+ userDetails: "\u30E6\u30FC\u30B6\u30FC\u8A73\u7D30",
2235
+ editUser: "\u30E6\u30FC\u30B6\u30FC\u7DE8\u96C6",
2236
+ deleteUser: "\u30E6\u30FC\u30B6\u30FC\u524A\u9664",
2237
+ searchUsers: "\u30E6\u30FC\u30B6\u30FC\u3092\u691C\u7D22...",
2238
+ noUsersFound: "\u30E6\u30FC\u30B6\u30FC\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093",
2239
+ userDeleted: "\u30E6\u30FC\u30B6\u30FC\u3092\u524A\u9664\u3057\u307E\u3057\u305F",
2240
+ userUpdated: "\u30E6\u30FC\u30B6\u30FC\u3092\u66F4\u65B0\u3057\u307E\u3057\u305F",
2241
+ // Roles
2242
+ roles: "\u30ED\u30FC\u30EB",
2243
+ role: "\u30ED\u30FC\u30EB",
2244
+ roleName: "\u30ED\u30FC\u30EB\u540D",
2245
+ roleDescription: "\u8AAC\u660E",
2246
+ permissions: "\u6A29\u9650",
2247
+ assignRole: "\u30ED\u30FC\u30EB\u3092\u5272\u308A\u5F53\u3066",
2248
+ removeRole: "\u30ED\u30FC\u30EB\u3092\u524A\u9664",
2249
+ // Permissions
2250
+ permission: "\u6A29\u9650",
2251
+ permissionName: "\u6A29\u9650\u540D",
2252
+ permissionDescription: "\u8AAC\u660E",
2253
+ // Validation
2254
+ required: "{{field}}\u306F\u5FC5\u9808\u3067\u3059",
2255
+ maxLength: "{{field}}\u306F{{max}}\u6587\u5B57\u4EE5\u5185\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
2256
+ invalidEmail: "\u6709\u52B9\u306A\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
2257
+ // Pagination
2258
+ total: "\u5168{{count}}\u4EF6",
2259
+ page: "{{total}}\u30DA\u30FC\u30B8\u4E2D{{current}}\u30DA\u30FC\u30B8"
2260
+ },
2261
+ vi: {
2262
+ // Common
2263
+ actions: "H\xE0nh \u0111\u1ED9ng",
2264
+ save: "L\u01B0u",
2265
+ cancel: "H\u1EE7y",
2266
+ delete: "X\xF3a",
2267
+ edit: "S\u1EEDa",
2268
+ search: "T\xECm ki\u1EBFm",
2269
+ loading: "\u0110ang t\u1EA3i...",
2270
+ yes: "C\xF3",
2271
+ no: "Kh\xF4ng",
2272
+ confirmDelete: "B\u1EA1n c\xF3 ch\u1EAFc mu\u1ED1n x\xF3a?",
2273
+ // Users
2274
+ users: "Ng\u01B0\u1EDDi d\xF9ng",
2275
+ user: "Ng\u01B0\u1EDDi d\xF9ng",
2276
+ name: "T\xEAn",
2277
+ email: "Email",
2278
+ ssoUser: "Ng\u01B0\u1EDDi d\xF9ng SSO",
2279
+ localUser: "Ng\u01B0\u1EDDi d\xF9ng n\u1ED9i b\u1ED9",
2280
+ userList: "Danh s\xE1ch ng\u01B0\u1EDDi d\xF9ng",
2281
+ userDetails: "Chi ti\u1EBFt ng\u01B0\u1EDDi d\xF9ng",
2282
+ editUser: "S\u1EEDa ng\u01B0\u1EDDi d\xF9ng",
2283
+ deleteUser: "X\xF3a ng\u01B0\u1EDDi d\xF9ng",
2284
+ searchUsers: "T\xECm ng\u01B0\u1EDDi d\xF9ng...",
2285
+ noUsersFound: "Kh\xF4ng t\xECm th\u1EA5y ng\u01B0\u1EDDi d\xF9ng",
2286
+ userDeleted: "\u0110\xE3 x\xF3a ng\u01B0\u1EDDi d\xF9ng",
2287
+ userUpdated: "\u0110\xE3 c\u1EADp nh\u1EADt ng\u01B0\u1EDDi d\xF9ng",
2288
+ // Roles
2289
+ roles: "Vai tr\xF2",
2290
+ role: "Vai tr\xF2",
2291
+ roleName: "T\xEAn vai tr\xF2",
2292
+ roleDescription: "M\xF4 t\u1EA3",
2293
+ permissions: "Quy\u1EC1n",
2294
+ assignRole: "G\xE1n vai tr\xF2",
2295
+ removeRole: "X\xF3a vai tr\xF2",
2296
+ // Permissions
2297
+ permission: "Quy\u1EC1n",
2298
+ permissionName: "T\xEAn quy\u1EC1n",
2299
+ permissionDescription: "M\xF4 t\u1EA3",
2300
+ // Validation
2301
+ required: "{{field}} l\xE0 b\u1EAFt bu\u1ED9c",
2302
+ maxLength: "{{field}} t\u1ED1i \u0111a {{max}} k\xFD t\u1EF1",
2303
+ invalidEmail: "Email kh\xF4ng h\u1EE3p l\u1EC7",
2304
+ // Pagination
2305
+ total: "T\u1ED5ng {{count}} m\u1EE5c",
2306
+ page: "Trang {{current}}/{{total}}"
2307
+ }
2308
+ };
2309
+
2310
+ // src/i18n/useSsoTranslation.ts
2311
+ var import_react13 = require("react");
2312
+ function useSsoTranslation() {
2313
+ const t = (0, import_react13.useCallback)(
2314
+ (key, options) => {
2315
+ let value = defaultTranslations.en[key] || key;
2316
+ if (options) {
2317
+ Object.entries(options).forEach(([k, v]) => {
2318
+ value = value.replace(new RegExp(`{{${k}}}`, "g"), String(v));
2319
+ });
2320
+ }
2321
+ return value;
2322
+ },
2323
+ []
2324
+ );
2325
+ return { t };
2326
+ }
2327
+
2328
+ // src/i18n/I18nProvider.tsx
2329
+ var import_i18next2 = __toESM(require("i18next"), 1);
2330
+ var import_i18next_browser_languagedetector = __toESM(require("i18next-browser-languagedetector"), 1);
2331
+ var import_react14 = require("react");
2332
+ var import_react_i18next = require("react-i18next");
2333
+ var import_react_i18next2 = require("react-i18next");
2334
+
2335
+ // src/i18n/config.ts
2336
+ var import_i18next = __toESM(require("i18next"), 1);
2337
+ var locales = ["ja", "en", "vi"];
2338
+ var defaultLocale2 = "ja";
2339
+ var localeNames = {
2340
+ ja: "\u65E5\u672C\u8A9E",
2341
+ en: "English",
2342
+ vi: "Ti\u1EBFng Vi\u1EC7t"
2343
+ };
2344
+ var changeLanguage = (locale) => {
2345
+ if (typeof window === "undefined") return;
2346
+ import_i18next.default.changeLanguage(locale);
2347
+ document.cookie = `locale=${locale};path=/;max-age=31536000`;
2348
+ };
2349
+ var getCurrentLocale = () => {
2350
+ if (typeof window === "undefined") return defaultLocale2;
2351
+ return import_i18next.default.language || defaultLocale2;
2352
+ };
2353
+
2354
+ // src/i18n/I18nProvider.tsx
2355
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2356
+ var initialized = false;
2357
+ function getOrCreateI18n(appTranslations, fallbackLocale2) {
2358
+ if (initialized) return import_i18next2.default;
2359
+ const resources = {
2360
+ en: {
2361
+ translation: appTranslations?.en || {},
2362
+ [ssoNamespace]: defaultTranslations.en
2363
+ },
2364
+ ja: {
2365
+ translation: appTranslations?.ja || {},
2366
+ [ssoNamespace]: defaultTranslations.ja
2367
+ },
2368
+ vi: {
2369
+ translation: appTranslations?.vi || {},
2370
+ [ssoNamespace]: defaultTranslations.vi
2371
+ }
2372
+ };
2373
+ import_i18next2.default.use(import_i18next_browser_languagedetector.default).use(import_react_i18next2.initReactI18next).init({
2374
+ resources,
2375
+ fallbackLng: fallbackLocale2 || defaultLocale2,
2376
+ supportedLngs: locales,
2377
+ detection: {
2378
+ order: ["cookie", "localStorage", "navigator"],
2379
+ caches: ["cookie", "localStorage"],
2380
+ lookupCookie: "locale",
2381
+ lookupLocalStorage: "locale"
2382
+ },
2383
+ interpolation: {
2384
+ escapeValue: false
2385
+ },
2386
+ defaultNS: "translation",
2387
+ ns: ["translation", ssoNamespace],
2388
+ react: {
2389
+ useSuspense: false
2390
+ }
2391
+ });
2392
+ initialized = true;
2393
+ return import_i18next2.default;
2394
+ }
2395
+ function I18nProvider({ children, translations, fallbackLocale: fallbackLocale2 }) {
2396
+ const i18nInstance = (0, import_react14.useMemo)(
2397
+ () => getOrCreateI18n(translations, fallbackLocale2),
2398
+ [translations, fallbackLocale2]
2399
+ );
2400
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_i18next.I18nextProvider, { i18n: i18nInstance, children });
2401
+ }
2402
+
2403
+ // src/i18n/useTranslations.ts
2404
+ var import_react15 = require("react");
2405
+ var import_react_i18next3 = require("react-i18next");
2406
+ function useTranslations(namespace) {
2407
+ const { t: i18nT } = (0, import_react_i18next3.useTranslation)();
2408
+ const t = (0, import_react15.useCallback)(
2409
+ (key, values) => {
2410
+ const fullKey = namespace ? `${namespace}.${key}` : key;
2411
+ return i18nT(fullKey, values);
2412
+ },
2413
+ [i18nT, namespace]
2414
+ );
2415
+ return t;
2416
+ }
2417
+
2418
+ // src/i18n/useLocale.ts
2419
+ var import_react_i18next4 = require("react-i18next");
2420
+ function useLocale() {
2421
+ const { i18n: i18n3 } = (0, import_react_i18next4.useTranslation)();
2422
+ return i18n3.language || defaultLocale2;
2423
+ }
2424
+
2425
+ // src/components/admin/UserTable.tsx
2426
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2427
+ function UserTable({
2428
+ users,
2429
+ loading = false,
2430
+ pagination,
2431
+ sortField,
2432
+ sortOrder,
2433
+ onPageChange,
2434
+ onSortChange,
2435
+ onSearch,
2436
+ onEdit,
2437
+ onDelete,
2438
+ deleteLoading = false,
2439
+ showSearch = true,
2440
+ showActions = true
2441
+ }) {
2442
+ const { t } = useSsoTranslation();
2443
+ const columns = [
2444
+ {
2445
+ title: t("email"),
2446
+ dataIndex: "email",
2447
+ key: "email",
2448
+ sorter: true,
2449
+ sortOrder: sortField === "email" ? sortOrder === "asc" ? "ascend" : "descend" : void 0
2450
+ },
2451
+ {
2452
+ title: t("name"),
2453
+ dataIndex: "name",
2454
+ key: "name",
2455
+ sorter: true,
2456
+ sortOrder: sortField === "name" ? sortOrder === "asc" ? "ascend" : "descend" : void 0
2457
+ },
2458
+ {
2459
+ title: "SSO",
2460
+ dataIndex: "console_user_id",
2461
+ key: "sso",
2462
+ width: 100,
2463
+ render: (value) => value ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_antd4.Tag, { color: "green", children: t("ssoUser") }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_antd4.Tag, { color: "default", children: t("localUser") })
2464
+ }
2465
+ ];
2466
+ if (showActions && (onEdit || onDelete)) {
2467
+ columns.push({
2468
+ title: t("actions"),
2469
+ key: "actions",
2470
+ width: 120,
2471
+ render: (_, record) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_antd4.Space, { children: [
2472
+ onEdit && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2473
+ import_antd4.Button,
2474
+ {
2475
+ type: "text",
2476
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons4.EditOutlined, {}),
2477
+ size: "small",
2478
+ onClick: () => onEdit(record)
2479
+ }
2480
+ ),
2481
+ onDelete && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2482
+ import_antd4.Popconfirm,
2483
+ {
2484
+ title: t("confirmDelete"),
2485
+ onConfirm: () => onDelete(record),
2486
+ okText: t("yes"),
2487
+ cancelText: t("no"),
2488
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2489
+ import_antd4.Button,
2490
+ {
2491
+ type: "text",
2492
+ danger: true,
2493
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons4.DeleteOutlined, {}),
2494
+ size: "small",
2495
+ loading: deleteLoading
2496
+ }
2497
+ )
2498
+ }
2499
+ )
2500
+ ] })
2501
+ });
2502
+ }
2503
+ const handleTableChange = (paginationConfig, _filters, sorter) => {
2504
+ if (onPageChange && paginationConfig.current && paginationConfig.pageSize) {
2505
+ onPageChange(paginationConfig.current, paginationConfig.pageSize);
2506
+ }
2507
+ if (onSortChange) {
2508
+ const singleSorter = Array.isArray(sorter) ? sorter[0] : sorter;
2509
+ if (singleSorter?.field) {
2510
+ onSortChange(
2511
+ singleSorter.field,
2512
+ singleSorter.order === "ascend" ? "asc" : "desc"
2513
+ );
2514
+ } else {
2515
+ onSortChange(void 0, void 0);
2516
+ }
2517
+ }
2518
+ };
2519
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2520
+ showSearch && onSearch && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { marginBottom: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2521
+ import_antd4.Input,
2522
+ {
2523
+ placeholder: t("searchUsers"),
2524
+ prefix: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons4.SearchOutlined, {}),
2525
+ onChange: (e) => onSearch(e.target.value),
2526
+ style: { width: 300 },
2527
+ allowClear: true
2528
+ }
2529
+ ) }),
2530
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2531
+ import_antd4.Table,
2532
+ {
2533
+ columns,
2534
+ dataSource: users,
2535
+ loading,
2536
+ rowKey: "id",
2537
+ onChange: handleTableChange,
2538
+ pagination: pagination ? {
2539
+ current: pagination.current_page,
2540
+ pageSize: pagination.per_page,
2541
+ total: pagination.total,
2542
+ showSizeChanger: true,
2543
+ showTotal: (total) => t("total", { count: total })
2544
+ } : false
2545
+ }
2546
+ )
2547
+ ] });
2548
+ }
2549
+
2550
+ // src/components/admin/UserForm.tsx
2551
+ var import_antd5 = require("antd");
2552
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2553
+ function UserForm({
2554
+ initialValues,
2555
+ onSubmit,
2556
+ onCancel,
2557
+ loading = false,
2558
+ submitText
2559
+ }) {
2560
+ const { t } = useSsoTranslation();
2561
+ const [form] = import_antd5.Form.useForm();
2562
+ const handleFinish = (values) => {
2563
+ onSubmit(values);
2564
+ };
2565
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2566
+ import_antd5.Form,
2567
+ {
2568
+ form,
2569
+ layout: "vertical",
2570
+ initialValues,
2571
+ onFinish: handleFinish,
2572
+ style: { maxWidth: 600 },
2573
+ children: [
2574
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2575
+ import_antd5.Form.Item,
2576
+ {
2577
+ label: t("name"),
2578
+ name: "name",
2579
+ rules: [
2580
+ { required: true, message: t("required", { field: t("name") }) },
2581
+ { max: 255, message: t("maxLength", { field: t("name"), max: 255 }) }
2582
+ ],
2583
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_antd5.Input, {})
2584
+ }
2585
+ ),
2586
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2587
+ import_antd5.Form.Item,
2588
+ {
2589
+ label: t("email"),
2590
+ name: "email",
2591
+ rules: [
2592
+ { required: true, message: t("required", { field: t("email") }) },
2593
+ { type: "email", message: t("invalidEmail") }
2594
+ ],
2595
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_antd5.Input, { type: "email" })
2596
+ }
2597
+ ),
2598
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_antd5.Form.Item, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_antd5.Space, { children: [
2599
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_antd5.Button, { type: "primary", htmlType: "submit", loading, children: submitText || t("save") }),
2600
+ onCancel && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_antd5.Button, { onClick: onCancel, children: t("cancel") })
2601
+ ] }) })
2602
+ ]
2603
+ }
2604
+ );
2605
+ }
2606
+
2110
2607
  // src/utils/branchHeaders.ts
2111
2608
  var BRANCH_HEADERS = {
2112
2609
  BRANCH_ID: "X-Branch-Id",
@@ -2253,8 +2750,13 @@ function createRoleService(config) {
2253
2750
  * List all roles (admin)
2254
2751
  * GET /api/admin/sso/roles
2255
2752
  */
2256
- adminList: async (orgSlug) => {
2257
- return request(apiUrl, "/api/admin/sso/roles", {
2753
+ adminList: async (orgSlug, params) => {
2754
+ const searchParams = new URLSearchParams();
2755
+ if (params?.["filter[scope]"]) searchParams.set("filter[scope]", params["filter[scope]"]);
2756
+ if (params?.["filter[org_id]"]) searchParams.set("filter[org_id]", params["filter[org_id]"]);
2757
+ const query = searchParams.toString();
2758
+ const path = query ? `/api/admin/sso/roles?${query}` : "/api/admin/sso/roles";
2759
+ return request(apiUrl, path, {
2258
2760
  headers: buildHeaders(orgSlug)
2259
2761
  });
2260
2762
  },
@@ -2608,6 +3110,91 @@ var getEffectivePermissions = (roleAssignments, allRoles, orgId, branchId) => {
2608
3110
  return Array.from(permissions);
2609
3111
  };
2610
3112
 
3113
+ // src/services/userService.ts
3114
+ function createUserService(config) {
3115
+ const { apiUrl } = config;
3116
+ const basePath = "/api/admin/sso/users";
3117
+ return {
3118
+ /**
3119
+ * List users with pagination and filtering
3120
+ */
3121
+ async list(params, orgSlug) {
3122
+ const searchParams = new URLSearchParams();
3123
+ if (params?.page) searchParams.set("page", String(params.page));
3124
+ if (params?.per_page) searchParams.set("per_page", String(params.per_page));
3125
+ if (params?.["filter[search]"]) searchParams.set("filter[search]", params["filter[search]"]);
3126
+ if (params?.["filter[org_id]"]) searchParams.set("filter[org_id]", params["filter[org_id]"]);
3127
+ if (params?.sort) searchParams.set("sort", params.sort);
3128
+ const query = searchParams.toString();
3129
+ const path = query ? `${basePath}?${query}` : basePath;
3130
+ return request(apiUrl, path, {
3131
+ method: "GET",
3132
+ headers: buildHeaders(orgSlug)
3133
+ });
3134
+ },
3135
+ /**
3136
+ * Get user by ID
3137
+ */
3138
+ async get(id, orgSlug) {
3139
+ const response = await request(apiUrl, `${basePath}/${id}`, {
3140
+ method: "GET",
3141
+ headers: buildHeaders(orgSlug)
3142
+ });
3143
+ return response.data;
3144
+ },
3145
+ /**
3146
+ * Update a user
3147
+ */
3148
+ async update(id, input, orgSlug) {
3149
+ const response = await request(apiUrl, `${basePath}/${id}`, {
3150
+ method: "PUT",
3151
+ headers: buildHeaders(orgSlug),
3152
+ body: JSON.stringify(input)
3153
+ });
3154
+ return response.data;
3155
+ },
3156
+ /**
3157
+ * Delete a user
3158
+ */
3159
+ async delete(id, orgSlug) {
3160
+ await request(apiUrl, `${basePath}/${id}`, {
3161
+ method: "DELETE",
3162
+ headers: buildHeaders(orgSlug)
3163
+ });
3164
+ },
3165
+ /**
3166
+ * Search users by email (autocomplete)
3167
+ */
3168
+ async search(email, orgSlug) {
3169
+ if (email.length < 2) return [];
3170
+ const response = await request(
3171
+ apiUrl,
3172
+ `${basePath}/search?email=${encodeURIComponent(email)}`,
3173
+ {
3174
+ method: "GET",
3175
+ headers: buildHeaders(orgSlug)
3176
+ }
3177
+ );
3178
+ return response.data;
3179
+ },
3180
+ /**
3181
+ * Get user permissions breakdown
3182
+ * Shows roles, teams, and aggregated permissions for a user in context
3183
+ */
3184
+ async getPermissions(userId, orgId, branchId, orgSlug) {
3185
+ const params = new URLSearchParams();
3186
+ if (orgId) params.set("org_id", orgId);
3187
+ if (branchId) params.set("branch_id", branchId);
3188
+ const query = params.toString();
3189
+ const path = query ? `${basePath}/${userId}/permissions?${query}` : `${basePath}/${userId}/permissions`;
3190
+ return request(apiUrl, path, {
3191
+ method: "GET",
3192
+ headers: buildHeaders(orgSlug)
3193
+ });
3194
+ }
3195
+ };
3196
+ }
3197
+
2611
3198
  // src/services/ssoService.ts
2612
3199
  function getXsrfToken3() {
2613
3200
  if (typeof document === "undefined") return void 0;
@@ -2623,7 +3210,7 @@ function buildHeaders2(orgSlug) {
2623
3210
  headers["X-XSRF-TOKEN"] = decodeURIComponent(xsrfToken);
2624
3211
  }
2625
3212
  if (orgSlug) {
2626
- headers["X-Org-Slug"] = orgSlug;
3213
+ headers["X-Org-Id"] = orgSlug;
2627
3214
  }
2628
3215
  return headers;
2629
3216
  }
@@ -2991,16 +3578,20 @@ function createSsoService(config) {
2991
3578
  BranchContext,
2992
3579
  BranchGate,
2993
3580
  BranchProvider,
3581
+ I18nProvider,
2994
3582
  OrgBranchSelectorModal,
2995
3583
  OrganizationSwitcher,
2996
3584
  ProtectedRoute,
2997
3585
  SsoCallback,
2998
3586
  SsoContext,
2999
3587
  SsoProvider,
3588
+ UserForm,
3589
+ UserTable,
3000
3590
  branchCacheCreateSchema,
3001
3591
  branchCacheI18n,
3002
3592
  branchCacheSchemas,
3003
3593
  branchCacheUpdateSchema,
3594
+ changeLanguage,
3004
3595
  createAuthService,
3005
3596
  createBranchHeaderSetter,
3006
3597
  createBranchService,
@@ -3010,11 +3601,14 @@ function createSsoService(config) {
3010
3601
  createTeamService,
3011
3602
  createTokenService,
3012
3603
  createUserRoleService,
3604
+ createUserService,
3013
3605
  defaultLocale,
3606
+ defaultTranslations,
3014
3607
  fallbackLocale,
3015
3608
  getBranchCacheFieldLabel,
3016
3609
  getBranchCacheFieldPlaceholder,
3017
3610
  getBranchCacheLabel,
3611
+ getCurrentLocale,
3018
3612
  getEffectivePermissions,
3019
3613
  getMessage,
3020
3614
  getMessages,
@@ -3040,6 +3634,8 @@ function createSsoService(config) {
3040
3634
  getUserCacheFieldLabel,
3041
3635
  getUserCacheFieldPlaceholder,
3042
3636
  getUserCacheLabel,
3637
+ localeNames,
3638
+ locales,
3043
3639
  organizationCacheCreateSchema,
3044
3640
  organizationCacheI18n,
3045
3641
  organizationCacheSchemas,
@@ -3057,6 +3653,7 @@ function createSsoService(config) {
3057
3653
  roleSchemas,
3058
3654
  roleUpdateSchema,
3059
3655
  setBranchHeaders,
3656
+ ssoNamespace,
3060
3657
  ssoQueryKeys,
3061
3658
  supportedLocales,
3062
3659
  teamCacheCreateSchema,
@@ -3070,8 +3667,11 @@ function createSsoService(config) {
3070
3667
  useAuth,
3071
3668
  useBranch,
3072
3669
  useBranchGate,
3670
+ useLocale,
3073
3671
  useOrganization,
3074
3672
  useSso,
3673
+ useSsoTranslation,
3674
+ useTranslations,
3075
3675
  userCacheCreateSchema,
3076
3676
  userCacheI18n,
3077
3677
  userCacheSchemas,