@memberjunction/ng-explorer-settings 2.50.0 → 2.52.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.md +89 -1
- package/dist/lib/application-management/application-management.component.d.ts +59 -0
- package/dist/lib/application-management/application-management.component.d.ts.map +1 -0
- package/dist/lib/application-management/application-management.component.js +540 -0
- package/dist/lib/application-management/application-management.component.js.map +1 -0
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts +71 -0
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -0
- package/dist/lib/entity-permissions/entity-permissions.component.js +667 -0
- package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -0
- package/dist/lib/module.d.ts +19 -23
- package/dist/lib/module.d.ts.map +1 -1
- package/dist/lib/module.js +13 -38
- package/dist/lib/module.js.map +1 -1
- package/dist/lib/role-management/role-management.component.d.ts +56 -0
- package/dist/lib/role-management/role-management.component.d.ts.map +1 -0
- package/dist/lib/role-management/role-management.component.js +464 -0
- package/dist/lib/role-management/role-management.component.js.map +1 -0
- package/dist/lib/settings/settings.component.d.ts +42 -51
- package/dist/lib/settings/settings.component.d.ts.map +1 -1
- package/dist/lib/settings/settings.component.js +432 -198
- package/dist/lib/settings/settings.component.js.map +1 -1
- package/dist/lib/shared/components/settings-card/settings-card.component.d.ts +27 -0
- package/dist/lib/shared/components/settings-card/settings-card.component.d.ts.map +1 -0
- package/dist/lib/shared/components/settings-card/settings-card.component.js +167 -0
- package/dist/lib/shared/components/settings-card/settings-card.component.js.map +1 -0
- package/dist/lib/shared/settings-card.component.d.ts +11 -0
- package/dist/lib/shared/settings-card.component.d.ts.map +1 -0
- package/dist/lib/shared/settings-card.component.js +73 -0
- package/dist/lib/shared/settings-card.component.js.map +1 -0
- package/dist/lib/shared/shared-settings.module.d.ts +9 -0
- package/dist/lib/shared/shared-settings.module.d.ts.map +1 -0
- package/dist/lib/shared/shared-settings.module.js +25 -0
- package/dist/lib/shared/shared-settings.module.js.map +1 -0
- package/dist/lib/sql-logging/sql-logging.component.d.ts +176 -0
- package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -0
- package/dist/lib/sql-logging/sql-logging.component.js +946 -0
- package/dist/lib/sql-logging/sql-logging.component.js.map +1 -0
- package/dist/lib/user-management/user-management.component.d.ts +65 -0
- package/dist/lib/user-management/user-management.component.d.ts.map +1 -0
- package/dist/lib/user-management/user-management.component.js +643 -0
- package/dist/lib/user-management/user-management.component.js.map +1 -0
- package/dist/public-api.d.ts +1 -5
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -5
- package/dist/public-api.js.map +1 -1
- package/package.json +13 -13
- package/dist/lib/application-entities-grid/application-entities-grid.component.d.ts +0 -50
- package/dist/lib/application-entities-grid/application-entities-grid.component.d.ts.map +0 -1
- package/dist/lib/application-entities-grid/application-entities-grid.component.js +0 -342
- package/dist/lib/application-entities-grid/application-entities-grid.component.js.map +0 -1
- package/dist/lib/single-application/single-application.component.d.ts +0 -22
- package/dist/lib/single-application/single-application.component.d.ts.map +0 -1
- package/dist/lib/single-application/single-application.component.js +0 -130
- package/dist/lib/single-application/single-application.component.js.map +0 -1
- package/dist/lib/single-role/single-role.component.d.ts +0 -36
- package/dist/lib/single-role/single-role.component.d.ts.map +0 -1
- package/dist/lib/single-role/single-role.component.js +0 -188
- package/dist/lib/single-role/single-role.component.js.map +0 -1
- package/dist/lib/single-user/single-user.component.d.ts +0 -24
- package/dist/lib/single-user/single-user.component.d.ts.map +0 -1
- package/dist/lib/single-user/single-user.component.js +0 -176
- package/dist/lib/single-user/single-user.component.js.map +0 -1
- package/dist/lib/user-roles-grid/user-roles-grid.component.d.ts +0 -42
- package/dist/lib/user-roles-grid/user-roles-grid.component.d.ts.map +0 -1
- package/dist/lib/user-roles-grid/user-roles-grid.component.js +0 -326
- package/dist/lib/user-roles-grid/user-roles-grid.component.js.map +0 -1
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { Subject, BehaviorSubject } from 'rxjs';
|
|
5
|
+
import { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
6
|
+
import { RunView, Metadata } from '@memberjunction/core';
|
|
7
|
+
import { SharedSettingsModule } from '../shared/shared-settings.module';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "@angular/common";
|
|
10
|
+
const _forTrack0 = ($index, $item) => $item.ID;
|
|
11
|
+
function RoleManagementComponent_Conditional_56_Template(rf, ctx) { if (rf & 1) {
|
|
12
|
+
i0.ɵɵelementStart(0, "div", 27)(1, "div", 31);
|
|
13
|
+
i0.ɵɵelement(2, "div", 32)(3, "div", 32)(4, "div", 32);
|
|
14
|
+
i0.ɵɵelementEnd();
|
|
15
|
+
i0.ɵɵelementStart(5, "div", 33);
|
|
16
|
+
i0.ɵɵtext(6, "Loading roles...");
|
|
17
|
+
i0.ɵɵelementEnd()();
|
|
18
|
+
} }
|
|
19
|
+
function RoleManagementComponent_Conditional_57_Template(rf, ctx) { if (rf & 1) {
|
|
20
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
21
|
+
i0.ɵɵelementStart(0, "div", 28)(1, "div", 34);
|
|
22
|
+
i0.ɵɵelement(2, "i", 35);
|
|
23
|
+
i0.ɵɵelementStart(3, "p", 36);
|
|
24
|
+
i0.ɵɵtext(4);
|
|
25
|
+
i0.ɵɵelementEnd();
|
|
26
|
+
i0.ɵɵelementStart(5, "button", 37);
|
|
27
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_57_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.loadInitialData()); });
|
|
28
|
+
i0.ɵɵelement(6, "i", 3);
|
|
29
|
+
i0.ɵɵtext(7, " Try Again ");
|
|
30
|
+
i0.ɵɵelementEnd()()();
|
|
31
|
+
} if (rf & 2) {
|
|
32
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
33
|
+
i0.ɵɵadvance(4);
|
|
34
|
+
i0.ɵɵtextInterpolate(ctx_r1.error);
|
|
35
|
+
} }
|
|
36
|
+
function RoleManagementComponent_Conditional_58_For_3_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
37
|
+
i0.ɵɵelementStart(0, "div", 57)(1, "div", 58)(2, "div", 59);
|
|
38
|
+
i0.ɵɵelement(3, "i", 60);
|
|
39
|
+
i0.ɵɵelementStart(4, "span", 12);
|
|
40
|
+
i0.ɵɵtext(5, "Users:");
|
|
41
|
+
i0.ɵɵelementEnd();
|
|
42
|
+
i0.ɵɵelementStart(6, "span", 11);
|
|
43
|
+
i0.ɵɵtext(7, "0");
|
|
44
|
+
i0.ɵɵelementEnd()();
|
|
45
|
+
i0.ɵɵelementStart(8, "div", 59);
|
|
46
|
+
i0.ɵɵelement(9, "i", 61);
|
|
47
|
+
i0.ɵɵelementStart(10, "span", 12);
|
|
48
|
+
i0.ɵɵtext(11, "Created:");
|
|
49
|
+
i0.ɵɵelementEnd();
|
|
50
|
+
i0.ɵɵelementStart(12, "span", 11);
|
|
51
|
+
i0.ɵɵtext(13);
|
|
52
|
+
i0.ɵɵpipe(14, "date");
|
|
53
|
+
i0.ɵɵelementEnd()();
|
|
54
|
+
i0.ɵɵelementStart(15, "div", 59);
|
|
55
|
+
i0.ɵɵelement(16, "i", 62);
|
|
56
|
+
i0.ɵɵelementStart(17, "span", 12);
|
|
57
|
+
i0.ɵɵtext(18, "Updated:");
|
|
58
|
+
i0.ɵɵelementEnd();
|
|
59
|
+
i0.ɵɵelementStart(19, "span", 11);
|
|
60
|
+
i0.ɵɵtext(20);
|
|
61
|
+
i0.ɵɵpipe(21, "date");
|
|
62
|
+
i0.ɵɵelementEnd()()();
|
|
63
|
+
i0.ɵɵelementStart(22, "div", 63)(23, "h4", 64);
|
|
64
|
+
i0.ɵɵelement(24, "i", 65);
|
|
65
|
+
i0.ɵɵtext(25, " Permissions Preview ");
|
|
66
|
+
i0.ɵɵelementEnd();
|
|
67
|
+
i0.ɵɵelementStart(26, "p", 66);
|
|
68
|
+
i0.ɵɵtext(27, "Full permission management available in the Permissions tab");
|
|
69
|
+
i0.ɵɵelementEnd()()();
|
|
70
|
+
} if (rf & 2) {
|
|
71
|
+
const role_r4 = i0.ɵɵnextContext().$implicit;
|
|
72
|
+
i0.ɵɵadvance(13);
|
|
73
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(14, 2, role_r4.__mj_CreatedAt, "short"));
|
|
74
|
+
i0.ɵɵadvance(7);
|
|
75
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(21, 5, role_r4.__mj_UpdatedAt, "short"));
|
|
76
|
+
} }
|
|
77
|
+
function RoleManagementComponent_Conditional_58_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
78
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
79
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "div", 42);
|
|
80
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_58_For_3_Template_div_click_1_listener() { const role_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleRoleExpansion(role_r4.ID)); });
|
|
81
|
+
i0.ɵɵelementStart(2, "div", 43)(3, "div", 44);
|
|
82
|
+
i0.ɵɵelement(4, "i");
|
|
83
|
+
i0.ɵɵelementEnd();
|
|
84
|
+
i0.ɵɵelementStart(5, "div", 45)(6, "h3", 46);
|
|
85
|
+
i0.ɵɵtext(7);
|
|
86
|
+
i0.ɵɵelementEnd();
|
|
87
|
+
i0.ɵɵelementStart(8, "p", 47);
|
|
88
|
+
i0.ɵɵtext(9);
|
|
89
|
+
i0.ɵɵelementEnd()()();
|
|
90
|
+
i0.ɵɵelementStart(10, "div", 48)(11, "span", 49);
|
|
91
|
+
i0.ɵɵtext(12);
|
|
92
|
+
i0.ɵɵelementEnd();
|
|
93
|
+
i0.ɵɵelementStart(13, "div", 50);
|
|
94
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_58_For_3_Template_div_click_13_listener($event) { i0.ɵɵrestoreView(_r3); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
95
|
+
i0.ɵɵelementStart(14, "button", 51);
|
|
96
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_58_For_3_Template_button_click_14_listener() { const role_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.editRole(role_r4)); });
|
|
97
|
+
i0.ɵɵelement(15, "i", 52);
|
|
98
|
+
i0.ɵɵelementEnd();
|
|
99
|
+
i0.ɵɵelementStart(16, "button", 53);
|
|
100
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_58_For_3_Template_button_click_16_listener() { const role_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.confirmDeleteRole(role_r4)); });
|
|
101
|
+
i0.ɵɵelement(17, "i", 54);
|
|
102
|
+
i0.ɵɵelementEnd()();
|
|
103
|
+
i0.ɵɵelementStart(18, "button", 55);
|
|
104
|
+
i0.ɵɵelement(19, "i", 56);
|
|
105
|
+
i0.ɵɵelementEnd()()();
|
|
106
|
+
i0.ɵɵtemplate(20, RoleManagementComponent_Conditional_58_For_3_Conditional_20_Template, 28, 8, "div", 57);
|
|
107
|
+
i0.ɵɵelementEnd();
|
|
108
|
+
} if (rf & 2) {
|
|
109
|
+
const role_r4 = ctx.$implicit;
|
|
110
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
111
|
+
i0.ɵɵclassProp("expanded", ctx_r1.isRoleExpanded(role_r4.ID));
|
|
112
|
+
i0.ɵɵadvance(4);
|
|
113
|
+
i0.ɵɵclassMap("fa-solid " + ctx_r1.getRoleIcon(role_r4));
|
|
114
|
+
i0.ɵɵadvance(3);
|
|
115
|
+
i0.ɵɵtextInterpolate(role_r4.Name);
|
|
116
|
+
i0.ɵɵadvance(2);
|
|
117
|
+
i0.ɵɵtextInterpolate(role_r4.Description || "No description available");
|
|
118
|
+
i0.ɵɵadvance(2);
|
|
119
|
+
i0.ɵɵclassMap(ctx_r1.getRoleTypeClass(role_r4));
|
|
120
|
+
i0.ɵɵadvance();
|
|
121
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.getRoleTypeLabel(role_r4), " ");
|
|
122
|
+
i0.ɵɵadvance(2);
|
|
123
|
+
i0.ɵɵproperty("disabled", ctx_r1.isSystemRole(role_r4));
|
|
124
|
+
i0.ɵɵadvance(2);
|
|
125
|
+
i0.ɵɵproperty("disabled", ctx_r1.isSystemRole(role_r4));
|
|
126
|
+
i0.ɵɵadvance(4);
|
|
127
|
+
i0.ɵɵconditional(ctx_r1.isRoleExpanded(role_r4.ID) ? 20 : -1);
|
|
128
|
+
} }
|
|
129
|
+
function RoleManagementComponent_Conditional_58_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
130
|
+
i0.ɵɵelementStart(0, "div", 40);
|
|
131
|
+
i0.ɵɵelement(1, "i", 67);
|
|
132
|
+
i0.ɵɵelementStart(2, "p", 68);
|
|
133
|
+
i0.ɵɵtext(3, "No roles found");
|
|
134
|
+
i0.ɵɵelementEnd();
|
|
135
|
+
i0.ɵɵelementStart(4, "p", 69);
|
|
136
|
+
i0.ɵɵtext(5, "Try adjusting your filters or create a new role");
|
|
137
|
+
i0.ɵɵelementEnd()();
|
|
138
|
+
} }
|
|
139
|
+
function RoleManagementComponent_Conditional_58_Template(rf, ctx) { if (rf & 1) {
|
|
140
|
+
i0.ɵɵelementStart(0, "div", 29)(1, "div", 38);
|
|
141
|
+
i0.ɵɵrepeaterCreate(2, RoleManagementComponent_Conditional_58_For_3_Template, 21, 12, "div", 39, _forTrack0);
|
|
142
|
+
i0.ɵɵtemplate(4, RoleManagementComponent_Conditional_58_Conditional_4_Template, 6, 0, "div", 40);
|
|
143
|
+
i0.ɵɵelementEnd()();
|
|
144
|
+
} if (rf & 2) {
|
|
145
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
146
|
+
i0.ɵɵadvance(2);
|
|
147
|
+
i0.ɵɵrepeater(ctx_r1.filteredRoles);
|
|
148
|
+
i0.ɵɵadvance(2);
|
|
149
|
+
i0.ɵɵconditional(ctx_r1.filteredRoles.length === 0 ? 4 : -1);
|
|
150
|
+
} }
|
|
151
|
+
function RoleManagementComponent_Conditional_59_Template(rf, ctx) { if (rf & 1) {
|
|
152
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
153
|
+
i0.ɵɵelementStart(0, "div", 70);
|
|
154
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_59_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
|
|
155
|
+
i0.ɵɵelementStart(1, "div", 71);
|
|
156
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_59_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r5); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
157
|
+
i0.ɵɵelementStart(2, "div", 72)(3, "h3", 73);
|
|
158
|
+
i0.ɵɵelement(4, "i", 74);
|
|
159
|
+
i0.ɵɵtext(5, " Confirm Delete ");
|
|
160
|
+
i0.ɵɵelementEnd();
|
|
161
|
+
i0.ɵɵelementStart(6, "button", 75);
|
|
162
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_59_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
|
|
163
|
+
i0.ɵɵelement(7, "i", 76);
|
|
164
|
+
i0.ɵɵelementEnd()();
|
|
165
|
+
i0.ɵɵelementStart(8, "div", 77)(9, "p");
|
|
166
|
+
i0.ɵɵtext(10, "Are you sure you want to delete the role ");
|
|
167
|
+
i0.ɵɵelementStart(11, "strong");
|
|
168
|
+
i0.ɵɵtext(12);
|
|
169
|
+
i0.ɵɵelementEnd();
|
|
170
|
+
i0.ɵɵtext(13, "?");
|
|
171
|
+
i0.ɵɵelementEnd();
|
|
172
|
+
i0.ɵɵelementStart(14, "p", 78);
|
|
173
|
+
i0.ɵɵelement(15, "i", 79);
|
|
174
|
+
i0.ɵɵtext(16, " This will affect all users assigned to this role. ");
|
|
175
|
+
i0.ɵɵelementEnd()();
|
|
176
|
+
i0.ɵɵelementStart(17, "div", 80)(18, "button", 81);
|
|
177
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_59_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
|
|
178
|
+
i0.ɵɵtext(19, "Cancel");
|
|
179
|
+
i0.ɵɵelementEnd();
|
|
180
|
+
i0.ɵɵelementStart(20, "button", 82);
|
|
181
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_59_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.deleteRole()); });
|
|
182
|
+
i0.ɵɵelement(21, "i", 54);
|
|
183
|
+
i0.ɵɵtext(22, " Delete Role ");
|
|
184
|
+
i0.ɵɵelementEnd()()()();
|
|
185
|
+
} if (rf & 2) {
|
|
186
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
187
|
+
i0.ɵɵadvance(12);
|
|
188
|
+
i0.ɵɵtextInterpolate(ctx_r1.selectedRole.Name);
|
|
189
|
+
} }
|
|
190
|
+
export class RoleManagementComponent {
|
|
191
|
+
// State management
|
|
192
|
+
roles = [];
|
|
193
|
+
filteredRoles = [];
|
|
194
|
+
selectedRole = null;
|
|
195
|
+
isLoading = false;
|
|
196
|
+
error = null;
|
|
197
|
+
// Stats
|
|
198
|
+
stats = {
|
|
199
|
+
totalRoles: 0,
|
|
200
|
+
systemRoles: 0,
|
|
201
|
+
customRoles: 0,
|
|
202
|
+
activeRoles: 0
|
|
203
|
+
};
|
|
204
|
+
// Filters
|
|
205
|
+
filters$ = new BehaviorSubject({
|
|
206
|
+
type: 'all',
|
|
207
|
+
search: ''
|
|
208
|
+
});
|
|
209
|
+
// UI State
|
|
210
|
+
showCreateDialog = false;
|
|
211
|
+
showEditDialog = false;
|
|
212
|
+
showDeleteConfirm = false;
|
|
213
|
+
expandedRoleId = null;
|
|
214
|
+
// Role permissions (simplified view)
|
|
215
|
+
rolePermissions = new Map();
|
|
216
|
+
destroy$ = new Subject();
|
|
217
|
+
metadata = new Metadata();
|
|
218
|
+
constructor() { }
|
|
219
|
+
ngOnInit() {
|
|
220
|
+
this.loadInitialData();
|
|
221
|
+
this.setupFilterSubscription();
|
|
222
|
+
}
|
|
223
|
+
ngOnDestroy() {
|
|
224
|
+
this.destroy$.next();
|
|
225
|
+
this.destroy$.complete();
|
|
226
|
+
}
|
|
227
|
+
async loadInitialData() {
|
|
228
|
+
try {
|
|
229
|
+
this.isLoading = true;
|
|
230
|
+
this.error = null;
|
|
231
|
+
// Load roles
|
|
232
|
+
const roles = await this.loadRoles();
|
|
233
|
+
this.roles = roles;
|
|
234
|
+
this.calculateStats();
|
|
235
|
+
this.applyFilters();
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
console.error('Error loading role data:', error);
|
|
239
|
+
this.error = 'Failed to load role data. Please try again.';
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
this.isLoading = false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async loadRoles() {
|
|
246
|
+
const rv = new RunView();
|
|
247
|
+
const result = await rv.RunView({
|
|
248
|
+
EntityName: 'Roles',
|
|
249
|
+
ResultType: 'entity_object',
|
|
250
|
+
OrderBy: 'Name ASC'
|
|
251
|
+
});
|
|
252
|
+
return result.Success ? result.Results : [];
|
|
253
|
+
}
|
|
254
|
+
setupFilterSubscription() {
|
|
255
|
+
this.filters$
|
|
256
|
+
.pipe(debounceTime(300), distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)), takeUntil(this.destroy$))
|
|
257
|
+
.subscribe(() => {
|
|
258
|
+
this.applyFilters();
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
applyFilters() {
|
|
262
|
+
const filters = this.filters$.value;
|
|
263
|
+
let filtered = [...this.roles];
|
|
264
|
+
// Apply type filter
|
|
265
|
+
if (filters.type !== 'all') {
|
|
266
|
+
filtered = filtered.filter(role => {
|
|
267
|
+
const isSystem = this.isSystemRole(role);
|
|
268
|
+
return filters.type === 'system' ? isSystem : !isSystem;
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
// Apply search filter
|
|
272
|
+
if (filters.search) {
|
|
273
|
+
const searchLower = filters.search.toLowerCase();
|
|
274
|
+
filtered = filtered.filter(role => role.Name?.toLowerCase().includes(searchLower) ||
|
|
275
|
+
role.Description?.toLowerCase().includes(searchLower));
|
|
276
|
+
}
|
|
277
|
+
this.filteredRoles = filtered;
|
|
278
|
+
}
|
|
279
|
+
calculateStats() {
|
|
280
|
+
const systemRoles = this.roles.filter(r => this.isSystemRole(r));
|
|
281
|
+
this.stats = {
|
|
282
|
+
totalRoles: this.roles.length,
|
|
283
|
+
systemRoles: systemRoles.length,
|
|
284
|
+
customRoles: this.roles.length - systemRoles.length,
|
|
285
|
+
activeRoles: this.roles.length // All roles are considered active for now
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
isSystemRole(role) {
|
|
289
|
+
// System roles typically have certain naming patterns or flags
|
|
290
|
+
const systemRoleNames = ['Administrator', 'User', 'Guest', 'Developer'];
|
|
291
|
+
return systemRoleNames.includes(role.Name || '');
|
|
292
|
+
}
|
|
293
|
+
// Public methods for template
|
|
294
|
+
onSearchChange(event) {
|
|
295
|
+
const value = event.target.value;
|
|
296
|
+
this.updateFilter({ search: value });
|
|
297
|
+
}
|
|
298
|
+
onTypeFilterChange(type) {
|
|
299
|
+
this.updateFilter({ type });
|
|
300
|
+
}
|
|
301
|
+
updateFilter(partial) {
|
|
302
|
+
this.filters$.next({
|
|
303
|
+
...this.filters$.value,
|
|
304
|
+
...partial
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
toggleRoleExpansion(roleId) {
|
|
308
|
+
this.expandedRoleId = this.expandedRoleId === roleId ? null : roleId;
|
|
309
|
+
}
|
|
310
|
+
isRoleExpanded(roleId) {
|
|
311
|
+
return this.expandedRoleId === roleId;
|
|
312
|
+
}
|
|
313
|
+
createNewRole() {
|
|
314
|
+
this.selectedRole = null;
|
|
315
|
+
this.showCreateDialog = true;
|
|
316
|
+
}
|
|
317
|
+
editRole(role) {
|
|
318
|
+
this.selectedRole = role;
|
|
319
|
+
this.showEditDialog = true;
|
|
320
|
+
}
|
|
321
|
+
confirmDeleteRole(role) {
|
|
322
|
+
this.selectedRole = role;
|
|
323
|
+
this.showDeleteConfirm = true;
|
|
324
|
+
}
|
|
325
|
+
async deleteRole() {
|
|
326
|
+
if (!this.selectedRole)
|
|
327
|
+
return;
|
|
328
|
+
try {
|
|
329
|
+
// Implement role deletion logic
|
|
330
|
+
this.showDeleteConfirm = false;
|
|
331
|
+
await this.loadInitialData();
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
console.error('Error deleting role:', error);
|
|
335
|
+
this.error = 'Failed to delete role';
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
getRoleIcon(role) {
|
|
339
|
+
if (this.isSystemRole(role)) {
|
|
340
|
+
return 'fa-shield-halved';
|
|
341
|
+
}
|
|
342
|
+
return 'fa-user-tag';
|
|
343
|
+
}
|
|
344
|
+
getRoleTypeLabel(role) {
|
|
345
|
+
return this.isSystemRole(role) ? 'System' : 'Custom';
|
|
346
|
+
}
|
|
347
|
+
getRoleTypeClass(role) {
|
|
348
|
+
return this.isSystemRole(role) ? 'badge-system' : 'badge-custom';
|
|
349
|
+
}
|
|
350
|
+
refreshData() {
|
|
351
|
+
this.loadInitialData();
|
|
352
|
+
}
|
|
353
|
+
static ɵfac = function RoleManagementComponent_Factory(t) { return new (t || RoleManagementComponent)(); };
|
|
354
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RoleManagementComponent, selectors: [["mj-role-management"]], standalone: true, features: [i0.ɵɵStandaloneFeature], decls: 60, vars: 18, consts: [[1, "role-management-container"], [1, "action-buttons"], [1, "btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-refresh"], [1, "btn-primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "stats-grid", 2, "display", "flex"], [1, "stat-card"], [1, "stat-icon", "stat-icon-total"], [1, "fa-solid", "fa-user-tag"], [1, "stat-content"], [1, "stat-value"], [1, "stat-label"], [1, "stat-icon", "stat-icon-system"], [1, "fa-solid", "fa-shield-halved"], [1, "stat-icon", "stat-icon-custom"], [1, "stat-icon", "stat-icon-active"], [1, "fa-solid", "fa-check-circle"], [1, "filters-section"], [1, "filters-row"], [1, "search-container"], [1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Search roles by name or description...", 1, "search-input", 3, "input", "value"], [1, "filter-group"], [1, "filter-label"], [1, "filter-buttons"], [1, "filter-btn", 3, "click"], [1, "loading-container"], [1, "error-container"], [1, "content-area"], [1, "modal-backdrop"], [1, "loading-spinner"], [1, "spinner-ring"], [1, "loading-text"], [1, "error-content"], [1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], [1, "retry-button", 3, "click"], [1, "roles-list"], [1, "role-card", 3, "expanded"], [1, "empty-state"], [1, "role-card"], [1, "role-header", 3, "click"], [1, "role-info"], [1, "role-icon-wrapper"], [1, "role-details"], [1, "role-name"], [1, "role-description"], [1, "role-meta"], [1, "role-type-badge"], [1, "role-actions", 3, "click"], ["title", "Edit", 1, "action-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-edit"], ["title", "Delete", 1, "action-btn", "action-btn-danger", 3, "click", "disabled"], [1, "fa-solid", "fa-trash"], [1, "expand-btn"], [1, "fa-solid", "fa-chevron-down"], [1, "role-content"], [1, "role-stats"], [1, "stat-item"], [1, "fa-solid", "fa-users"], [1, "fa-solid", "fa-calendar"], [1, "fa-solid", "fa-clock"], [1, "permissions-preview"], [1, "section-title"], [1, "fa-solid", "fa-key"], [1, "permissions-note"], [1, "fa-solid", "fa-user-tag", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], [1, "modal-backdrop", 3, "click"], [1, "modal-dialog", 3, "click"], [1, "modal-header"], [1, "modal-title"], [1, "fa-solid", "fa-exclamation-triangle", "text-danger"], [1, "modal-close", 3, "click"], [1, "fa-solid", "fa-times"], [1, "modal-body"], [1, "text-warning"], [1, "fa-solid", "fa-warning"], [1, "modal-footer"], [1, "btn-secondary", 3, "click"], [1, "btn-danger", 3, "click"]], template: function RoleManagementComponent_Template(rf, ctx) { if (rf & 1) {
|
|
355
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "button", 2);
|
|
356
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_2_listener() { return ctx.refreshData(); });
|
|
357
|
+
i0.ɵɵelement(3, "i", 3);
|
|
358
|
+
i0.ɵɵtext(4, " Refresh ");
|
|
359
|
+
i0.ɵɵelementEnd();
|
|
360
|
+
i0.ɵɵelementStart(5, "button", 4);
|
|
361
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_5_listener() { return ctx.createNewRole(); });
|
|
362
|
+
i0.ɵɵelement(6, "i", 5);
|
|
363
|
+
i0.ɵɵtext(7, " Add Role ");
|
|
364
|
+
i0.ɵɵelementEnd()();
|
|
365
|
+
i0.ɵɵelementStart(8, "div", 6)(9, "div", 7)(10, "div", 8);
|
|
366
|
+
i0.ɵɵelement(11, "i", 9);
|
|
367
|
+
i0.ɵɵelementEnd();
|
|
368
|
+
i0.ɵɵelementStart(12, "div", 10)(13, "div", 11);
|
|
369
|
+
i0.ɵɵtext(14);
|
|
370
|
+
i0.ɵɵelementEnd();
|
|
371
|
+
i0.ɵɵelementStart(15, "div", 12);
|
|
372
|
+
i0.ɵɵtext(16, "Total Roles");
|
|
373
|
+
i0.ɵɵelementEnd()()();
|
|
374
|
+
i0.ɵɵelementStart(17, "div", 7)(18, "div", 13);
|
|
375
|
+
i0.ɵɵelement(19, "i", 14);
|
|
376
|
+
i0.ɵɵelementEnd();
|
|
377
|
+
i0.ɵɵelementStart(20, "div", 10)(21, "div", 11);
|
|
378
|
+
i0.ɵɵtext(22);
|
|
379
|
+
i0.ɵɵelementEnd();
|
|
380
|
+
i0.ɵɵelementStart(23, "div", 12);
|
|
381
|
+
i0.ɵɵtext(24, "System Roles");
|
|
382
|
+
i0.ɵɵelementEnd()()();
|
|
383
|
+
i0.ɵɵelementStart(25, "div", 7)(26, "div", 15);
|
|
384
|
+
i0.ɵɵelement(27, "i", 9);
|
|
385
|
+
i0.ɵɵelementEnd();
|
|
386
|
+
i0.ɵɵelementStart(28, "div", 10)(29, "div", 11);
|
|
387
|
+
i0.ɵɵtext(30);
|
|
388
|
+
i0.ɵɵelementEnd();
|
|
389
|
+
i0.ɵɵelementStart(31, "div", 12);
|
|
390
|
+
i0.ɵɵtext(32, "Custom Roles");
|
|
391
|
+
i0.ɵɵelementEnd()()();
|
|
392
|
+
i0.ɵɵelementStart(33, "div", 7)(34, "div", 16);
|
|
393
|
+
i0.ɵɵelement(35, "i", 17);
|
|
394
|
+
i0.ɵɵelementEnd();
|
|
395
|
+
i0.ɵɵelementStart(36, "div", 10)(37, "div", 11);
|
|
396
|
+
i0.ɵɵtext(38);
|
|
397
|
+
i0.ɵɵelementEnd();
|
|
398
|
+
i0.ɵɵelementStart(39, "div", 12);
|
|
399
|
+
i0.ɵɵtext(40, "Active Roles");
|
|
400
|
+
i0.ɵɵelementEnd()()()();
|
|
401
|
+
i0.ɵɵelementStart(41, "div", 18)(42, "div", 19)(43, "div", 20);
|
|
402
|
+
i0.ɵɵelement(44, "i", 21);
|
|
403
|
+
i0.ɵɵelementStart(45, "input", 22);
|
|
404
|
+
i0.ɵɵlistener("input", function RoleManagementComponent_Template_input_input_45_listener($event) { return ctx.onSearchChange($event); });
|
|
405
|
+
i0.ɵɵelementEnd()();
|
|
406
|
+
i0.ɵɵelementStart(46, "div", 23)(47, "label", 24);
|
|
407
|
+
i0.ɵɵtext(48, "Type");
|
|
408
|
+
i0.ɵɵelementEnd();
|
|
409
|
+
i0.ɵɵelementStart(49, "div", 25)(50, "button", 26);
|
|
410
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_50_listener() { return ctx.onTypeFilterChange("all"); });
|
|
411
|
+
i0.ɵɵtext(51, " All ");
|
|
412
|
+
i0.ɵɵelementEnd();
|
|
413
|
+
i0.ɵɵelementStart(52, "button", 26);
|
|
414
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_52_listener() { return ctx.onTypeFilterChange("system"); });
|
|
415
|
+
i0.ɵɵtext(53, " System ");
|
|
416
|
+
i0.ɵɵelementEnd();
|
|
417
|
+
i0.ɵɵelementStart(54, "button", 26);
|
|
418
|
+
i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_54_listener() { return ctx.onTypeFilterChange("custom"); });
|
|
419
|
+
i0.ɵɵtext(55, " Custom ");
|
|
420
|
+
i0.ɵɵelementEnd()()()()();
|
|
421
|
+
i0.ɵɵtemplate(56, RoleManagementComponent_Conditional_56_Template, 7, 0, "div", 27)(57, RoleManagementComponent_Conditional_57_Template, 8, 1, "div", 28)(58, RoleManagementComponent_Conditional_58_Template, 5, 1, "div", 29)(59, RoleManagementComponent_Conditional_59_Template, 23, 1, "div", 30);
|
|
422
|
+
i0.ɵɵelementEnd();
|
|
423
|
+
} if (rf & 2) {
|
|
424
|
+
i0.ɵɵadvance(2);
|
|
425
|
+
i0.ɵɵproperty("disabled", ctx.isLoading);
|
|
426
|
+
i0.ɵɵadvance();
|
|
427
|
+
i0.ɵɵclassProp("fa-spin", ctx.isLoading);
|
|
428
|
+
i0.ɵɵadvance(11);
|
|
429
|
+
i0.ɵɵtextInterpolate(ctx.stats.totalRoles);
|
|
430
|
+
i0.ɵɵadvance(8);
|
|
431
|
+
i0.ɵɵtextInterpolate(ctx.stats.systemRoles);
|
|
432
|
+
i0.ɵɵadvance(8);
|
|
433
|
+
i0.ɵɵtextInterpolate(ctx.stats.customRoles);
|
|
434
|
+
i0.ɵɵadvance(8);
|
|
435
|
+
i0.ɵɵtextInterpolate(ctx.stats.activeRoles);
|
|
436
|
+
i0.ɵɵadvance(7);
|
|
437
|
+
i0.ɵɵproperty("value", ctx.filters$.value.search);
|
|
438
|
+
i0.ɵɵadvance(5);
|
|
439
|
+
i0.ɵɵclassProp("active", ctx.filters$.value.type === "all");
|
|
440
|
+
i0.ɵɵadvance(2);
|
|
441
|
+
i0.ɵɵclassProp("active", ctx.filters$.value.type === "system");
|
|
442
|
+
i0.ɵɵadvance(2);
|
|
443
|
+
i0.ɵɵclassProp("active", ctx.filters$.value.type === "custom");
|
|
444
|
+
i0.ɵɵadvance(2);
|
|
445
|
+
i0.ɵɵconditional(ctx.isLoading ? 56 : -1);
|
|
446
|
+
i0.ɵɵadvance();
|
|
447
|
+
i0.ɵɵconditional(ctx.error && !ctx.isLoading ? 57 : -1);
|
|
448
|
+
i0.ɵɵadvance();
|
|
449
|
+
i0.ɵɵconditional(!ctx.isLoading && !ctx.error ? 58 : -1);
|
|
450
|
+
i0.ɵɵadvance();
|
|
451
|
+
i0.ɵɵconditional(ctx.showDeleteConfirm && ctx.selectedRole ? 59 : -1);
|
|
452
|
+
} }, dependencies: [CommonModule, i1.DatePipe, FormsModule,
|
|
453
|
+
SharedSettingsModule], styles: ["@import '../shared/styles/variables';\n@import '../shared/styles/mixins';\n\n.role-management-container[_ngcontent-%COMP%] {\n @include scrollable-container;\n max-width: 1200px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n//[_ngcontent-%COMP%] Action[_ngcontent-%COMP%] Buttons\n.action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-bottom: 1.5rem;\n\n @media (max-width: 768px) {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n//[_ngcontent-%COMP%] Buttons\n.btn-primary[_ngcontent-%COMP%] {\n @include button-base;\n background-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n }\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n @include button-base;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n \n &:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n }\n}\n\n.btn-danger[_ngcontent-%COMP%] {\n @include button-base;\n background-color: #f44336;\n color: white;\n \n &:hover {\n background-color: #d32f2f;\n }\n}\n\n//[_ngcontent-%COMP%] Stats[_ngcontent-%COMP%] Grid\n.stats-grid[_ngcontent-%COMP%] {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n margin-bottom: 2rem;\n width: 100%;\n\n @media (max-width: 768px) {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0; // Prevent grid blowout\n\n &:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n }\n}\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n\n &-total {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n }\n\n &-system {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n }\n\n &-custom {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n }\n\n &-active {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n }\n}\n\n.stat-content[_ngcontent-%COMP%] {\n flex: 1;\n\n .stat-value {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n }\n\n .stat-label {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n }\n}\n\n//[_ngcontent-%COMP%] Filters[_ngcontent-%COMP%] Section\n.filters-section[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n margin-bottom: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filters-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 1.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n\n @media (max-width: 768px) {\n gap: 1rem;\n }\n}\n\n.search-container[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 250px;\n position: relative;\n\n .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n }\n\n .search-input {\n width: 100%;\n padding: 0.75rem 1rem 0.75rem 2.75rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n\n &:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n }\n }\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n\n .filter-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n }\n\n .filter-buttons {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n }\n\n .filter-btn {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n\n &:hover {\n color: #374151;\n }\n\n &.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n }\n }\n}\n\n//[_ngcontent-%COMP%] Content[_ngcontent-%COMP%] Area\n.content-area[_ngcontent-%COMP%] {\n @include scrollable-content;\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n padding: 1.5rem;\n}\n\n//[_ngcontent-%COMP%] Roles[_ngcontent-%COMP%] List\n.roles-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n max-height: calc(100vh - 450px); // Dynamic height\n overflow-y: auto;\n padding-right: 0.5rem; // Space for scrollbar\n}\n\n.role-card[_ngcontent-%COMP%] {\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.3s ease;\n\n &:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n }\n\n &.expanded {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n \n .expand-btn i {\n transform: rotate(180deg);\n }\n }\n}\n\n.role-header[_ngcontent-%COMP%] {\n padding: 1.5rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: #f9fafb;\n transition: background-color 0.2s;\n\n &:hover {\n background: #f3f4f6;\n }\n}\n\n.role-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex: 1;\n}\n\n.role-icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n background: rgba(33, 150, 243, 0.1);\n display: flex;\n align-items: center;\n justify-content: center;\n color: #2196f3;\n font-size: 1.25rem;\n}\n\n.role-details[_ngcontent-%COMP%] {\n flex: 1;\n\n .role-name {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n }\n\n .role-description {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0;\n }\n}\n\n.role-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.role-type-badge[_ngcontent-%COMP%] {\n padding: 0.375rem 0.75rem;\n border-radius: 20px;\n font-size: 0.75rem;\n font-weight: 600;\n\n &.badge-system {\n background: rgba(156, 39, 176, 0.1);\n color: #7b1fa2;\n }\n\n &.badge-custom {\n background: rgba(255, 152, 0, 0.1);\n color: #f57c00;\n }\n}\n\n.role-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n\n &:hover:not(:disabled) {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n }\n\n &:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n &-danger:hover:not(:disabled) {\n color: #f44336;\n }\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s;\n\n i {\n transition: transform 0.3s ease;\n }\n}\n\n//[_ngcontent-%COMP%] Role[_ngcontent-%COMP%] Content[_ngcontent-%COMP%] (Expanded)\n.role-content[_ngcontent-%COMP%] {\n padding: 1.5rem;\n background: white;\n border-top: 1px solid #e5e7eb;\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n.role-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 2rem;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\n\n .stat-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n\n i {\n color: #6b7280;\n }\n\n .stat-label {\n color: #6b7280;\n }\n\n .stat-value {\n color: #1f2937;\n font-weight: 500;\n }\n }\n}\n\n.permissions-preview[_ngcontent-%COMP%] {\n padding: 1rem;\n background: #f9fafb;\n border-radius: 8px;\n\n .section-title {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 1rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.5rem 0;\n\n i {\n color: #2196f3;\n }\n }\n\n .permissions-note {\n color: #6b7280;\n font-size: 0.875rem;\n margin: 0;\n }\n}\n\n//[_ngcontent-%COMP%] Method[_ngcontent-%COMP%] not[_ngcontent-%COMP%] accessible[_ngcontent-%COMP%] from[_ngcontent-%COMP%] template[_ngcontent-%COMP%], so[_ngcontent-%COMP%] we[_ngcontent-%COMP%] duplicate[_ngcontent-%COMP%] the[_ngcontent-%COMP%] logic\n.role-card[data-system=\"true\"][_ngcontent-%COMP%] {\n .role-icon-wrapper {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n }\n}\n\n//[_ngcontent-%COMP%] Empty[_ngcontent-%COMP%] State\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n\n .empty-icon {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n }\n\n .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n }\n\n .empty-subtext {\n color: #6b7280;\n margin: 0;\n }\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] State\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n\n .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n\n &:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n }\n\n &:nth-child(2) {\n border-color: transparent #9c27b0 transparent transparent;\n animation-delay: -0.3s;\n }\n\n &:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n }\n }\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n.loading-text[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n//[_ngcontent-%COMP%] Error[_ngcontent-%COMP%] State\n.error-container[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n\n .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n }\n\n .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n }\n\n .retry-button {\n @include button-base;\n background-color: #2196f3;\n color: white;\n }\n}\n\n//[_ngcontent-%COMP%] Modal[_ngcontent-%COMP%] Styles\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUp 0.3s ease;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n\n .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n }\n\n .modal-close {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n\n &:hover {\n background: #f3f4f6;\n color: #374151;\n }\n }\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n\n p {\n margin: 0 0 1rem 0;\n color: #374151;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .text-warning {\n color: #f57c00;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n//[_ngcontent-%COMP%] Animations\n@keyframes[_ngcontent-%COMP%] fadeIn[_ngcontent-%COMP%] {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 500px;\n }\n}\n\n//[_ngcontent-%COMP%] Utility[_ngcontent-%COMP%] Classes\n.text-danger[_ngcontent-%COMP%] {\n color: #f44336;\n}"] });
|
|
454
|
+
}
|
|
455
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RoleManagementComponent, [{
|
|
456
|
+
type: Component,
|
|
457
|
+
args: [{ selector: 'mj-role-management', standalone: true, imports: [
|
|
458
|
+
CommonModule,
|
|
459
|
+
FormsModule,
|
|
460
|
+
SharedSettingsModule
|
|
461
|
+
], template: "<div class=\"role-management-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button class=\"btn-secondary\" (click)=\"refreshData()\" [disabled]=\"isLoading\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\"></i>\n Refresh\n </button>\n <button class=\"btn-primary\" (click)=\"createNewRole()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Role\n </button>\n </div>\n\n <!-- Stats Cards -->\n <div class=\"stats-grid\" style=\"display: flex\">\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-total\">\n <i class=\"fa-solid fa-user-tag\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.totalRoles }}</div>\n <div class=\"stat-label\">Total Roles</div>\n </div>\n </div>\n \n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-system\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.systemRoles }}</div>\n <div class=\"stat-label\">System Roles</div>\n </div>\n </div>\n \n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-custom\">\n <i class=\"fa-solid fa-user-tag\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.customRoles }}</div>\n <div class=\"stat-label\">Custom Roles</div>\n </div>\n </div>\n \n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-active\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.activeRoles }}</div>\n <div class=\"stat-label\">Active Roles</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\">\n <div class=\"filters-row\">\n <!-- Search -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input \n type=\"text\" \n class=\"search-input\" \n placeholder=\"Search roles by name or description...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.search\"\n />\n </div>\n \n <!-- Type Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">Type</label>\n <div class=\"filter-buttons\">\n <button \n class=\"filter-btn\"\n [class.active]=\"filters$.value.type === 'all'\"\n (click)=\"onTypeFilterChange('all')\"\n >\n All\n </button>\n <button \n class=\"filter-btn\"\n [class.active]=\"filters$.value.type === 'system'\"\n (click)=\"onTypeFilterChange('system')\"\n >\n System\n </button>\n <button \n class=\"filter-btn\"\n [class.active]=\"filters$.value.type === 'custom'\"\n (click)=\"onTypeFilterChange('custom')\"\n >\n Custom\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading roles...</div>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"retry-button\" (click)=\"loadInitialData()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Content Area -->\n @if (!isLoading && !error) {\n <div class=\"content-area\">\n <div class=\"roles-list\">\n @for (role of filteredRoles; track role.ID) {\n <div class=\"role-card\" [class.expanded]=\"isRoleExpanded(role.ID)\">\n <div class=\"role-header\" (click)=\"toggleRoleExpansion(role.ID)\">\n <div class=\"role-info\">\n <div class=\"role-icon-wrapper\">\n <i [class]=\"'fa-solid ' + getRoleIcon(role)\"></i>\n </div>\n <div class=\"role-details\">\n <h3 class=\"role-name\">{{ role.Name }}</h3>\n <p class=\"role-description\">{{ role.Description || 'No description available' }}</p>\n </div>\n </div>\n \n <div class=\"role-meta\">\n <span class=\"role-type-badge\" [class]=\"getRoleTypeClass(role)\">\n {{ getRoleTypeLabel(role) }}\n </span>\n <div class=\"role-actions\" (click)=\"$event.stopPropagation()\">\n <button class=\"action-btn\" (click)=\"editRole(role)\" title=\"Edit\" [disabled]=\"isSystemRole(role)\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button class=\"action-btn action-btn-danger\" (click)=\"confirmDeleteRole(role)\" title=\"Delete\" [disabled]=\"isSystemRole(role)\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n <button class=\"expand-btn\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n </div>\n </div>\n \n @if (isRoleExpanded(role.ID)) {\n <div class=\"role-content\">\n <div class=\"role-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-users\"></i>\n <span class=\"stat-label\">Users:</span>\n <span class=\"stat-value\">0</span><!-- UserCount would come from a join -->\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-calendar\"></i>\n <span class=\"stat-label\">Created:</span>\n <span class=\"stat-value\">{{ role.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"stat-label\">Updated:</span>\n <span class=\"stat-value\">{{ role.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n </div>\n \n <div class=\"permissions-preview\">\n <h4 class=\"section-title\">\n <i class=\"fa-solid fa-key\"></i>\n Permissions Preview\n </h4>\n <p class=\"permissions-note\">Full permission management available in the Permissions tab</p>\n </div>\n </div>\n }\n </div>\n }\n \n @if (filteredRoles.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-user-tag empty-icon\"></i>\n <p class=\"empty-text\">No roles found</p>\n <p class=\"empty-subtext\">Try adjusting your filters or create a new role</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedRole) {\n <div class=\"modal-backdrop\" (click)=\"showDeleteConfirm = false\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\"></i>\n Confirm Delete\n </h3>\n <button class=\"modal-close\" (click)=\"showDeleteConfirm = false\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Are you sure you want to delete the role <strong>{{ selectedRole.Name }}</strong>?</p>\n <p class=\"text-warning\">\n <i class=\"fa-solid fa-warning\"></i>\n This will affect all users assigned to this role.\n </p>\n </div>\n <div class=\"modal-footer\">\n <button class=\"btn-secondary\" (click)=\"showDeleteConfirm = false\">Cancel</button>\n <button class=\"btn-danger\" (click)=\"deleteRole()\">\n <i class=\"fa-solid fa-trash\"></i>\n Delete Role\n </button>\n </div>\n </div>\n </div>\n }\n</div>", styles: ["@import '../shared/styles/variables';\n@import '../shared/styles/mixins';\n\n.role-management-container {\n @include scrollable-container;\n max-width: 1200px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n// Action Buttons\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-bottom: 1.5rem;\n\n @media (max-width: 768px) {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n// Buttons\n.btn-primary {\n @include button-base;\n background-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n }\n}\n\n.btn-secondary {\n @include button-base;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n \n &:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n }\n}\n\n.btn-danger {\n @include button-base;\n background-color: #f44336;\n color: white;\n \n &:hover {\n background-color: #d32f2f;\n }\n}\n\n// Stats Grid\n.stats-grid {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n margin-bottom: 2rem;\n width: 100%;\n\n @media (max-width: 768px) {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0; // Prevent grid blowout\n\n &:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n }\n}\n\n.stat-icon {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n\n &-total {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n }\n\n &-system {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n }\n\n &-custom {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n }\n\n &-active {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n }\n}\n\n.stat-content {\n flex: 1;\n\n .stat-value {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n }\n\n .stat-label {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n }\n}\n\n// Filters Section\n.filters-section {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n margin-bottom: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filters-row {\n display: flex;\n gap: 1.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n\n @media (max-width: 768px) {\n gap: 1rem;\n }\n}\n\n.search-container {\n flex: 1;\n min-width: 250px;\n position: relative;\n\n .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n }\n\n .search-input {\n width: 100%;\n padding: 0.75rem 1rem 0.75rem 2.75rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n\n &:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n }\n }\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n\n .filter-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n }\n\n .filter-buttons {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n }\n\n .filter-btn {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n\n &:hover {\n color: #374151;\n }\n\n &.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n }\n }\n}\n\n// Content Area\n.content-area {\n @include scrollable-content;\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n padding: 1.5rem;\n}\n\n// Roles List\n.roles-list {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n max-height: calc(100vh - 450px); // Dynamic height\n overflow-y: auto;\n padding-right: 0.5rem; // Space for scrollbar\n}\n\n.role-card {\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.3s ease;\n\n &:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n }\n\n &.expanded {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n \n .expand-btn i {\n transform: rotate(180deg);\n }\n }\n}\n\n.role-header {\n padding: 1.5rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: #f9fafb;\n transition: background-color 0.2s;\n\n &:hover {\n background: #f3f4f6;\n }\n}\n\n.role-info {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex: 1;\n}\n\n.role-icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n background: rgba(33, 150, 243, 0.1);\n display: flex;\n align-items: center;\n justify-content: center;\n color: #2196f3;\n font-size: 1.25rem;\n}\n\n.role-details {\n flex: 1;\n\n .role-name {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n }\n\n .role-description {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0;\n }\n}\n\n.role-meta {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.role-type-badge {\n padding: 0.375rem 0.75rem;\n border-radius: 20px;\n font-size: 0.75rem;\n font-weight: 600;\n\n &.badge-system {\n background: rgba(156, 39, 176, 0.1);\n color: #7b1fa2;\n }\n\n &.badge-custom {\n background: rgba(255, 152, 0, 0.1);\n color: #f57c00;\n }\n}\n\n.role-actions {\n display: flex;\n gap: 0.5rem;\n}\n\n.action-btn {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n\n &:hover:not(:disabled) {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n }\n\n &:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n &-danger:hover:not(:disabled) {\n color: #f44336;\n }\n}\n\n.expand-btn {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s;\n\n i {\n transition: transform 0.3s ease;\n }\n}\n\n// Role Content (Expanded)\n.role-content {\n padding: 1.5rem;\n background: white;\n border-top: 1px solid #e5e7eb;\n animation: slideDown 0.3s ease-out;\n}\n\n.role-stats {\n display: flex;\n gap: 2rem;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\n\n .stat-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n\n i {\n color: #6b7280;\n }\n\n .stat-label {\n color: #6b7280;\n }\n\n .stat-value {\n color: #1f2937;\n font-weight: 500;\n }\n }\n}\n\n.permissions-preview {\n padding: 1rem;\n background: #f9fafb;\n border-radius: 8px;\n\n .section-title {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 1rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.5rem 0;\n\n i {\n color: #2196f3;\n }\n }\n\n .permissions-note {\n color: #6b7280;\n font-size: 0.875rem;\n margin: 0;\n }\n}\n\n// Method not accessible from template, so we duplicate the logic\n.role-card[data-system=\"true\"] {\n .role-icon-wrapper {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n }\n}\n\n// Empty State\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n\n .empty-icon {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n }\n\n .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n }\n\n .empty-subtext {\n color: #6b7280;\n margin: 0;\n }\n}\n\n// Loading State\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n\n .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n\n &:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n }\n\n &:nth-child(2) {\n border-color: transparent #9c27b0 transparent transparent;\n animation-delay: -0.3s;\n }\n\n &:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n }\n }\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n// Error State\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n\n .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n }\n\n .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n }\n\n .retry-button {\n @include button-base;\n background-color: #2196f3;\n color: white;\n }\n}\n\n// Modal Styles\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.modal-dialog {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s ease;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n\n .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n }\n\n .modal-close {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n\n &:hover {\n background: #f3f4f6;\n color: #374151;\n }\n }\n}\n\n.modal-body {\n padding: 1.5rem;\n\n p {\n margin: 0 0 1rem 0;\n color: #374151;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .text-warning {\n color: #f57c00;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n// Animations\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 500px;\n }\n}\n\n// Utility Classes\n.text-danger {\n color: #f44336;\n}"] }]
|
|
462
|
+
}], () => [], null); })();
|
|
463
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RoleManagementComponent, { className: "RoleManagementComponent", filePath: "src/lib/role-management/role-management.component.ts", lineNumber: 33 }); })();
|
|
464
|
+
//# sourceMappingURL=role-management.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-management.component.js","sourceRoot":"","sources":["../../../src/lib/role-management/role-management.component.ts","../../../src/lib/role-management/role-management.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAqB,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;;;;;ICiGlE,AADF,+BAA+B,cACA;IAG3B,AADA,AADA,0BAAgC,cACA,cACA;IAClC,iBAAM;IACN,+BAA0B;IAAA,gCAAgB;IAC5C,AAD4C,iBAAM,EAC5C;;;;IAMJ,AADF,+BAA6B,cACA;IACzB,wBAA2D;IAC3D,6BAAyB;IAAA,YAAW;IAAA,iBAAI;IACxC,kCAAyD;IAA5B,4LAAS,wBAAiB,KAAC;IACtD,uBAAmC;IACnC,2BACF;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;IANuB,eAAW;IAAX,kCAAW;;;IA+C1B,AADF,AADF,+BAA0B,cACA,cACC;IACrB,wBAAiC;IACjC,gCAAyB;IAAA,sBAAM;IAAA,iBAAO;IACtC,gCAAyB;IAAA,iBAAC;IAC5B,AAD4B,iBAAO,EAC7B;IACN,+BAAuB;IACrB,wBAAoC;IACpC,iCAAyB;IAAA,yBAAQ;IAAA,iBAAO;IACxC,iCAAyB;IAAA,aAAwC;;IACnE,AADmE,iBAAO,EACpE;IACN,gCAAuB;IACrB,yBAAiC;IACjC,iCAAyB;IAAA,yBAAQ;IAAA,iBAAO;IACxC,iCAAyB;IAAA,aAAwC;;IAErE,AADE,AADmE,iBAAO,EACpE,EACF;IAGJ,AADF,gCAAiC,cACL;IACxB,yBAA+B;IAC/B,sCACF;IAAA,iBAAK;IACL,8BAA4B;IAAA,4EAA2D;IAE3F,AADE,AADyF,iBAAI,EACvF,EACF;;;IAhByB,gBAAwC;IAAxC,4EAAwC;IAKxC,eAAwC;IAAxC,4EAAwC;;;;IA7CzE,AADF,+BAAkE,cACA;IAAvC,0NAAS,sCAA4B,KAAC;IAE3D,AADF,+BAAuB,cACU;IAC7B,oBAAiD;IACnD,iBAAM;IAEJ,AADF,+BAA0B,aACF;IAAA,YAAe;IAAA,iBAAK;IAC1C,6BAA4B;IAAA,YAAoD;IAEpF,AADE,AADkF,iBAAI,EAChF,EACF;IAGJ,AADF,gCAAuB,gBAC0C;IAC7D,aACF;IAAA,iBAAO;IACP,gCAA6D;IAAnC,mKAAS,wBAAwB,KAAC;IAC1D,mCAAiG;IAAtE,8NAAS,wBAAc,KAAC;IACjD,yBAAgC;IAClC,iBAAS;IACT,mCAA8H;IAAjF,8NAAS,iCAAuB,KAAC;IAC5E,yBAAiC;IAErC,AADE,iBAAS,EACL;IACN,mCAA2B;IACzB,yBAAwC;IAG9C,AADE,AADE,iBAAS,EACL,EACF;IAEN,yGAA+B;IA6BjC,iBAAM;;;;IA3DiB,6DAA0C;IAItD,eAAyC;IAAzC,wDAAyC;IAGtB,eAAe;IAAf,kCAAe;IACT,eAAoD;IAApD,uEAAoD;IAKpD,eAAgC;IAAhC,+CAAgC;IAC5D,cACF;IADE,iEACF;IAEmE,eAA+B;IAA/B,uDAA+B;IAGF,eAA+B;IAA/B,uDAA+B;IAUnI,eA4BC;IA5BD,6DA4BC;;;IAKH,+BAAyB;IACvB,wBAA+C;IAC/C,6BAAsB;IAAA,8BAAc;IAAA,iBAAI;IACxC,6BAAyB;IAAA,+DAA+C;IAC1E,AAD0E,iBAAI,EACxE;;;IArEV,AADF,+BAA0B,cACA;IACtB,4GA6DC;IAED,gGAAkC;IAQtC,AADE,iBAAM,EACF;;;IAvEF,eA6DC;IA7DD,mCA6DC;IAED,eAMC;IAND,4DAMC;;;;IAOL,+BAAgE;IAApC,oNAA6B,KAAK,KAAC;IAC7D,+BAA6D;IAAnC,4JAAS,wBAAwB,KAAC;IAExD,AADF,+BAA0B,aACA;IACtB,wBAA4D;IAC5D,gCACF;IAAA,iBAAK;IACL,kCAAgE;IAApC,uNAA6B,KAAK,KAAC;IAC7D,wBAAiC;IAErC,AADE,iBAAS,EACL;IAEJ,AADF,+BAAwB,QACnB;IAAA,0DAAyC;IAAA,+BAAQ;IAAA,aAAuB;IAAA,iBAAS;IAAA,kBAAC;IAAA,iBAAI;IACzF,8BAAwB;IACtB,yBAAmC;IACnC,oEACF;IACF,AADE,iBAAI,EACA;IAEJ,AADF,gCAA0B,kBAC0C;IAApC,wNAA6B,KAAK,KAAC;IAAC,uBAAM;IAAA,iBAAS;IACjF,mCAAkD;IAAvB,6LAAS,mBAAY,KAAC;IAC/C,yBAAiC;IACjC,8BACF;IAGN,AADE,AADE,AADE,iBAAS,EACL,EACF,EACF;;;IAdoD,gBAAuB;IAAvB,8CAAuB;;AD3LrF,MAAM,OAAO,uBAAuB;IAClC,mBAAmB;IACZ,KAAK,GAAiB,EAAE,CAAC;IACzB,aAAa,GAAiB,EAAE,CAAC;IACjC,YAAY,GAAsB,IAAI,CAAC;IACvC,SAAS,GAAG,KAAK,CAAC;IAClB,KAAK,GAAkB,IAAI,CAAC;IAEnC,QAAQ;IACD,KAAK,GAAc;QACxB,UAAU,EAAE,CAAC;QACb,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,CAAC;KACf,CAAC;IAEF,UAAU;IACH,QAAQ,GAAG,IAAI,eAAe,CAAgB;QACnD,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,EAAE;KACX,CAAC,CAAC;IAEH,WAAW;IACJ,gBAAgB,GAAG,KAAK,CAAC;IACzB,cAAc,GAAG,KAAK,CAAC;IACvB,iBAAiB,GAAG,KAAK,CAAC;IAC1B,cAAc,GAAkB,IAAI,CAAC;IAE5C,qCAAqC;IAC9B,eAAe,GAA0B,IAAI,GAAG,EAAE,CAAC;IAElD,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAC/B,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAElC,gBAAe,CAAC;IAEhB,QAAQ;QACN,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,uBAAuB,EAAE,CAAC;IACjC,CAAC;IAED,WAAW;QACT,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;IAEM,KAAK,CAAC,eAAe;QAC1B,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAElB,aAAa;YACb,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,EAAE,CAAC;QAEtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YACjD,IAAI,CAAC,KAAK,GAAG,6CAA6C,CAAC;QAC7D,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACzB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAa;YAC1C,UAAU,EAAE,OAAO;YACnB,UAAU,EAAE,eAAe;YAC3B,OAAO,EAAE,UAAU;SACpB,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,CAAC;IAEO,uBAAuB;QAC7B,IAAI,CAAC,QAAQ;aACV,IAAI,CACH,YAAY,CAAC,GAAG,CAAC,EACjB,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EACvE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB;aACA,SAAS,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,YAAY;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpC,IAAI,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAE/B,oBAAoB;QACpB,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC3B,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;gBAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;gBACzC,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC1D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,sBAAsB;QACtB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACjD,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAChC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC9C,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CACtD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;IAChC,CAAC;IAEO,cAAc;QACpB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjE,IAAI,CAAC,KAAK,GAAG;YACX,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YAC7B,WAAW,EAAE,WAAW,CAAC,MAAM;YAC/B,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM;YACnD,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,0CAA0C;SAC1E,CAAC;IACJ,CAAC;IAEM,YAAY,CAAC,IAAgB;QAClC,+DAA+D;QAC/D,MAAM,eAAe,GAAG,CAAC,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QACxE,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,8BAA8B;IACvB,cAAc,CAAC,KAAY;QAChC,MAAM,KAAK,GAAI,KAAK,CAAC,MAA2B,CAAC,KAAK,CAAC;QACvD,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACvC,CAAC;IAEM,kBAAkB,CAAC,IAAiC;QACzD,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC;IAEM,YAAY,CAAC,OAA+B;QACjD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK;YACtB,GAAG,OAAO;SACX,CAAC,CAAC;IACL,CAAC;IAEM,mBAAmB,CAAC,MAAc;QACvC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACvE,CAAC;IAEM,cAAc,CAAC,MAAc;QAClC,OAAO,IAAI,CAAC,cAAc,KAAK,MAAM,CAAC;IACxC,CAAC;IAEM,aAAa;QAClB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAC/B,CAAC;IAEM,QAAQ,CAAC,IAAgB;QAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;IAEM,iBAAiB,CAAC,IAAgB;QACvC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAChC,CAAC;IAEM,KAAK,CAAC,UAAU;QACrB,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAE/B,IAAI,CAAC;YACH,gCAAgC;YAChC,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;YAC/B,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;YAC7C,IAAI,CAAC,KAAK,GAAG,uBAAuB,CAAC;QACvC,CAAC;IACH,CAAC;IAEM,WAAW,CAAC,IAAgB;QACjC,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,OAAO,kBAAkB,CAAC;QAC5B,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC;IAEM,gBAAgB,CAAC,IAAgB;QACtC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IACvD,CAAC;IAEM,gBAAgB,CAAC,IAAgB;QACtC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC;IACnE,CAAC;IAEM,WAAW;QAChB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;iFAvMU,uBAAuB;6DAAvB,uBAAuB;YC7BhC,AADF,AAFF,8BAAuC,aAET,gBACmD;YAA/C,oGAAS,iBAAa,IAAC;YACnD,uBAA+D;YAC/D,yBACF;YAAA,iBAAS;YACT,iCAAsD;YAA1B,oGAAS,mBAAe,IAAC;YACnD,uBAAgC;YAChC,0BACF;YACF,AADE,iBAAS,EACL;YAKF,AADF,AADF,8BAA8C,aACrB,cACkB;YACrC,wBAAoC;YACtC,iBAAM;YAEJ,AADF,gCAA0B,eACA;YAAA,aAAsB;YAAA,iBAAM;YACpD,gCAAwB;YAAA,4BAAW;YAEvC,AADE,AADqC,iBAAM,EACrC,EACF;YAGJ,AADF,+BAAuB,eACmB;YACtC,yBAAyC;YAC3C,iBAAM;YAEJ,AADF,gCAA0B,eACA;YAAA,aAAuB;YAAA,iBAAM;YACrD,gCAAwB;YAAA,6BAAY;YAExC,AADE,AADsC,iBAAM,EACtC,EACF;YAGJ,AADF,+BAAuB,eACmB;YACtC,wBAAoC;YACtC,iBAAM;YAEJ,AADF,gCAA0B,eACA;YAAA,aAAuB;YAAA,iBAAM;YACrD,gCAAwB;YAAA,6BAAY;YAExC,AADE,AADsC,iBAAM,EACtC,EACF;YAGJ,AADF,+BAAuB,eACmB;YACtC,yBAAwC;YAC1C,iBAAM;YAEJ,AADF,gCAA0B,eACA;YAAA,aAAuB;YAAA,iBAAM;YACrD,gCAAwB;YAAA,6BAAY;YAG1C,AADE,AADE,AADsC,iBAAM,EACtC,EACF,EACF;YAMF,AAFF,AADF,gCAA6B,eACF,eAEO;YAC5B,yBAA8C;YAC9C,kCAME;YAFA,0GAAS,0BAAsB,IAAC;YAGpC,AAPE,iBAME,EACE;YAIJ,AADF,gCAA0B,iBACI;YAAA,qBAAI;YAAA,iBAAQ;YAEtC,AADF,gCAA4B,kBAKzB;YADC,qGAAS,uBAAmB,KAAK,CAAC,IAAC;YAEnC,sBACF;YAAA,iBAAS;YACT,mCAIC;YADC,qGAAS,uBAAmB,QAAQ,CAAC,IAAC;YAEtC,yBACF;YAAA,iBAAS;YACT,mCAIC;YADC,qGAAS,uBAAmB,QAAQ,CAAC,IAAC;YAEtC,yBACF;YAIR,AADE,AADE,AADE,AADE,iBAAS,EACL,EACF,EACF,EACF;YA2GN,AA9EA,AAdA,AAZA,mFAAiB,sEAYU,sEAcC,uEA8Ea;YA6B3C,iBAAM;;YAxOoD,eAAsB;YAAtB,wCAAsB;YAC3C,cAA2B;YAA3B,wCAA2B;YAgBhC,gBAAsB;YAAtB,0CAAsB;YAUtB,eAAuB;YAAvB,2CAAuB;YAUvB,eAAuB;YAAvB,2CAAuB;YAUvB,eAAuB;YAAvB,2CAAuB;YAiB7C,eAA+B;YAA/B,iDAA+B;YAU7B,eAA8C;YAA9C,2DAA8C;YAO9C,eAAiD;YAAjD,8DAAiD;YAOjD,eAAiD;YAAjD,8DAAiD;YAW3D,eASC;YATD,yCASC;YAGD,cAWC;YAXD,uDAWC;YAGD,cA2EC;YA3ED,wDA2EC;YAGD,cA4BC;YA5BD,qEA4BC;4BDjNC,YAAY,eACZ,WAAW;YACX,oBAAoB;;iFAKX,uBAAuB;cAXnC,SAAS;2BACE,oBAAoB,cAClB,IAAI,WACP;oBACP,YAAY;oBACZ,WAAW;oBACX,oBAAoB;iBACrB;;kFAIU,uBAAuB"}
|