@abpjs/identity 0.7.6

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.mjs ADDED
@@ -0,0 +1,1146 @@
1
+ // src/services/identity.service.ts
2
+ var IdentityService = class {
3
+ constructor(rest) {
4
+ this.rest = rest;
5
+ }
6
+ // ========================
7
+ // Role Operations
8
+ // ========================
9
+ /**
10
+ * Get all roles
11
+ * @returns Promise with paginated role response
12
+ */
13
+ getRoles() {
14
+ return this.rest.request({
15
+ method: "GET",
16
+ url: "/api/identity/roles"
17
+ });
18
+ }
19
+ /**
20
+ * Get a role by ID
21
+ * @param id - The role ID
22
+ * @returns Promise with the role item
23
+ */
24
+ getRoleById(id) {
25
+ return this.rest.request({
26
+ method: "GET",
27
+ url: `/api/identity/roles/${id}`
28
+ });
29
+ }
30
+ /**
31
+ * Delete a role
32
+ * @param id - The role ID to delete
33
+ * @returns Promise with the deleted role
34
+ */
35
+ deleteRole(id) {
36
+ return this.rest.request({
37
+ method: "DELETE",
38
+ url: `/api/identity/roles/${id}`
39
+ });
40
+ }
41
+ /**
42
+ * Create a new role
43
+ * @param body - The role data to create
44
+ * @returns Promise with the created role
45
+ */
46
+ createRole(body) {
47
+ return this.rest.request({
48
+ method: "POST",
49
+ url: "/api/identity/roles",
50
+ body
51
+ });
52
+ }
53
+ /**
54
+ * Update an existing role
55
+ * @param id - The role ID to update
56
+ * @param body - The updated role data
57
+ * @returns Promise with the updated role
58
+ */
59
+ updateRole(id, body) {
60
+ return this.rest.request({
61
+ method: "PUT",
62
+ url: `/api/identity/roles/${id}`,
63
+ body
64
+ });
65
+ }
66
+ // ========================
67
+ // User Operations
68
+ // ========================
69
+ /**
70
+ * Get users with pagination and filtering
71
+ * @param params - Query parameters for pagination and filtering
72
+ * @returns Promise with paginated user response
73
+ */
74
+ getUsers(params = {}) {
75
+ return this.rest.request({
76
+ method: "GET",
77
+ url: "/api/identity/users",
78
+ params
79
+ });
80
+ }
81
+ /**
82
+ * Get a user by ID
83
+ * @param id - The user ID
84
+ * @returns Promise with the user item
85
+ */
86
+ getUserById(id) {
87
+ return this.rest.request({
88
+ method: "GET",
89
+ url: `/api/identity/users/${id}`
90
+ });
91
+ }
92
+ /**
93
+ * Get roles assigned to a user
94
+ * @param id - The user ID
95
+ * @returns Promise with the user's roles
96
+ */
97
+ getUserRoles(id) {
98
+ return this.rest.request({
99
+ method: "GET",
100
+ url: `/api/identity/users/${id}/roles`
101
+ });
102
+ }
103
+ /**
104
+ * Delete a user
105
+ * @param id - The user ID to delete
106
+ * @returns Promise resolving when complete
107
+ */
108
+ deleteUser(id) {
109
+ return this.rest.request({
110
+ method: "DELETE",
111
+ url: `/api/identity/users/${id}`
112
+ });
113
+ }
114
+ /**
115
+ * Create a new user
116
+ * @param body - The user data to create
117
+ * @returns Promise with the created user
118
+ */
119
+ createUser(body) {
120
+ return this.rest.request({
121
+ method: "POST",
122
+ url: "/api/identity/users",
123
+ body
124
+ });
125
+ }
126
+ /**
127
+ * Update an existing user
128
+ * @param id - The user ID to update
129
+ * @param body - The updated user data
130
+ * @returns Promise with the updated user
131
+ */
132
+ updateUser(id, body) {
133
+ return this.rest.request({
134
+ method: "PUT",
135
+ url: `/api/identity/users/${id}`,
136
+ body
137
+ });
138
+ }
139
+ };
140
+
141
+ // src/hooks/useRoles.ts
142
+ import { useState, useCallback, useMemo } from "react";
143
+ import { useRestService } from "@abpjs/core";
144
+ function useRoles() {
145
+ const restService = useRestService();
146
+ const service = useMemo(() => new IdentityService(restService), [restService]);
147
+ const [roles, setRoles] = useState([]);
148
+ const [totalCount, setTotalCount] = useState(0);
149
+ const [selectedRole, setSelectedRole] = useState(null);
150
+ const [isLoading, setIsLoading] = useState(false);
151
+ const [error, setError] = useState(null);
152
+ const fetchRoles = useCallback(async () => {
153
+ setIsLoading(true);
154
+ setError(null);
155
+ try {
156
+ const response = await service.getRoles();
157
+ setRoles(response.items || []);
158
+ setTotalCount(response.totalCount || 0);
159
+ setIsLoading(false);
160
+ return { success: true };
161
+ } catch (err) {
162
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch roles";
163
+ setError(errorMessage);
164
+ setIsLoading(false);
165
+ return { success: false, error: errorMessage };
166
+ }
167
+ }, [service]);
168
+ const getRoleById = useCallback(
169
+ async (id) => {
170
+ setIsLoading(true);
171
+ setError(null);
172
+ try {
173
+ const role = await service.getRoleById(id);
174
+ setSelectedRole(role);
175
+ setIsLoading(false);
176
+ return { success: true };
177
+ } catch (err) {
178
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch role";
179
+ setError(errorMessage);
180
+ setIsLoading(false);
181
+ return { success: false, error: errorMessage };
182
+ }
183
+ },
184
+ [service]
185
+ );
186
+ const createRole = useCallback(
187
+ async (role) => {
188
+ setIsLoading(true);
189
+ setError(null);
190
+ try {
191
+ await service.createRole(role);
192
+ await fetchRoles();
193
+ return { success: true };
194
+ } catch (err) {
195
+ const errorMessage = err instanceof Error ? err.message : "Failed to create role";
196
+ setError(errorMessage);
197
+ setIsLoading(false);
198
+ return { success: false, error: errorMessage };
199
+ }
200
+ },
201
+ [service, fetchRoles]
202
+ );
203
+ const updateRole = useCallback(
204
+ async (id, role) => {
205
+ setIsLoading(true);
206
+ setError(null);
207
+ try {
208
+ await service.updateRole(id, role);
209
+ await fetchRoles();
210
+ return { success: true };
211
+ } catch (err) {
212
+ const errorMessage = err instanceof Error ? err.message : "Failed to update role";
213
+ setError(errorMessage);
214
+ setIsLoading(false);
215
+ return { success: false, error: errorMessage };
216
+ }
217
+ },
218
+ [service, fetchRoles]
219
+ );
220
+ const deleteRole = useCallback(
221
+ async (id) => {
222
+ setIsLoading(true);
223
+ setError(null);
224
+ try {
225
+ await service.deleteRole(id);
226
+ await fetchRoles();
227
+ return { success: true };
228
+ } catch (err) {
229
+ const errorMessage = err instanceof Error ? err.message : "Failed to delete role";
230
+ setError(errorMessage);
231
+ setIsLoading(false);
232
+ return { success: false, error: errorMessage };
233
+ }
234
+ },
235
+ [service, fetchRoles]
236
+ );
237
+ const reset = useCallback(() => {
238
+ setRoles([]);
239
+ setTotalCount(0);
240
+ setSelectedRole(null);
241
+ setIsLoading(false);
242
+ setError(null);
243
+ }, []);
244
+ return {
245
+ roles,
246
+ totalCount,
247
+ selectedRole,
248
+ isLoading,
249
+ error,
250
+ fetchRoles,
251
+ getRoleById,
252
+ createRole,
253
+ updateRole,
254
+ deleteRole,
255
+ setSelectedRole,
256
+ reset
257
+ };
258
+ }
259
+
260
+ // src/hooks/useUsers.ts
261
+ import { useState as useState2, useCallback as useCallback2, useMemo as useMemo2 } from "react";
262
+ import { useRestService as useRestService2 } from "@abpjs/core";
263
+ var DEFAULT_PAGE_QUERY = {
264
+ sorting: "userName",
265
+ skipCount: 0,
266
+ maxResultCount: 10
267
+ };
268
+ function useUsers() {
269
+ const restService = useRestService2();
270
+ const service = useMemo2(() => new IdentityService(restService), [restService]);
271
+ const [users, setUsers] = useState2([]);
272
+ const [totalCount, setTotalCount] = useState2(0);
273
+ const [selectedUser, setSelectedUser] = useState2(null);
274
+ const [selectedUserRoles, setSelectedUserRoles] = useState2([]);
275
+ const [isLoading, setIsLoading] = useState2(false);
276
+ const [error, setError] = useState2(null);
277
+ const [pageQuery, setPageQuery] = useState2(DEFAULT_PAGE_QUERY);
278
+ const fetchUsers = useCallback2(
279
+ async (params) => {
280
+ setIsLoading(true);
281
+ setError(null);
282
+ const queryParams = params || pageQuery;
283
+ try {
284
+ const response = await service.getUsers(queryParams);
285
+ setUsers(response.items || []);
286
+ setTotalCount(response.totalCount || 0);
287
+ setIsLoading(false);
288
+ return { success: true };
289
+ } catch (err) {
290
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch users";
291
+ setError(errorMessage);
292
+ setIsLoading(false);
293
+ return { success: false, error: errorMessage };
294
+ }
295
+ },
296
+ [service, pageQuery]
297
+ );
298
+ const getUserById = useCallback2(
299
+ async (id) => {
300
+ setIsLoading(true);
301
+ setError(null);
302
+ try {
303
+ const user = await service.getUserById(id);
304
+ setSelectedUser(user);
305
+ setIsLoading(false);
306
+ return { success: true };
307
+ } catch (err) {
308
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch user";
309
+ setError(errorMessage);
310
+ setIsLoading(false);
311
+ return { success: false, error: errorMessage };
312
+ }
313
+ },
314
+ [service]
315
+ );
316
+ const getUserRoles = useCallback2(
317
+ async (id) => {
318
+ setIsLoading(true);
319
+ setError(null);
320
+ try {
321
+ const response = await service.getUserRoles(id);
322
+ setSelectedUserRoles(response.items || []);
323
+ setIsLoading(false);
324
+ return { success: true };
325
+ } catch (err) {
326
+ const errorMessage = err instanceof Error ? err.message : "Failed to fetch user roles";
327
+ setError(errorMessage);
328
+ setIsLoading(false);
329
+ return { success: false, error: errorMessage };
330
+ }
331
+ },
332
+ [service]
333
+ );
334
+ const createUser = useCallback2(
335
+ async (user) => {
336
+ setIsLoading(true);
337
+ setError(null);
338
+ try {
339
+ await service.createUser(user);
340
+ await fetchUsers();
341
+ return { success: true };
342
+ } catch (err) {
343
+ const errorMessage = err instanceof Error ? err.message : "Failed to create user";
344
+ setError(errorMessage);
345
+ setIsLoading(false);
346
+ return { success: false, error: errorMessage };
347
+ }
348
+ },
349
+ [service, fetchUsers]
350
+ );
351
+ const updateUser = useCallback2(
352
+ async (id, user) => {
353
+ setIsLoading(true);
354
+ setError(null);
355
+ try {
356
+ await service.updateUser(id, user);
357
+ await fetchUsers();
358
+ return { success: true };
359
+ } catch (err) {
360
+ const errorMessage = err instanceof Error ? err.message : "Failed to update user";
361
+ setError(errorMessage);
362
+ setIsLoading(false);
363
+ return { success: false, error: errorMessage };
364
+ }
365
+ },
366
+ [service, fetchUsers]
367
+ );
368
+ const deleteUser = useCallback2(
369
+ async (id) => {
370
+ setIsLoading(true);
371
+ setError(null);
372
+ try {
373
+ await service.deleteUser(id);
374
+ await fetchUsers();
375
+ return { success: true };
376
+ } catch (err) {
377
+ const errorMessage = err instanceof Error ? err.message : "Failed to delete user";
378
+ setError(errorMessage);
379
+ setIsLoading(false);
380
+ return { success: false, error: errorMessage };
381
+ }
382
+ },
383
+ [service, fetchUsers]
384
+ );
385
+ const reset = useCallback2(() => {
386
+ setUsers([]);
387
+ setTotalCount(0);
388
+ setSelectedUser(null);
389
+ setSelectedUserRoles([]);
390
+ setIsLoading(false);
391
+ setError(null);
392
+ setPageQuery(DEFAULT_PAGE_QUERY);
393
+ }, []);
394
+ return {
395
+ users,
396
+ totalCount,
397
+ selectedUser,
398
+ selectedUserRoles,
399
+ isLoading,
400
+ error,
401
+ pageQuery,
402
+ fetchUsers,
403
+ getUserById,
404
+ getUserRoles,
405
+ createUser,
406
+ updateUser,
407
+ deleteUser,
408
+ setSelectedUser,
409
+ setPageQuery,
410
+ reset
411
+ };
412
+ }
413
+
414
+ // src/hooks/useIdentity.ts
415
+ import { useCallback as useCallback3, useMemo as useMemo3 } from "react";
416
+ function useIdentity() {
417
+ const rolesHook = useRoles();
418
+ const usersHook = useUsers();
419
+ const isLoading = useMemo3(
420
+ () => rolesHook.isLoading || usersHook.isLoading,
421
+ [rolesHook.isLoading, usersHook.isLoading]
422
+ );
423
+ const error = useMemo3(
424
+ () => rolesHook.error || usersHook.error,
425
+ [rolesHook.error, usersHook.error]
426
+ );
427
+ const resetAll = useCallback3(() => {
428
+ rolesHook.reset();
429
+ usersHook.reset();
430
+ }, [rolesHook, usersHook]);
431
+ return {
432
+ roles: rolesHook,
433
+ users: usersHook,
434
+ isLoading,
435
+ error,
436
+ resetAll
437
+ };
438
+ }
439
+
440
+ // src/components/Roles/RolesComponent.tsx
441
+ import { useEffect, useState as useState3, useCallback as useCallback4 } from "react";
442
+ import { useLocalization } from "@abpjs/core";
443
+ import { Modal, useConfirmation, Toaster, Alert, Button, Checkbox, FormField } from "@abpjs/theme-shared";
444
+ import { PermissionManagementModal } from "@abpjs/permission-management";
445
+ import {
446
+ Box,
447
+ Flex,
448
+ Input,
449
+ Table,
450
+ Spinner,
451
+ VStack,
452
+ Menu,
453
+ Text
454
+ } from "@chakra-ui/react";
455
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
456
+ var DEFAULT_FORM_STATE = {
457
+ name: "",
458
+ isDefault: false,
459
+ isPublic: false
460
+ };
461
+ function RolesComponent({
462
+ onRoleCreated,
463
+ onRoleUpdated,
464
+ onRoleDeleted
465
+ }) {
466
+ const { t } = useLocalization();
467
+ const confirmation = useConfirmation();
468
+ const {
469
+ roles,
470
+ selectedRole,
471
+ isLoading,
472
+ error,
473
+ fetchRoles,
474
+ getRoleById,
475
+ createRole,
476
+ updateRole,
477
+ deleteRole,
478
+ setSelectedRole
479
+ } = useRoles();
480
+ const [isModalOpen, setIsModalOpen] = useState3(false);
481
+ const [formState, setFormState] = useState3(DEFAULT_FORM_STATE);
482
+ const [isSubmitting, setIsSubmitting] = useState3(false);
483
+ const [isPermissionModalOpen, setIsPermissionModalOpen] = useState3(false);
484
+ const [permissionProviderKey, setPermissionProviderKey] = useState3("");
485
+ const [searchTerm, setSearchTerm] = useState3("");
486
+ useEffect(() => {
487
+ fetchRoles();
488
+ }, [fetchRoles]);
489
+ const filteredRoles = roles.filter(
490
+ (role) => !searchTerm || role.name.toLowerCase().includes(searchTerm.toLowerCase())
491
+ );
492
+ const handleAdd = useCallback4(() => {
493
+ setSelectedRole(null);
494
+ setFormState(DEFAULT_FORM_STATE);
495
+ setIsModalOpen(true);
496
+ }, [setSelectedRole]);
497
+ const handleEdit = useCallback4(
498
+ async (id) => {
499
+ const result = await getRoleById(id);
500
+ if (result.success && selectedRole) {
501
+ setFormState({
502
+ name: selectedRole.name || "",
503
+ isDefault: selectedRole.isDefault || false,
504
+ isPublic: selectedRole.isPublic || false
505
+ });
506
+ setIsModalOpen(true);
507
+ }
508
+ },
509
+ [getRoleById, selectedRole]
510
+ );
511
+ useEffect(() => {
512
+ if (selectedRole) {
513
+ setFormState({
514
+ name: selectedRole.name || "",
515
+ isDefault: selectedRole.isDefault || false,
516
+ isPublic: selectedRole.isPublic || false
517
+ });
518
+ }
519
+ }, [selectedRole]);
520
+ const handleDelete = useCallback4(
521
+ async (id, name) => {
522
+ const status = await confirmation.warn(
523
+ t("AbpIdentity::RoleDeletionConfirmationMessage", name),
524
+ t("AbpIdentity::AreYouSure")
525
+ );
526
+ if (status === Toaster.Status.confirm) {
527
+ const result = await deleteRole(id);
528
+ if (result.success) {
529
+ onRoleDeleted?.(id);
530
+ }
531
+ }
532
+ },
533
+ [confirmation, t, deleteRole, onRoleDeleted]
534
+ );
535
+ const handleOpenPermissions = useCallback4((roleName) => {
536
+ setPermissionProviderKey(roleName);
537
+ setIsPermissionModalOpen(true);
538
+ }, []);
539
+ const handleSubmit = useCallback4(async () => {
540
+ if (!formState.name.trim()) return;
541
+ setIsSubmitting(true);
542
+ const roleData = {
543
+ name: formState.name.trim(),
544
+ isDefault: formState.isDefault,
545
+ isPublic: formState.isPublic
546
+ };
547
+ let result;
548
+ if (selectedRole?.id) {
549
+ result = await updateRole(selectedRole.id, roleData);
550
+ if (result.success) {
551
+ onRoleUpdated?.({ ...selectedRole, ...roleData });
552
+ }
553
+ } else {
554
+ result = await createRole(roleData);
555
+ if (result.success) {
556
+ onRoleCreated?.({ ...roleData, id: "", isStatic: false, concurrencyStamp: "" });
557
+ }
558
+ }
559
+ setIsSubmitting(false);
560
+ if (result.success) {
561
+ setIsModalOpen(false);
562
+ setFormState(DEFAULT_FORM_STATE);
563
+ setSelectedRole(null);
564
+ }
565
+ }, [formState, selectedRole, updateRole, createRole, onRoleCreated, onRoleUpdated, setSelectedRole]);
566
+ const handleModalClose = useCallback4(() => {
567
+ setIsModalOpen(false);
568
+ setFormState(DEFAULT_FORM_STATE);
569
+ setSelectedRole(null);
570
+ }, [setSelectedRole]);
571
+ const handleInputChange = useCallback4(
572
+ (field, value) => {
573
+ setFormState((prev) => ({ ...prev, [field]: value }));
574
+ },
575
+ []
576
+ );
577
+ return /* @__PURE__ */ jsxs(Box, { id: "identity-roles-wrapper", className: "card", p: 4, children: [
578
+ /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", mb: 4, children: [
579
+ /* @__PURE__ */ jsx(Text, { fontSize: "xl", fontWeight: "bold", children: t("AbpIdentity::Roles") }),
580
+ /* @__PURE__ */ jsx(Button, { colorPalette: "blue", onClick: handleAdd, children: t("AbpIdentity::NewRole") })
581
+ ] }),
582
+ /* @__PURE__ */ jsx(Box, { mb: 4, children: /* @__PURE__ */ jsx(
583
+ Input,
584
+ {
585
+ placeholder: t("AbpIdentity::Search"),
586
+ value: searchTerm,
587
+ onChange: (e) => setSearchTerm(e.target.value),
588
+ maxW: "300px"
589
+ }
590
+ ) }),
591
+ error && /* @__PURE__ */ jsx(Alert, { status: "error", mb: 4, children: error }),
592
+ isLoading && roles.length === 0 && /* @__PURE__ */ jsx(Flex, { justify: "center", py: 8, children: /* @__PURE__ */ jsx(Spinner, { size: "lg" }) }),
593
+ roles.length > 0 && /* @__PURE__ */ jsxs(Table.Root, { variant: "outline", children: [
594
+ /* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
595
+ /* @__PURE__ */ jsx(Table.ColumnHeader, { children: t("AbpIdentity::Actions") }),
596
+ /* @__PURE__ */ jsx(Table.ColumnHeader, { children: t("AbpIdentity::RoleName") })
597
+ ] }) }),
598
+ /* @__PURE__ */ jsx(Table.Body, { children: filteredRoles.map((role) => /* @__PURE__ */ jsxs(Table.Row, { children: [
599
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Menu.Root, { children: [
600
+ /* @__PURE__ */ jsx(Menu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "sm", colorPalette: "blue", children: t("AbpIdentity::Actions") }) }),
601
+ /* @__PURE__ */ jsx(Menu.Positioner, { children: /* @__PURE__ */ jsxs(Menu.Content, { children: [
602
+ /* @__PURE__ */ jsx(Menu.Item, { value: "edit", onClick: () => handleEdit(role.id), children: t("AbpIdentity::Edit") }),
603
+ /* @__PURE__ */ jsx(Menu.Item, { value: "permissions", onClick: () => handleOpenPermissions(role.name), children: t("AbpIdentity::Permissions") }),
604
+ !role.isStatic && /* @__PURE__ */ jsx(
605
+ Menu.Item,
606
+ {
607
+ value: "delete",
608
+ color: "red.500",
609
+ onClick: () => handleDelete(role.id, role.name),
610
+ children: t("AbpIdentity::Delete")
611
+ }
612
+ )
613
+ ] }) })
614
+ ] }) }),
615
+ /* @__PURE__ */ jsx(Table.Cell, { children: role.name })
616
+ ] }, role.id)) })
617
+ ] }),
618
+ !isLoading && roles.length === 0 && /* @__PURE__ */ jsx(Text, { textAlign: "center", color: "gray.500", py: 8, children: t("AbpIdentity::NoRolesFound") }),
619
+ /* @__PURE__ */ jsx(
620
+ Modal,
621
+ {
622
+ visible: isModalOpen,
623
+ onVisibleChange: setIsModalOpen,
624
+ header: selectedRole?.id ? t("AbpIdentity::Edit") : t("AbpIdentity::NewRole"),
625
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
626
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleModalClose, disabled: isSubmitting, children: t("AbpIdentity::Cancel") }),
627
+ /* @__PURE__ */ jsx(
628
+ Button,
629
+ {
630
+ colorPalette: "blue",
631
+ onClick: handleSubmit,
632
+ loading: isSubmitting,
633
+ disabled: !formState.name.trim(),
634
+ children: t("AbpIdentity::Save")
635
+ }
636
+ )
637
+ ] }),
638
+ children: /* @__PURE__ */ jsxs(VStack, { gap: 4, align: "stretch", children: [
639
+ /* @__PURE__ */ jsx(FormField, { label: t("AbpIdentity::RoleName"), required: true, children: /* @__PURE__ */ jsx(
640
+ Input,
641
+ {
642
+ value: formState.name,
643
+ onChange: (e) => handleInputChange("name", e.target.value),
644
+ maxLength: 256,
645
+ placeholder: t("AbpIdentity::RoleName")
646
+ }
647
+ ) }),
648
+ /* @__PURE__ */ jsx(
649
+ Checkbox,
650
+ {
651
+ checked: formState.isDefault,
652
+ onChange: (e) => handleInputChange("isDefault", e.target.checked),
653
+ children: t("AbpIdentity::DisplayName:IsDefault")
654
+ }
655
+ ),
656
+ /* @__PURE__ */ jsx(
657
+ Checkbox,
658
+ {
659
+ checked: formState.isPublic,
660
+ onChange: (e) => handleInputChange("isPublic", e.target.checked),
661
+ children: t("AbpIdentity::DisplayName:IsPublic")
662
+ }
663
+ )
664
+ ] })
665
+ }
666
+ ),
667
+ /* @__PURE__ */ jsx(
668
+ PermissionManagementModal,
669
+ {
670
+ visible: isPermissionModalOpen,
671
+ onVisibleChange: setIsPermissionModalOpen,
672
+ providerName: "R",
673
+ providerKey: permissionProviderKey
674
+ }
675
+ )
676
+ ] });
677
+ }
678
+
679
+ // src/components/Users/UsersComponent.tsx
680
+ import { useEffect as useEffect2, useState as useState4, useCallback as useCallback5, useMemo as useMemo4 } from "react";
681
+ import { useLocalization as useLocalization2 } from "@abpjs/core";
682
+ import { Modal as Modal2, useConfirmation as useConfirmation2, Toaster as Toaster2, Alert as Alert2, Button as Button2, Checkbox as Checkbox2, FormField as FormField2 } from "@abpjs/theme-shared";
683
+ import { PermissionManagementModal as PermissionManagementModal2 } from "@abpjs/permission-management";
684
+ import {
685
+ Box as Box2,
686
+ Flex as Flex2,
687
+ Input as Input2,
688
+ Table as Table2,
689
+ Spinner as Spinner2,
690
+ VStack as VStack2,
691
+ Menu as Menu2,
692
+ Text as Text2,
693
+ Tabs,
694
+ SimpleGrid
695
+ } from "@chakra-ui/react";
696
+ import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
697
+ var DEFAULT_FORM_STATE2 = {
698
+ userName: "",
699
+ name: "",
700
+ surname: "",
701
+ email: "",
702
+ phoneNumber: "",
703
+ password: "",
704
+ lockoutEnabled: true,
705
+ twoFactorEnabled: true,
706
+ roleNames: []
707
+ };
708
+ function UsersComponent({
709
+ onUserCreated,
710
+ onUserUpdated,
711
+ onUserDeleted
712
+ }) {
713
+ const { t } = useLocalization2();
714
+ const confirmation = useConfirmation2();
715
+ const {
716
+ users,
717
+ totalCount,
718
+ selectedUser,
719
+ selectedUserRoles,
720
+ isLoading,
721
+ error,
722
+ pageQuery,
723
+ fetchUsers,
724
+ getUserById,
725
+ getUserRoles,
726
+ createUser,
727
+ updateUser,
728
+ deleteUser,
729
+ setSelectedUser,
730
+ setPageQuery
731
+ } = useUsers();
732
+ const { roles, fetchRoles } = useRoles();
733
+ const [isModalOpen, setIsModalOpen] = useState4(false);
734
+ const [formState, setFormState] = useState4(DEFAULT_FORM_STATE2);
735
+ const [isSubmitting, setIsSubmitting] = useState4(false);
736
+ const [isPermissionModalOpen, setIsPermissionModalOpen] = useState4(false);
737
+ const [permissionProviderKey, setPermissionProviderKey] = useState4("");
738
+ const [searchTerm, setSearchTerm] = useState4("");
739
+ const [debouncedSearchTerm, setDebouncedSearchTerm] = useState4("");
740
+ useEffect2(() => {
741
+ fetchRoles();
742
+ fetchUsers();
743
+ }, [fetchRoles, fetchUsers]);
744
+ useEffect2(() => {
745
+ const timer = setTimeout(() => {
746
+ setDebouncedSearchTerm(searchTerm);
747
+ }, 300);
748
+ return () => clearTimeout(timer);
749
+ }, [searchTerm]);
750
+ useEffect2(() => {
751
+ const newQuery = {
752
+ ...pageQuery,
753
+ filter: debouncedSearchTerm || void 0,
754
+ skipCount: 0
755
+ };
756
+ setPageQuery(newQuery);
757
+ fetchUsers(newQuery);
758
+ }, [debouncedSearchTerm]);
759
+ const selectedRoleNames = useMemo4(() => {
760
+ return selectedUserRoles.map((role) => role.name);
761
+ }, [selectedUserRoles]);
762
+ const handleAdd = useCallback5(() => {
763
+ setSelectedUser(null);
764
+ setFormState(DEFAULT_FORM_STATE2);
765
+ setIsModalOpen(true);
766
+ }, [setSelectedUser]);
767
+ const handleEdit = useCallback5(
768
+ async (id) => {
769
+ await Promise.all([getUserById(id), getUserRoles(id)]);
770
+ setIsModalOpen(true);
771
+ },
772
+ [getUserById, getUserRoles]
773
+ );
774
+ useEffect2(() => {
775
+ if (selectedUser) {
776
+ setFormState({
777
+ userName: selectedUser.userName || "",
778
+ name: selectedUser.name || "",
779
+ surname: selectedUser.surname || "",
780
+ email: selectedUser.email || "",
781
+ phoneNumber: selectedUser.phoneNumber || "",
782
+ password: "",
783
+ lockoutEnabled: selectedUser.lockoutEnabled ?? true,
784
+ twoFactorEnabled: selectedUser.twoFactorEnabled ?? true,
785
+ roleNames: selectedRoleNames
786
+ });
787
+ }
788
+ }, [selectedUser, selectedRoleNames]);
789
+ const handleDelete = useCallback5(
790
+ async (id, userName) => {
791
+ const status = await confirmation.warn(
792
+ t("AbpIdentity::UserDeletionConfirmationMessage", userName),
793
+ t("AbpIdentity::AreYouSure")
794
+ );
795
+ if (status === Toaster2.Status.confirm) {
796
+ const result = await deleteUser(id);
797
+ if (result.success) {
798
+ onUserDeleted?.(id);
799
+ }
800
+ }
801
+ },
802
+ [confirmation, t, deleteUser, onUserDeleted]
803
+ );
804
+ const handleOpenPermissions = useCallback5((userId) => {
805
+ setPermissionProviderKey(userId);
806
+ setIsPermissionModalOpen(true);
807
+ }, []);
808
+ const handleSubmit = useCallback5(async () => {
809
+ if (!formState.userName.trim() || !formState.email.trim()) return;
810
+ if (!selectedUser?.id && !formState.password) return;
811
+ setIsSubmitting(true);
812
+ const userData = {
813
+ userName: formState.userName.trim(),
814
+ name: formState.name.trim(),
815
+ surname: formState.surname.trim(),
816
+ email: formState.email.trim(),
817
+ phoneNumber: formState.phoneNumber.trim(),
818
+ password: formState.password,
819
+ lockoutEnabled: formState.lockoutEnabled,
820
+ twoFactorEnabled: formState.twoFactorEnabled,
821
+ roleNames: formState.roleNames
822
+ };
823
+ let result;
824
+ if (selectedUser?.id) {
825
+ result = await updateUser(selectedUser.id, userData);
826
+ if (result.success) {
827
+ onUserUpdated?.({
828
+ ...selectedUser,
829
+ ...userData
830
+ });
831
+ }
832
+ } else {
833
+ result = await createUser(userData);
834
+ if (result.success) {
835
+ onUserCreated?.({
836
+ ...userData,
837
+ id: "",
838
+ tenantId: "",
839
+ emailConfirmed: false,
840
+ phoneNumberConfirmed: false,
841
+ isLockedOut: false,
842
+ concurrencyStamp: ""
843
+ });
844
+ }
845
+ }
846
+ setIsSubmitting(false);
847
+ if (result.success) {
848
+ setIsModalOpen(false);
849
+ setFormState(DEFAULT_FORM_STATE2);
850
+ setSelectedUser(null);
851
+ }
852
+ }, [formState, selectedUser, updateUser, createUser, onUserCreated, onUserUpdated, setSelectedUser]);
853
+ const handleModalClose = useCallback5(() => {
854
+ setIsModalOpen(false);
855
+ setFormState(DEFAULT_FORM_STATE2);
856
+ setSelectedUser(null);
857
+ }, [setSelectedUser]);
858
+ const handleInputChange = useCallback5(
859
+ (field, value) => {
860
+ setFormState((prev) => ({ ...prev, [field]: value }));
861
+ },
862
+ []
863
+ );
864
+ const handleRoleChange = useCallback5((roleName, checked) => {
865
+ setFormState((prev) => ({
866
+ ...prev,
867
+ roleNames: checked ? [...prev.roleNames, roleName] : prev.roleNames.filter((name) => name !== roleName)
868
+ }));
869
+ }, []);
870
+ const handlePageChange = useCallback5(
871
+ (newSkipCount) => {
872
+ const newQuery = { ...pageQuery, skipCount: newSkipCount };
873
+ setPageQuery(newQuery);
874
+ fetchUsers(newQuery);
875
+ },
876
+ [pageQuery, setPageQuery, fetchUsers]
877
+ );
878
+ return /* @__PURE__ */ jsxs2(Box2, { id: "identity-users-wrapper", className: "card", p: 4, children: [
879
+ /* @__PURE__ */ jsxs2(Flex2, { justify: "space-between", align: "center", mb: 4, children: [
880
+ /* @__PURE__ */ jsx2(Text2, { fontSize: "xl", fontWeight: "bold", children: t("AbpIdentity::Users") }),
881
+ /* @__PURE__ */ jsx2(Button2, { colorPalette: "blue", onClick: handleAdd, children: t("AbpIdentity::NewUser") })
882
+ ] }),
883
+ /* @__PURE__ */ jsx2(Box2, { mb: 4, children: /* @__PURE__ */ jsx2(
884
+ Input2,
885
+ {
886
+ placeholder: t("AbpIdentity::Search"),
887
+ value: searchTerm,
888
+ onChange: (e) => setSearchTerm(e.target.value),
889
+ maxW: "300px"
890
+ }
891
+ ) }),
892
+ error && /* @__PURE__ */ jsx2(Alert2, { status: "error", mb: 4, children: error }),
893
+ isLoading && users.length === 0 && /* @__PURE__ */ jsx2(Flex2, { justify: "center", py: 8, children: /* @__PURE__ */ jsx2(Spinner2, { size: "lg" }) }),
894
+ users.length > 0 && /* @__PURE__ */ jsxs2(Fragment2, { children: [
895
+ /* @__PURE__ */ jsxs2(Table2.Root, { variant: "outline", children: [
896
+ /* @__PURE__ */ jsx2(Table2.Header, { children: /* @__PURE__ */ jsxs2(Table2.Row, { children: [
897
+ /* @__PURE__ */ jsx2(Table2.ColumnHeader, { children: t("AbpIdentity::Actions") }),
898
+ /* @__PURE__ */ jsx2(Table2.ColumnHeader, { children: t("AbpIdentity::UserName") }),
899
+ /* @__PURE__ */ jsx2(Table2.ColumnHeader, { children: t("AbpIdentity::EmailAddress") }),
900
+ /* @__PURE__ */ jsx2(Table2.ColumnHeader, { children: t("AbpIdentity::PhoneNumber") })
901
+ ] }) }),
902
+ /* @__PURE__ */ jsx2(Table2.Body, { children: users.map((user) => /* @__PURE__ */ jsxs2(Table2.Row, { children: [
903
+ /* @__PURE__ */ jsx2(Table2.Cell, { children: /* @__PURE__ */ jsxs2(Menu2.Root, { children: [
904
+ /* @__PURE__ */ jsx2(Menu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx2(Button2, { size: "sm", colorPalette: "blue", children: t("AbpIdentity::Actions") }) }),
905
+ /* @__PURE__ */ jsx2(Menu2.Positioner, { children: /* @__PURE__ */ jsxs2(Menu2.Content, { children: [
906
+ /* @__PURE__ */ jsx2(Menu2.Item, { value: "edit", onClick: () => handleEdit(user.id), children: t("AbpIdentity::Edit") }),
907
+ /* @__PURE__ */ jsx2(Menu2.Item, { value: "permissions", onClick: () => handleOpenPermissions(user.id), children: t("AbpIdentity::Permissions") }),
908
+ /* @__PURE__ */ jsx2(
909
+ Menu2.Item,
910
+ {
911
+ value: "delete",
912
+ color: "red.500",
913
+ onClick: () => handleDelete(user.id, user.userName),
914
+ children: t("AbpIdentity::Delete")
915
+ }
916
+ )
917
+ ] }) })
918
+ ] }) }),
919
+ /* @__PURE__ */ jsx2(Table2.Cell, { children: user.userName }),
920
+ /* @__PURE__ */ jsx2(Table2.Cell, { children: user.email }),
921
+ /* @__PURE__ */ jsx2(Table2.Cell, { children: user.phoneNumber })
922
+ ] }, user.id)) })
923
+ ] }),
924
+ /* @__PURE__ */ jsxs2(Flex2, { justify: "space-between", align: "center", mt: 4, children: [
925
+ /* @__PURE__ */ jsxs2(Text2, { color: "gray.600", children: [
926
+ t("AbpIdentity::TotalCount"),
927
+ ": ",
928
+ totalCount
929
+ ] }),
930
+ /* @__PURE__ */ jsxs2(Flex2, { gap: 2, children: [
931
+ /* @__PURE__ */ jsx2(
932
+ Button2,
933
+ {
934
+ size: "sm",
935
+ disabled: (pageQuery.skipCount || 0) === 0,
936
+ onClick: () => handlePageChange(
937
+ Math.max(0, (pageQuery.skipCount || 0) - (pageQuery.maxResultCount || 10))
938
+ ),
939
+ children: t("AbpIdentity::Previous")
940
+ }
941
+ ),
942
+ /* @__PURE__ */ jsx2(
943
+ Button2,
944
+ {
945
+ size: "sm",
946
+ disabled: (pageQuery.skipCount || 0) + (pageQuery.maxResultCount || 10) >= totalCount,
947
+ onClick: () => handlePageChange((pageQuery.skipCount || 0) + (pageQuery.maxResultCount || 10)),
948
+ children: t("AbpIdentity::Next")
949
+ }
950
+ )
951
+ ] })
952
+ ] })
953
+ ] }),
954
+ !isLoading && users.length === 0 && /* @__PURE__ */ jsx2(Text2, { textAlign: "center", color: "gray.500", py: 8, children: t("AbpIdentity::NoUsersFound") }),
955
+ /* @__PURE__ */ jsx2(
956
+ Modal2,
957
+ {
958
+ visible: isModalOpen,
959
+ onVisibleChange: setIsModalOpen,
960
+ size: "lg",
961
+ header: selectedUser?.id ? t("AbpIdentity::Edit") : t("AbpIdentity::NewUser"),
962
+ footer: /* @__PURE__ */ jsxs2(Fragment2, { children: [
963
+ /* @__PURE__ */ jsx2(Button2, { variant: "outline", onClick: handleModalClose, disabled: isSubmitting, children: t("AbpIdentity::Cancel") }),
964
+ /* @__PURE__ */ jsx2(
965
+ Button2,
966
+ {
967
+ colorPalette: "blue",
968
+ onClick: handleSubmit,
969
+ loading: isSubmitting,
970
+ disabled: !formState.userName.trim() || !formState.email.trim() || !selectedUser?.id && !formState.password,
971
+ children: t("AbpIdentity::Save")
972
+ }
973
+ )
974
+ ] }),
975
+ children: /* @__PURE__ */ jsxs2(Tabs.Root, { defaultValue: "info", children: [
976
+ /* @__PURE__ */ jsxs2(Tabs.List, { children: [
977
+ /* @__PURE__ */ jsx2(Tabs.Trigger, { value: "info", children: t("AbpIdentity::UserInformations") }),
978
+ /* @__PURE__ */ jsx2(Tabs.Trigger, { value: "roles", children: t("AbpIdentity::Roles") })
979
+ ] }),
980
+ /* @__PURE__ */ jsx2(Tabs.Content, { value: "info", children: /* @__PURE__ */ jsxs2(VStack2, { gap: 4, align: "stretch", pt: 4, children: [
981
+ /* @__PURE__ */ jsx2(FormField2, { label: t("AbpIdentity::UserName"), required: true, children: /* @__PURE__ */ jsx2(
982
+ Input2,
983
+ {
984
+ value: formState.userName,
985
+ onChange: (e) => handleInputChange("userName", e.target.value),
986
+ maxLength: 256
987
+ }
988
+ ) }),
989
+ /* @__PURE__ */ jsxs2(SimpleGrid, { columns: 2, gap: 4, children: [
990
+ /* @__PURE__ */ jsx2(FormField2, { label: t("AbpIdentity::Name"), children: /* @__PURE__ */ jsx2(
991
+ Input2,
992
+ {
993
+ value: formState.name,
994
+ onChange: (e) => handleInputChange("name", e.target.value),
995
+ maxLength: 64
996
+ }
997
+ ) }),
998
+ /* @__PURE__ */ jsx2(FormField2, { label: t("AbpIdentity::DisplayName:Surname"), children: /* @__PURE__ */ jsx2(
999
+ Input2,
1000
+ {
1001
+ value: formState.surname,
1002
+ onChange: (e) => handleInputChange("surname", e.target.value),
1003
+ maxLength: 64
1004
+ }
1005
+ ) })
1006
+ ] }),
1007
+ /* @__PURE__ */ jsx2(FormField2, { label: t("AbpIdentity::Password"), required: !selectedUser?.id, children: /* @__PURE__ */ jsx2(
1008
+ Input2,
1009
+ {
1010
+ type: "password",
1011
+ value: formState.password,
1012
+ onChange: (e) => handleInputChange("password", e.target.value),
1013
+ autoComplete: "new-password",
1014
+ maxLength: 32,
1015
+ placeholder: selectedUser?.id ? t("AbpIdentity::LeaveBlankToKeepCurrent") : ""
1016
+ }
1017
+ ) }),
1018
+ /* @__PURE__ */ jsx2(FormField2, { label: t("AbpIdentity::EmailAddress"), required: true, children: /* @__PURE__ */ jsx2(
1019
+ Input2,
1020
+ {
1021
+ type: "email",
1022
+ value: formState.email,
1023
+ onChange: (e) => handleInputChange("email", e.target.value),
1024
+ maxLength: 256
1025
+ }
1026
+ ) }),
1027
+ /* @__PURE__ */ jsx2(FormField2, { label: t("AbpIdentity::PhoneNumber"), children: /* @__PURE__ */ jsx2(
1028
+ Input2,
1029
+ {
1030
+ value: formState.phoneNumber,
1031
+ onChange: (e) => handleInputChange("phoneNumber", e.target.value),
1032
+ maxLength: 16
1033
+ }
1034
+ ) }),
1035
+ /* @__PURE__ */ jsx2(
1036
+ Checkbox2,
1037
+ {
1038
+ checked: formState.lockoutEnabled,
1039
+ onChange: (e) => handleInputChange("lockoutEnabled", e.target.checked),
1040
+ children: t("AbpIdentity::DisplayName:LockoutEnabled")
1041
+ }
1042
+ ),
1043
+ /* @__PURE__ */ jsx2(
1044
+ Checkbox2,
1045
+ {
1046
+ checked: formState.twoFactorEnabled,
1047
+ onChange: (e) => handleInputChange("twoFactorEnabled", e.target.checked),
1048
+ children: t("AbpIdentity::DisplayName:TwoFactorEnabled")
1049
+ }
1050
+ )
1051
+ ] }) }),
1052
+ /* @__PURE__ */ jsx2(Tabs.Content, { value: "roles", children: /* @__PURE__ */ jsxs2(VStack2, { gap: 2, align: "stretch", pt: 4, children: [
1053
+ roles.map((role) => /* @__PURE__ */ jsx2(
1054
+ Checkbox2,
1055
+ {
1056
+ checked: formState.roleNames.includes(role.name),
1057
+ onChange: (e) => handleRoleChange(role.name, e.target.checked),
1058
+ children: role.name
1059
+ },
1060
+ role.id
1061
+ )),
1062
+ roles.length === 0 && /* @__PURE__ */ jsx2(Text2, { color: "gray.500", children: t("AbpIdentity::NoRolesFound") })
1063
+ ] }) })
1064
+ ] })
1065
+ }
1066
+ ),
1067
+ /* @__PURE__ */ jsx2(
1068
+ PermissionManagementModal2,
1069
+ {
1070
+ visible: isPermissionModalOpen,
1071
+ onVisibleChange: setIsPermissionModalOpen,
1072
+ providerName: "U",
1073
+ providerKey: permissionProviderKey
1074
+ }
1075
+ )
1076
+ ] });
1077
+ }
1078
+
1079
+ // src/constants/routes.ts
1080
+ import { eLayoutType } from "@abpjs/core";
1081
+ var IDENTITY_ROUTES = [
1082
+ {
1083
+ name: "AbpUiNavigation::Menu:Administration",
1084
+ path: "",
1085
+ order: 1,
1086
+ wrapper: true
1087
+ },
1088
+ {
1089
+ name: "AbpIdentity::Menu:IdentityManagement",
1090
+ path: "identity",
1091
+ order: 1,
1092
+ parentName: "AbpUiNavigation::Menu:Administration",
1093
+ layout: eLayoutType.application,
1094
+ children: [
1095
+ {
1096
+ path: "roles",
1097
+ name: "AbpIdentity::Roles",
1098
+ order: 2,
1099
+ requiredPolicy: "AbpIdentity.Roles"
1100
+ },
1101
+ {
1102
+ path: "users",
1103
+ name: "AbpIdentity::Users",
1104
+ order: 1,
1105
+ requiredPolicy: "AbpIdentity.Users"
1106
+ }
1107
+ ]
1108
+ }
1109
+ ];
1110
+ var IDENTITY_ROUTE_PATHS = {
1111
+ /** Base path for identity module */
1112
+ BASE: "/identity",
1113
+ /** Roles management path */
1114
+ ROLES: "/identity/roles",
1115
+ /** Users management path */
1116
+ USERS: "/identity/users"
1117
+ };
1118
+ var IDENTITY_POLICIES = {
1119
+ /** Policy for roles management */
1120
+ ROLES: "AbpIdentity.Roles",
1121
+ /** Policy for users management */
1122
+ USERS: "AbpIdentity.Users",
1123
+ /** Policy for creating users */
1124
+ USERS_CREATE: "AbpIdentity.Users.Create",
1125
+ /** Policy for updating users */
1126
+ USERS_UPDATE: "AbpIdentity.Users.Update",
1127
+ /** Policy for deleting users */
1128
+ USERS_DELETE: "AbpIdentity.Users.Delete",
1129
+ /** Policy for creating roles */
1130
+ ROLES_CREATE: "AbpIdentity.Roles.Create",
1131
+ /** Policy for updating roles */
1132
+ ROLES_UPDATE: "AbpIdentity.Roles.Update",
1133
+ /** Policy for deleting roles */
1134
+ ROLES_DELETE: "AbpIdentity.Roles.Delete"
1135
+ };
1136
+ export {
1137
+ IDENTITY_POLICIES,
1138
+ IDENTITY_ROUTES,
1139
+ IDENTITY_ROUTE_PATHS,
1140
+ IdentityService,
1141
+ RolesComponent,
1142
+ UsersComponent,
1143
+ useIdentity,
1144
+ useRoles,
1145
+ useUsers
1146
+ };