@memberjunction/ng-explorer-settings 3.2.0 → 3.3.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.
Files changed (56) hide show
  1. package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts +15 -1
  2. package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts.map +1 -1
  3. package/dist/lib/application-management/application-dialog/application-dialog.component.js +329 -190
  4. package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
  5. package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
  6. package/dist/lib/application-management/application-management.component.js +265 -184
  7. package/dist/lib/application-management/application-management.component.js.map +1 -1
  8. package/dist/lib/entity-permissions/entity-permissions.component.d.ts +1 -0
  9. package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
  10. package/dist/lib/entity-permissions/entity-permissions.component.js +369 -192
  11. package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
  12. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts.map +1 -1
  13. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +160 -143
  14. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
  15. package/dist/lib/module.d.ts +20 -25
  16. package/dist/lib/module.d.ts.map +1 -1
  17. package/dist/lib/module.js +20 -44
  18. package/dist/lib/module.js.map +1 -1
  19. package/dist/lib/notification-preferences/notification-preferences.component.d.ts +77 -0
  20. package/dist/lib/notification-preferences/notification-preferences.component.d.ts.map +1 -1
  21. package/dist/lib/notification-preferences/notification-preferences.component.js +153 -77
  22. package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
  23. package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts.map +1 -1
  24. package/dist/lib/role-management/role-dialog/role-dialog.component.js +93 -89
  25. package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
  26. package/dist/lib/role-management/role-management.component.d.ts +1 -0
  27. package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
  28. package/dist/lib/role-management/role-management.component.js +275 -158
  29. package/dist/lib/role-management/role-management.component.js.map +1 -1
  30. package/dist/lib/settings/settings.component.d.ts +54 -1
  31. package/dist/lib/settings/settings.component.d.ts.map +1 -1
  32. package/dist/lib/settings/settings.component.js +528 -182
  33. package/dist/lib/settings/settings.component.js.map +1 -1
  34. package/dist/lib/shared/settings-card.component.d.ts.map +1 -1
  35. package/dist/lib/shared/settings-card.component.js +21 -18
  36. package/dist/lib/shared/settings-card.component.js.map +1 -1
  37. package/dist/lib/sql-logging/sql-logging.component.d.ts +12 -3
  38. package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -1
  39. package/dist/lib/sql-logging/sql-logging.component.js +318 -245
  40. package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
  41. package/dist/lib/user-app-config/user-app-config.component.d.ts +21 -3
  42. package/dist/lib/user-app-config/user-app-config.component.d.ts.map +1 -1
  43. package/dist/lib/user-app-config/user-app-config.component.js +202 -147
  44. package/dist/lib/user-app-config/user-app-config.component.js.map +1 -1
  45. package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
  46. package/dist/lib/user-management/user-dialog/user-dialog.component.js +120 -116
  47. package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
  48. package/dist/lib/user-management/user-management.component.d.ts +32 -2
  49. package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
  50. package/dist/lib/user-management/user-management.component.js +822 -297
  51. package/dist/lib/user-management/user-management.component.js.map +1 -1
  52. package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts +31 -2
  53. package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts.map +1 -1
  54. package/dist/lib/user-profile-settings/user-profile-settings.component.js +213 -80
  55. package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
  56. package/package.json +21 -20
@@ -11,27 +11,25 @@ import { RunView, Metadata } from '@memberjunction/core';
11
11
  import { BaseDashboard } from '@memberjunction/ng-shared';
12
12
  import { RegisterClass } from '@memberjunction/global';
13
13
  import * as i0 from "@angular/core";
14
- import * as i1 from "./role-dialog/role-dialog.component";
15
- import * as i2 from "@angular/common";
14
+ import * as i1 from "@memberjunction/ng-shared-generic";
15
+ import * as i2 from "./role-dialog/role-dialog.component";
16
+ import * as i3 from "@angular/common";
16
17
  const _forTrack0 = ($index, $item) => $item.ID;
17
- function RoleManagementComponent_Conditional_56_Template(rf, ctx) { if (rf & 1) {
18
- i0.ɵɵelementStart(0, "div", 27)(1, "div", 32);
19
- i0.ɵɵelement(2, "div", 33)(3, "div", 33)(4, "div", 33);
18
+ function RoleManagementComponent_Conditional_65_Template(rf, ctx) { if (rf & 1) {
19
+ i0.ɵɵelementStart(0, "div", 36);
20
+ i0.ɵɵelement(1, "mj-loading", 42);
20
21
  i0.ɵɵelementEnd();
21
- i0.ɵɵelementStart(5, "div", 34);
22
- i0.ɵɵtext(6, "Loading roles...");
23
- i0.ɵɵelementEnd()();
24
22
  } }
25
- function RoleManagementComponent_Conditional_57_Template(rf, ctx) { if (rf & 1) {
23
+ function RoleManagementComponent_Conditional_66_Template(rf, ctx) { if (rf & 1) {
26
24
  const _r1 = i0.ɵɵgetCurrentView();
27
- i0.ɵɵelementStart(0, "div", 28)(1, "div", 35);
28
- i0.ɵɵelement(2, "i", 36);
29
- i0.ɵɵelementStart(3, "p", 37);
25
+ i0.ɵɵelementStart(0, "div", 37)(1, "div", 43);
26
+ i0.ɵɵelement(2, "i", 44);
27
+ i0.ɵɵelementStart(3, "p", 45);
30
28
  i0.ɵɵtext(4);
31
29
  i0.ɵɵelementEnd();
32
- i0.ɵɵelementStart(5, "button", 38);
33
- 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()); });
34
- i0.ɵɵelement(6, "i", 3);
30
+ i0.ɵɵelementStart(5, "button", 46);
31
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_66_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.loadInitialData()); });
32
+ i0.ɵɵelement(6, "i", 4);
35
33
  i0.ɵɵtext(7, " Try Again ");
36
34
  i0.ɵɵelementEnd()()();
37
35
  } if (rf & 2) {
@@ -39,83 +37,115 @@ function RoleManagementComponent_Conditional_57_Template(rf, ctx) { if (rf & 1)
39
37
  i0.ɵɵadvance(4);
40
38
  i0.ɵɵtextInterpolate(ctx_r1.error);
41
39
  } }
42
- function RoleManagementComponent_Conditional_58_For_3_Conditional_20_Template(rf, ctx) { if (rf & 1) {
43
- i0.ɵɵelementStart(0, "div", 58)(1, "div", 59)(2, "div", 60);
44
- i0.ɵɵelement(3, "i", 61);
45
- i0.ɵɵelementStart(4, "span", 12);
46
- i0.ɵɵtext(5, "Users:");
40
+ function RoleManagementComponent_Conditional_67_For_3_Conditional_20_Template(rf, ctx) { if (rf & 1) {
41
+ const _r5 = i0.ɵɵgetCurrentView();
42
+ i0.ɵɵelementStart(0, "div", 66)(1, "div", 67);
43
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_67_For_3_Conditional_20_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r5); return i0.ɵɵresetView($event.stopPropagation()); });
44
+ i0.ɵɵelementStart(2, "span", 58);
45
+ i0.ɵɵtext(3);
46
+ i0.ɵɵelementEnd();
47
+ i0.ɵɵelementStart(4, "div", 68)(5, "button", 60);
48
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_67_For_3_Conditional_20_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r5); const role_r4 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.editRole(role_r4)); });
49
+ i0.ɵɵelement(6, "i", 61);
50
+ i0.ɵɵelementStart(7, "span", 69);
51
+ i0.ɵɵtext(8, "Edit");
52
+ i0.ɵɵelementEnd()();
53
+ i0.ɵɵelementStart(9, "button", 62);
54
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_67_For_3_Conditional_20_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r5); const role_r4 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.confirmDeleteRole(role_r4)); });
55
+ i0.ɵɵelement(10, "i", 63);
56
+ i0.ɵɵelementStart(11, "span", 69);
57
+ i0.ɵɵtext(12, "Delete");
58
+ i0.ɵɵelementEnd()()()();
59
+ i0.ɵɵelementStart(13, "div", 70)(14, "div", 71);
60
+ i0.ɵɵelement(15, "i", 72);
61
+ i0.ɵɵelementStart(16, "span", 14);
62
+ i0.ɵɵtext(17, "Users:");
47
63
  i0.ɵɵelementEnd();
48
- i0.ɵɵelementStart(6, "span", 11);
49
- i0.ɵɵtext(7, "0");
64
+ i0.ɵɵelementStart(18, "span", 73);
65
+ i0.ɵɵtext(19, "0");
50
66
  i0.ɵɵelementEnd()();
51
- i0.ɵɵelementStart(8, "div", 60);
52
- i0.ɵɵelement(9, "i", 62);
53
- i0.ɵɵelementStart(10, "span", 12);
54
- i0.ɵɵtext(11, "Created:");
67
+ i0.ɵɵelementStart(20, "div", 71);
68
+ i0.ɵɵelement(21, "i", 74);
69
+ i0.ɵɵelementStart(22, "span", 14);
70
+ i0.ɵɵtext(23, "Created:");
55
71
  i0.ɵɵelementEnd();
56
- i0.ɵɵelementStart(12, "span", 11);
57
- i0.ɵɵtext(13);
58
- i0.ɵɵpipe(14, "date");
72
+ i0.ɵɵelementStart(24, "span", 73);
73
+ i0.ɵɵtext(25);
74
+ i0.ɵɵpipe(26, "date");
59
75
  i0.ɵɵelementEnd()();
60
- i0.ɵɵelementStart(15, "div", 60);
61
- i0.ɵɵelement(16, "i", 63);
62
- i0.ɵɵelementStart(17, "span", 12);
63
- i0.ɵɵtext(18, "Updated:");
76
+ i0.ɵɵelementStart(27, "div", 71);
77
+ i0.ɵɵelement(28, "i", 75);
78
+ i0.ɵɵelementStart(29, "span", 14);
79
+ i0.ɵɵtext(30, "Updated:");
64
80
  i0.ɵɵelementEnd();
65
- i0.ɵɵelementStart(19, "span", 11);
66
- i0.ɵɵtext(20);
67
- i0.ɵɵpipe(21, "date");
81
+ i0.ɵɵelementStart(31, "span", 73);
82
+ i0.ɵɵtext(32);
83
+ i0.ɵɵpipe(33, "date");
68
84
  i0.ɵɵelementEnd()()();
69
- i0.ɵɵelementStart(22, "div", 64)(23, "h4", 65);
70
- i0.ɵɵelement(24, "i", 66);
71
- i0.ɵɵtext(25, " Permissions Preview ");
85
+ i0.ɵɵelementStart(34, "div", 76)(35, "h4", 77);
86
+ i0.ɵɵelement(36, "i", 78);
87
+ i0.ɵɵtext(37, " Permissions Preview ");
72
88
  i0.ɵɵelementEnd();
73
- i0.ɵɵelementStart(26, "p", 67);
74
- i0.ɵɵtext(27, "Full permission management available in the Permissions tab");
89
+ i0.ɵɵelementStart(38, "p", 79);
90
+ i0.ɵɵtext(39, "Full permission management available in the Permissions tab");
75
91
  i0.ɵɵelementEnd()()();
76
92
  } if (rf & 2) {
77
93
  const role_r4 = i0.ɵɵnextContext().$implicit;
78
- i0.ɵɵadvance(13);
79
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(14, 2, role_r4.__mj_CreatedAt, "short"));
94
+ const ctx_r1 = i0.ɵɵnextContext(2);
95
+ i0.ɵɵadvance(2);
96
+ i0.ɵɵclassMap(ctx_r1.getRoleTypeClass(role_r4));
97
+ i0.ɵɵadvance();
98
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.getRoleTypeLabel(role_r4), " ");
99
+ i0.ɵɵadvance(2);
100
+ i0.ɵɵproperty("disabled", ctx_r1.isSystemRole(role_r4));
101
+ i0.ɵɵattribute("aria-label", "Edit " + role_r4.Name);
102
+ i0.ɵɵadvance(4);
103
+ i0.ɵɵproperty("disabled", ctx_r1.isSystemRole(role_r4));
104
+ i0.ɵɵattribute("aria-label", "Delete " + role_r4.Name);
105
+ i0.ɵɵadvance(16);
106
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(26, 9, role_r4.__mj_CreatedAt, "short"));
80
107
  i0.ɵɵadvance(7);
81
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(21, 5, role_r4.__mj_UpdatedAt, "short"));
108
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(33, 12, role_r4.__mj_UpdatedAt, "short"));
82
109
  } }
83
- function RoleManagementComponent_Conditional_58_For_3_Template(rf, ctx) { if (rf & 1) {
110
+ function RoleManagementComponent_Conditional_67_For_3_Template(rf, ctx) { if (rf & 1) {
84
111
  const _r3 = i0.ɵɵgetCurrentView();
85
- i0.ɵɵelementStart(0, "div", 42)(1, "div", 43);
86
- 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)); });
87
- i0.ɵɵelementStart(2, "div", 44)(3, "div", 45);
112
+ i0.ɵɵelementStart(0, "div", 50)(1, "div", 51);
113
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_67_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)); })("keydown.enter", function RoleManagementComponent_Conditional_67_For_3_Template_div_keydown_enter_1_listener() { const role_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleRoleExpansion(role_r4.ID)); })("keydown.space", function RoleManagementComponent_Conditional_67_For_3_Template_div_keydown_space_1_listener($event) { const role_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); ctx_r1.toggleRoleExpansion(role_r4.ID); return i0.ɵɵresetView($event.preventDefault()); });
114
+ i0.ɵɵelementStart(2, "div", 52)(3, "div", 53);
88
115
  i0.ɵɵelement(4, "i");
89
116
  i0.ɵɵelementEnd();
90
- i0.ɵɵelementStart(5, "div", 46)(6, "h3", 47);
117
+ i0.ɵɵelementStart(5, "div", 54)(6, "h3", 55);
91
118
  i0.ɵɵtext(7);
92
119
  i0.ɵɵelementEnd();
93
- i0.ɵɵelementStart(8, "p", 48);
120
+ i0.ɵɵelementStart(8, "p", 56);
94
121
  i0.ɵɵtext(9);
95
122
  i0.ɵɵelementEnd()()();
96
- i0.ɵɵelementStart(10, "div", 49)(11, "span", 50);
123
+ i0.ɵɵelementStart(10, "div", 57)(11, "span", 58);
97
124
  i0.ɵɵtext(12);
98
125
  i0.ɵɵelementEnd();
99
- i0.ɵɵelementStart(13, "div", 51);
100
- i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_58_For_3_Template_div_click_13_listener($event) { i0.ɵɵrestoreView(_r3); return i0.ɵɵresetView($event.stopPropagation()); });
101
- i0.ɵɵelementStart(14, "button", 52);
102
- 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)); });
103
- i0.ɵɵelement(15, "i", 53);
126
+ i0.ɵɵelementStart(13, "div", 59);
127
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_67_For_3_Template_div_click_13_listener($event) { i0.ɵɵrestoreView(_r3); return i0.ɵɵresetView($event.stopPropagation()); });
128
+ i0.ɵɵelementStart(14, "button", 60);
129
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_67_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)); });
130
+ i0.ɵɵelement(15, "i", 61);
104
131
  i0.ɵɵelementEnd();
105
- i0.ɵɵelementStart(16, "button", 54);
106
- 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)); });
107
- i0.ɵɵelement(17, "i", 55);
132
+ i0.ɵɵelementStart(16, "button", 62);
133
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_67_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)); });
134
+ i0.ɵɵelement(17, "i", 63);
108
135
  i0.ɵɵelementEnd()();
109
- i0.ɵɵelementStart(18, "button", 56);
110
- i0.ɵɵelement(19, "i", 57);
136
+ i0.ɵɵelementStart(18, "button", 64);
137
+ i0.ɵɵelement(19, "i", 65);
111
138
  i0.ɵɵelementEnd()()();
112
- i0.ɵɵtemplate(20, RoleManagementComponent_Conditional_58_For_3_Conditional_20_Template, 28, 8, "div", 58);
139
+ i0.ɵɵtemplate(20, RoleManagementComponent_Conditional_67_For_3_Conditional_20_Template, 40, 15, "div", 66);
113
140
  i0.ɵɵelementEnd();
114
141
  } if (rf & 2) {
115
142
  const role_r4 = ctx.$implicit;
116
143
  const ctx_r1 = i0.ɵɵnextContext(2);
117
144
  i0.ɵɵclassProp("expanded", ctx_r1.isRoleExpanded(role_r4.ID));
118
- i0.ɵɵadvance(4);
145
+ i0.ɵɵattribute("aria-expanded", ctx_r1.isRoleExpanded(role_r4.ID));
146
+ i0.ɵɵadvance();
147
+ i0.ɵɵattribute("aria-label", "Toggle details for " + role_r4.Name);
148
+ i0.ɵɵadvance(3);
119
149
  i0.ɵɵclassMap("fa-solid " + ctx_r1.getRoleIcon(role_r4));
120
150
  i0.ɵɵadvance(3);
121
151
  i0.ɵɵtextInterpolate(role_r4.Name);
@@ -127,25 +157,27 @@ function RoleManagementComponent_Conditional_58_For_3_Template(rf, ctx) { if (rf
127
157
  i0.ɵɵtextInterpolate1(" ", ctx_r1.getRoleTypeLabel(role_r4), " ");
128
158
  i0.ɵɵadvance(2);
129
159
  i0.ɵɵproperty("disabled", ctx_r1.isSystemRole(role_r4));
160
+ i0.ɵɵattribute("aria-label", "Edit " + role_r4.Name);
130
161
  i0.ɵɵadvance(2);
131
162
  i0.ɵɵproperty("disabled", ctx_r1.isSystemRole(role_r4));
163
+ i0.ɵɵattribute("aria-label", "Delete " + role_r4.Name);
132
164
  i0.ɵɵadvance(4);
133
165
  i0.ɵɵconditional(ctx_r1.isRoleExpanded(role_r4.ID) ? 20 : -1);
134
166
  } }
135
- function RoleManagementComponent_Conditional_58_Conditional_4_Template(rf, ctx) { if (rf & 1) {
136
- i0.ɵɵelementStart(0, "div", 41);
137
- i0.ɵɵelement(1, "i", 68);
138
- i0.ɵɵelementStart(2, "p", 69);
167
+ function RoleManagementComponent_Conditional_67_Conditional_4_Template(rf, ctx) { if (rf & 1) {
168
+ i0.ɵɵelementStart(0, "div", 49);
169
+ i0.ɵɵelement(1, "i", 80);
170
+ i0.ɵɵelementStart(2, "p", 81);
139
171
  i0.ɵɵtext(3, "No roles found");
140
172
  i0.ɵɵelementEnd();
141
- i0.ɵɵelementStart(4, "p", 70);
173
+ i0.ɵɵelementStart(4, "p", 82);
142
174
  i0.ɵɵtext(5, "Try adjusting your filters or create a new role");
143
175
  i0.ɵɵelementEnd()();
144
176
  } }
145
- function RoleManagementComponent_Conditional_58_Template(rf, ctx) { if (rf & 1) {
146
- i0.ɵɵelementStart(0, "div", 29)(1, "div", 39);
147
- i0.ɵɵrepeaterCreate(2, RoleManagementComponent_Conditional_58_For_3_Template, 21, 12, "div", 40, _forTrack0);
148
- i0.ɵɵtemplate(4, RoleManagementComponent_Conditional_58_Conditional_4_Template, 6, 0, "div", 41);
177
+ function RoleManagementComponent_Conditional_67_Template(rf, ctx) { if (rf & 1) {
178
+ i0.ɵɵelementStart(0, "div", 38)(1, "div", 47);
179
+ i0.ɵɵrepeaterCreate(2, RoleManagementComponent_Conditional_67_For_3_Template, 21, 16, "div", 48, _forTrack0);
180
+ i0.ɵɵtemplate(4, RoleManagementComponent_Conditional_67_Conditional_4_Template, 6, 0, "div", 49);
149
181
  i0.ɵɵelementEnd()();
150
182
  } if (rf & 2) {
151
183
  const ctx_r1 = i0.ɵɵnextContext();
@@ -154,44 +186,113 @@ function RoleManagementComponent_Conditional_58_Template(rf, ctx) { if (rf & 1)
154
186
  i0.ɵɵadvance(2);
155
187
  i0.ɵɵconditional(ctx_r1.filteredRoles.length === 0 ? 4 : -1);
156
188
  } }
157
- function RoleManagementComponent_Conditional_60_Template(rf, ctx) { if (rf & 1) {
158
- const _r5 = i0.ɵɵgetCurrentView();
159
- i0.ɵɵelementStart(0, "div", 71);
160
- i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_60_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
161
- i0.ɵɵelementStart(1, "div", 72);
162
- i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_60_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r5); return i0.ɵɵresetView($event.stopPropagation()); });
163
- i0.ɵɵelementStart(2, "div", 73)(3, "h3", 74);
164
- i0.ɵɵelement(4, "i", 75);
189
+ function RoleManagementComponent_Conditional_69_Conditional_19_Template(rf, ctx) { if (rf & 1) {
190
+ i0.ɵɵelement(0, "i", 96);
191
+ i0.ɵɵtext(1, " Deleting... ");
192
+ } }
193
+ function RoleManagementComponent_Conditional_69_Conditional_20_Template(rf, ctx) { if (rf & 1) {
194
+ i0.ɵɵelement(0, "i", 63);
195
+ i0.ɵɵtext(1, " Delete Role ");
196
+ } }
197
+ function RoleManagementComponent_Conditional_69_Template(rf, ctx) { if (rf & 1) {
198
+ const _r6 = i0.ɵɵgetCurrentView();
199
+ i0.ɵɵelementStart(0, "div", 83);
200
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_69_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
201
+ i0.ɵɵelementStart(1, "div", 84);
202
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_69_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r6); return i0.ɵɵresetView($event.stopPropagation()); });
203
+ i0.ɵɵelementStart(2, "div", 85)(3, "h3", 86);
204
+ i0.ɵɵelement(4, "i", 87);
165
205
  i0.ɵɵtext(5, " Confirm Delete ");
166
206
  i0.ɵɵelementEnd();
167
- i0.ɵɵelementStart(6, "button", 76);
168
- i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_60_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
169
- i0.ɵɵelement(7, "i", 77);
207
+ i0.ɵɵelementStart(6, "button", 88);
208
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_69_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
209
+ i0.ɵɵelement(7, "i", 89);
170
210
  i0.ɵɵelementEnd()();
171
- i0.ɵɵelementStart(8, "div", 78)(9, "p");
211
+ i0.ɵɵelementStart(8, "div", 90)(9, "p");
172
212
  i0.ɵɵtext(10, "Are you sure you want to delete the role ");
173
213
  i0.ɵɵelementStart(11, "strong");
174
214
  i0.ɵɵtext(12);
175
215
  i0.ɵɵelementEnd();
176
216
  i0.ɵɵtext(13, "?");
177
217
  i0.ɵɵelementEnd();
178
- i0.ɵɵelementStart(14, "p", 79);
179
- i0.ɵɵelement(15, "i", 80);
218
+ i0.ɵɵelementStart(14, "p", 91);
219
+ i0.ɵɵelement(15, "i", 92);
180
220
  i0.ɵɵtext(16, " This will affect all users assigned to this role. ");
181
221
  i0.ɵɵelementEnd()();
182
- i0.ɵɵelementStart(17, "div", 81)(18, "button", 82);
183
- i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_60_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
184
- i0.ɵɵtext(19, "Cancel");
222
+ i0.ɵɵelementStart(17, "div", 93)(18, "button", 94);
223
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_69_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.deleteRole()); });
224
+ i0.ɵɵtemplate(19, RoleManagementComponent_Conditional_69_Conditional_19_Template, 2, 0)(20, RoleManagementComponent_Conditional_69_Conditional_20_Template, 2, 0);
185
225
  i0.ɵɵelementEnd();
186
- i0.ɵɵelementStart(20, "button", 83);
187
- i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_60_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.deleteRole()); });
188
- i0.ɵɵelement(21, "i", 55);
189
- i0.ɵɵtext(22, " Delete Role ");
226
+ i0.ɵɵelementStart(21, "button", 95);
227
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_69_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
228
+ i0.ɵɵtext(22, " Cancel ");
190
229
  i0.ɵɵelementEnd()()()();
191
230
  } if (rf & 2) {
192
231
  const ctx_r1 = i0.ɵɵnextContext();
193
232
  i0.ɵɵadvance(12);
194
233
  i0.ɵɵtextInterpolate(ctx_r1.selectedRole.Name);
234
+ i0.ɵɵadvance(6);
235
+ i0.ɵɵproperty("disabled", ctx_r1.isLoading);
236
+ i0.ɵɵadvance();
237
+ i0.ɵɵconditional(ctx_r1.isLoading ? 19 : 20);
238
+ } }
239
+ function RoleManagementComponent_Conditional_70_Template(rf, ctx) { if (rf & 1) {
240
+ const _r7 = i0.ɵɵgetCurrentView();
241
+ i0.ɵɵelementStart(0, "div", 97);
242
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_70_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showMobileFilters = false); });
243
+ i0.ɵɵelementStart(1, "div", 98);
244
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_70_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r7); return i0.ɵɵresetView($event.stopPropagation()); });
245
+ i0.ɵɵelementStart(2, "div", 99)(3, "h3", 100);
246
+ i0.ɵɵelement(4, "i", 30);
247
+ i0.ɵɵtext(5, " Filters ");
248
+ i0.ɵɵelementEnd();
249
+ i0.ɵɵelementStart(6, "button", 101);
250
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_70_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showMobileFilters = false); });
251
+ i0.ɵɵelement(7, "i", 89);
252
+ i0.ɵɵelementEnd()();
253
+ i0.ɵɵelementStart(8, "div", 102)(9, "div", 103)(10, "div", 104)(11, "h4", 105);
254
+ i0.ɵɵtext(12, "Type");
255
+ i0.ɵɵelementEnd();
256
+ i0.ɵɵelementStart(13, "div", 106)(14, "label", 107)(15, "input", 108);
257
+ i0.ɵɵlistener("change", function RoleManagementComponent_Conditional_70_Template_input_change_15_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onTypeFilterChange("all")); });
258
+ i0.ɵɵelementEnd();
259
+ i0.ɵɵelementStart(16, "span", 109);
260
+ i0.ɵɵtext(17, "All Roles");
261
+ i0.ɵɵelementEnd()();
262
+ i0.ɵɵelementStart(18, "label", 107)(19, "input", 110);
263
+ i0.ɵɵlistener("change", function RoleManagementComponent_Conditional_70_Template_input_change_19_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onTypeFilterChange("system")); });
264
+ i0.ɵɵelementEnd();
265
+ i0.ɵɵelementStart(20, "span", 109);
266
+ i0.ɵɵtext(21, "System Roles");
267
+ i0.ɵɵelementEnd()();
268
+ i0.ɵɵelementStart(22, "label", 107)(23, "input", 111);
269
+ i0.ɵɵlistener("change", function RoleManagementComponent_Conditional_70_Template_input_change_23_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onTypeFilterChange("custom")); });
270
+ i0.ɵɵelementEnd();
271
+ i0.ɵɵelementStart(24, "span", 109);
272
+ i0.ɵɵtext(25, "Custom Roles");
273
+ i0.ɵɵelementEnd()()()()()();
274
+ i0.ɵɵelementStart(26, "div", 112)(27, "button", 113);
275
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_70_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showMobileFilters = false); });
276
+ i0.ɵɵtext(28, " Apply Filters ");
277
+ i0.ɵɵelementEnd();
278
+ i0.ɵɵelementStart(29, "button", 95);
279
+ i0.ɵɵlistener("click", function RoleManagementComponent_Conditional_70_Template_button_click_29_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showMobileFilters = false); });
280
+ i0.ɵɵtext(30, " Cancel ");
281
+ i0.ɵɵelementEnd()()()();
282
+ } if (rf & 2) {
283
+ const ctx_r1 = i0.ɵɵnextContext();
284
+ i0.ɵɵadvance(14);
285
+ i0.ɵɵclassProp("selected", ctx_r1.filters$.value.type === "all");
286
+ i0.ɵɵadvance();
287
+ i0.ɵɵproperty("checked", ctx_r1.filters$.value.type === "all");
288
+ i0.ɵɵadvance(3);
289
+ i0.ɵɵclassProp("selected", ctx_r1.filters$.value.type === "system");
290
+ i0.ɵɵadvance();
291
+ i0.ɵɵproperty("checked", ctx_r1.filters$.value.type === "system");
292
+ i0.ɵɵadvance(3);
293
+ i0.ɵɵclassProp("selected", ctx_r1.filters$.value.type === "custom");
294
+ i0.ɵɵadvance();
295
+ i0.ɵɵproperty("checked", ctx_r1.filters$.value.type === "custom");
195
296
  } }
196
297
  let RoleManagementComponent = class RoleManagementComponent extends BaseDashboard {
197
298
  // State management
@@ -219,6 +320,7 @@ let RoleManagementComponent = class RoleManagementComponent extends BaseDashboar
219
320
  showCreateDialog = false;
220
321
  showEditDialog = false;
221
322
  showDeleteConfirm = false;
323
+ showMobileFilters = false;
222
324
  expandedRoleId = null;
223
325
  // Role permissions (simplified view)
224
326
  rolePermissions = new Map();
@@ -395,85 +497,95 @@ let RoleManagementComponent = class RoleManagementComponent extends BaseDashboar
395
497
  }
396
498
  }
397
499
  static ɵfac = function RoleManagementComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RoleManagementComponent)(); };
398
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RoleManagementComponent, selectors: [["mj-role-management"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 61, vars: 20, consts: [[1, "role-management-container"], [1, "action-buttons"], [1, "mj-btn", "mj-btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-refresh"], [1, "mj-btn", "mj-btn-primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "mj-grid", "mj-grid-4"], [1, "mj-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, "mj-btn", "mj-btn-ghost", 3, "click"], [1, "loading-container"], [1, "error-container"], [1, "content-area"], [3, "result", "data", "visible"], [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, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click", "disabled"], [1, "fa-solid", "fa-edit"], ["title", "Delete", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", "text-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, "mj-btn", "mj-btn-secondary", 3, "click"], [1, "mj-btn", "mj-btn-primary", "text-danger", 3, "click"]], template: function RoleManagementComponent_Template(rf, ctx) { if (rf & 1) {
399
- i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "button", 2);
400
- i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_2_listener() { return ctx.refreshData(); });
401
- i0.ɵɵelement(3, "i", 3);
402
- i0.ɵɵtext(4, " Refresh ");
403
- i0.ɵɵelementEnd();
404
- i0.ɵɵelementStart(5, "button", 4);
405
- i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_5_listener() { return ctx.createNewRole(); });
406
- i0.ɵɵelement(6, "i", 5);
407
- i0.ɵɵtext(7, " Add Role ");
500
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RoleManagementComponent, selectors: [["mj-role-management"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 71, vars: 24, consts: [[1, "role-management-container"], [1, "sticky-header"], ["role", "toolbar", "aria-label", "Role management actions", 1, "action-buttons"], ["aria-label", "Refresh role list", 1, "mj-btn", "mj-btn-secondary", "mj-btn-icon-mobile", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-refresh"], [1, "btn-text"], ["aria-label", "Add new role", 1, "mj-btn", "mj-btn-primary", "mj-btn-icon-mobile", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], ["role", "region", "aria-label", "Role statistics", 1, "mj-grid-4"], [1, "mj-card"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-total"], [1, "fa-solid", "fa-user-tag"], [1, "stat-content"], ["aria-label", "Total roles count", 1, "stat-value"], [1, "stat-label"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-system"], [1, "fa-solid", "fa-shield-halved"], ["aria-label", "System roles count", 1, "stat-value"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-custom"], ["aria-label", "Custom roles count", 1, "stat-value"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-active"], [1, "fa-solid", "fa-check-circle"], ["aria-label", "Active roles count", 1, "stat-value"], ["role", "search", "aria-label", "Filter roles", 1, "filters-section"], [1, "filters-row"], [1, "mobile-search-container"], [1, "mj-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "mj-search-icon"], ["type", "text", "placeholder", "Search roles by name or description...", "aria-label", "Search roles by name or description", 1, "mj-search-input", 3, "input", "value"], ["aria-label", "Open filters", 1, "filter-button", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-filter"], [1, "mj-filter-group"], ["id", "type-filter-label", 1, "mj-filter-label"], ["role", "group", "aria-labelledby", "type-filter-label", 1, "mj-filter-buttons"], [1, "mj-btn", "mj-btn-ghost", 3, "click"], [1, "scrollable-content"], ["role", "status", "aria-live", "polite", "aria-busy", "true", 1, "loading-container"], ["role", "alert", "aria-live", "assertive", 1, "error-container"], [1, "content-area"], [3, "result", "data", "visible"], ["role", "presentation", 1, "modal-backdrop"], ["role", "presentation", 1, "filter-modal-backdrop"], ["text", "Loading roles...", "size", "medium"], [1, "error-content"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], ["aria-label", "Retry loading roles", 1, "mj-btn", "mj-btn-primary", 3, "click"], ["role", "list", "aria-label", "Roles list", 1, "roles-list"], ["role", "listitem", 1, "role-card", 3, "expanded"], ["role", "status", 1, "empty-state"], ["role", "listitem", 1, "role-card"], ["tabindex", "0", "role", "button", 1, "role-header", 3, "click", "keydown.enter", "keydown.space"], [1, "role-info"], ["aria-hidden", "true", 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, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-edit"], ["title", "Delete", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", "mj-btn-danger", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-trash"], ["aria-label", "Toggle details", 1, "expand-btn"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], [1, "role-content"], [1, "mobile-actions-bar", 3, "click"], [1, "mobile-action-buttons"], [1, "btn-label"], [1, "role-stats"], [1, "stat-item"], ["aria-hidden", "true", 1, "fa-solid", "fa-users"], [1, "stat-value"], ["aria-hidden", "true", 1, "fa-solid", "fa-calendar"], ["aria-hidden", "true", 1, "fa-solid", "fa-clock"], [1, "permissions-preview"], [1, "section-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-key"], [1, "permissions-note"], ["aria-hidden", "true", 1, "fa-solid", "fa-user-tag", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], ["role", "presentation", 1, "modal-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "delete-dialog-title", "aria-describedby", "delete-dialog-desc", 1, "modal-dialog", 3, "click"], [1, "modal-header"], ["id", "delete-dialog-title", 1, "modal-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "text-danger"], ["aria-label", "Close dialog", 1, "modal-close", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-times"], ["id", "delete-dialog-desc", 1, "modal-body"], [1, "text-warning"], ["aria-hidden", "true", 1, "fa-solid", "fa-warning"], [1, "modal-footer"], [1, "mj-btn", "mj-btn-danger", 3, "click", "disabled"], [1, "mj-btn", "mj-btn-secondary", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["role", "presentation", 1, "filter-modal-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "filter-modal-title", 1, "filter-modal", 3, "click"], [1, "filter-modal-header"], ["id", "filter-modal-title", 1, "filter-modal-title"], ["aria-label", "Close filters", 1, "filter-modal-close", 3, "click"], [1, "filter-modal-body"], [1, "filter-options-container"], [1, "filter-group"], [1, "filter-group-label"], [1, "filter-group-options"], [1, "filter-option"], ["type", "radio", "name", "type", "value", "all", 3, "change", "checked"], [1, "filter-option-label"], ["type", "radio", "name", "type", "value", "system", 3, "change", "checked"], ["type", "radio", "name", "type", "value", "custom", 3, "change", "checked"], [1, "filter-modal-footer"], [1, "mj-btn", "mj-btn-primary", 3, "click"]], template: function RoleManagementComponent_Template(rf, ctx) { if (rf & 1) {
501
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "button", 3);
502
+ i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_3_listener() { return ctx.refreshData(); });
503
+ i0.ɵɵelement(4, "i", 4);
504
+ i0.ɵɵelementStart(5, "span", 5);
505
+ i0.ɵɵtext(6, "Refresh");
408
506
  i0.ɵɵelementEnd()();
409
- i0.ɵɵelementStart(8, "div", 6)(9, "div", 7)(10, "div", 8);
410
- i0.ɵɵelement(11, "i", 9);
507
+ i0.ɵɵelementStart(7, "button", 6);
508
+ i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_7_listener() { return ctx.createNewRole(); });
509
+ i0.ɵɵelement(8, "i", 7);
510
+ i0.ɵɵelementStart(9, "span", 5);
511
+ i0.ɵɵtext(10, "Add Role");
512
+ i0.ɵɵelementEnd()()();
513
+ i0.ɵɵelementStart(11, "div", 8)(12, "div", 9)(13, "div", 10);
514
+ i0.ɵɵelement(14, "i", 11);
411
515
  i0.ɵɵelementEnd();
412
- i0.ɵɵelementStart(12, "div", 10)(13, "div", 11);
413
- i0.ɵɵtext(14);
516
+ i0.ɵɵelementStart(15, "div", 12)(16, "div", 13);
517
+ i0.ɵɵtext(17);
414
518
  i0.ɵɵelementEnd();
415
- i0.ɵɵelementStart(15, "div", 12);
416
- i0.ɵɵtext(16, "Total Roles");
519
+ i0.ɵɵelementStart(18, "div", 14);
520
+ i0.ɵɵtext(19, "Total Roles");
417
521
  i0.ɵɵelementEnd()()();
418
- i0.ɵɵelementStart(17, "div", 7)(18, "div", 13);
419
- i0.ɵɵelement(19, "i", 14);
522
+ i0.ɵɵelementStart(20, "div", 9)(21, "div", 15);
523
+ i0.ɵɵelement(22, "i", 16);
420
524
  i0.ɵɵelementEnd();
421
- i0.ɵɵelementStart(20, "div", 10)(21, "div", 11);
422
- i0.ɵɵtext(22);
525
+ i0.ɵɵelementStart(23, "div", 12)(24, "div", 17);
526
+ i0.ɵɵtext(25);
423
527
  i0.ɵɵelementEnd();
424
- i0.ɵɵelementStart(23, "div", 12);
425
- i0.ɵɵtext(24, "System Roles");
528
+ i0.ɵɵelementStart(26, "div", 14);
529
+ i0.ɵɵtext(27, "System Roles");
426
530
  i0.ɵɵelementEnd()()();
427
- i0.ɵɵelementStart(25, "div", 7)(26, "div", 15);
428
- i0.ɵɵelement(27, "i", 9);
531
+ i0.ɵɵelementStart(28, "div", 9)(29, "div", 18);
532
+ i0.ɵɵelement(30, "i", 11);
429
533
  i0.ɵɵelementEnd();
430
- i0.ɵɵelementStart(28, "div", 10)(29, "div", 11);
431
- i0.ɵɵtext(30);
534
+ i0.ɵɵelementStart(31, "div", 12)(32, "div", 19);
535
+ i0.ɵɵtext(33);
432
536
  i0.ɵɵelementEnd();
433
- i0.ɵɵelementStart(31, "div", 12);
434
- i0.ɵɵtext(32, "Custom Roles");
537
+ i0.ɵɵelementStart(34, "div", 14);
538
+ i0.ɵɵtext(35, "Custom Roles");
435
539
  i0.ɵɵelementEnd()()();
436
- i0.ɵɵelementStart(33, "div", 7)(34, "div", 16);
437
- i0.ɵɵelement(35, "i", 17);
540
+ i0.ɵɵelementStart(36, "div", 9)(37, "div", 20);
541
+ i0.ɵɵelement(38, "i", 21);
438
542
  i0.ɵɵelementEnd();
439
- i0.ɵɵelementStart(36, "div", 10)(37, "div", 11);
440
- i0.ɵɵtext(38);
543
+ i0.ɵɵelementStart(39, "div", 12)(40, "div", 22);
544
+ i0.ɵɵtext(41);
441
545
  i0.ɵɵelementEnd();
442
- i0.ɵɵelementStart(39, "div", 12);
443
- i0.ɵɵtext(40, "Active Roles");
546
+ i0.ɵɵelementStart(42, "div", 14);
547
+ i0.ɵɵtext(43, "Active Roles");
444
548
  i0.ɵɵelementEnd()()()();
445
- i0.ɵɵelementStart(41, "div", 18)(42, "div", 19)(43, "div", 20);
446
- i0.ɵɵelement(44, "i", 21);
447
- i0.ɵɵelementStart(45, "input", 22);
448
- i0.ɵɵlistener("input", function RoleManagementComponent_Template_input_input_45_listener($event) { return ctx.onSearchChange($event); });
549
+ i0.ɵɵelementStart(44, "div", 23)(45, "div", 24)(46, "div", 25)(47, "div", 26);
550
+ i0.ɵɵelement(48, "i", 27);
551
+ i0.ɵɵelementStart(49, "input", 28);
552
+ i0.ɵɵlistener("input", function RoleManagementComponent_Template_input_input_49_listener($event) { return ctx.onSearchChange($event); });
449
553
  i0.ɵɵelementEnd()();
450
- i0.ɵɵelementStart(46, "div", 23)(47, "label", 24);
451
- i0.ɵɵtext(48, "Type");
554
+ i0.ɵɵelementStart(50, "button", 29);
555
+ i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_50_listener() { return ctx.showMobileFilters = true; });
556
+ i0.ɵɵelement(51, "i", 30);
557
+ i0.ɵɵelementStart(52, "span");
558
+ i0.ɵɵtext(53, "Filters");
559
+ i0.ɵɵelementEnd()()();
560
+ i0.ɵɵelementStart(54, "div", 31)(55, "label", 32);
561
+ i0.ɵɵtext(56, "Type");
452
562
  i0.ɵɵelementEnd();
453
- i0.ɵɵelementStart(49, "div", 25)(50, "button", 26);
454
- i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_50_listener() { return ctx.onTypeFilterChange("all"); });
455
- i0.ɵɵtext(51, " All ");
563
+ i0.ɵɵelementStart(57, "div", 33)(58, "button", 34);
564
+ i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_58_listener() { return ctx.onTypeFilterChange("all"); });
565
+ i0.ɵɵtext(59, " All ");
456
566
  i0.ɵɵelementEnd();
457
- i0.ɵɵelementStart(52, "button", 26);
458
- i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_52_listener() { return ctx.onTypeFilterChange("system"); });
459
- i0.ɵɵtext(53, " System ");
567
+ i0.ɵɵelementStart(60, "button", 34);
568
+ i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_60_listener() { return ctx.onTypeFilterChange("system"); });
569
+ i0.ɵɵtext(61, " System ");
460
570
  i0.ɵɵelementEnd();
461
- i0.ɵɵelementStart(54, "button", 26);
462
- i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_54_listener() { return ctx.onTypeFilterChange("custom"); });
463
- i0.ɵɵtext(55, " Custom ");
464
- i0.ɵɵelementEnd()()()()();
465
- 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);
466
- i0.ɵɵelementStart(59, "mj-role-dialog", 30);
467
- i0.ɵɵlistener("result", function RoleManagementComponent_Template_mj_role_dialog_result_59_listener($event) { return ctx.onRoleDialogResult($event); });
571
+ i0.ɵɵelementStart(62, "button", 34);
572
+ i0.ɵɵlistener("click", function RoleManagementComponent_Template_button_click_62_listener() { return ctx.onTypeFilterChange("custom"); });
573
+ i0.ɵɵtext(63, " Custom ");
574
+ i0.ɵɵelementEnd()()()()()();
575
+ i0.ɵɵelementStart(64, "div", 35);
576
+ i0.ɵɵtemplate(65, RoleManagementComponent_Conditional_65_Template, 2, 0, "div", 36)(66, RoleManagementComponent_Conditional_66_Template, 8, 1, "div", 37)(67, RoleManagementComponent_Conditional_67_Template, 5, 1, "div", 38);
468
577
  i0.ɵɵelementEnd();
469
- i0.ɵɵtemplate(60, RoleManagementComponent_Conditional_60_Template, 23, 1, "div", 31);
578
+ i0.ɵɵelementStart(68, "mj-role-dialog", 39);
579
+ i0.ɵɵlistener("result", function RoleManagementComponent_Template_mj_role_dialog_result_68_listener($event) { return ctx.onRoleDialogResult($event); });
580
+ i0.ɵɵelementEnd();
581
+ i0.ɵɵtemplate(69, RoleManagementComponent_Conditional_69_Template, 23, 3, "div", 40)(70, RoleManagementComponent_Conditional_70_Template, 31, 9, "div", 41);
470
582
  i0.ɵɵelementEnd();
471
583
  } if (rf & 2) {
472
- i0.ɵɵadvance(2);
584
+ i0.ɵɵadvance(3);
473
585
  i0.ɵɵproperty("disabled", ctx.isLoading);
474
586
  i0.ɵɵadvance();
475
587
  i0.ɵɵclassProp("fa-spin", ctx.isLoading);
476
- i0.ɵɵadvance(11);
588
+ i0.ɵɵadvance(13);
477
589
  i0.ɵɵtextInterpolate(ctx.stats.totalRoles);
478
590
  i0.ɵɵadvance(8);
479
591
  i0.ɵɵtextInterpolate(ctx.stats.systemRoles);
@@ -481,25 +593,30 @@ let RoleManagementComponent = class RoleManagementComponent extends BaseDashboar
481
593
  i0.ɵɵtextInterpolate(ctx.stats.customRoles);
482
594
  i0.ɵɵadvance(8);
483
595
  i0.ɵɵtextInterpolate(ctx.stats.activeRoles);
484
- i0.ɵɵadvance(7);
596
+ i0.ɵɵadvance(8);
485
597
  i0.ɵɵproperty("value", ctx.filters$.value.search);
486
- i0.ɵɵadvance(5);
598
+ i0.ɵɵadvance(9);
487
599
  i0.ɵɵclassProp("mj-btn-primary", ctx.filters$.value.type === "all");
600
+ i0.ɵɵattribute("aria-pressed", ctx.filters$.value.type === "all");
488
601
  i0.ɵɵadvance(2);
489
602
  i0.ɵɵclassProp("mj-btn-primary", ctx.filters$.value.type === "system");
603
+ i0.ɵɵattribute("aria-pressed", ctx.filters$.value.type === "system");
490
604
  i0.ɵɵadvance(2);
491
605
  i0.ɵɵclassProp("mj-btn-primary", ctx.filters$.value.type === "custom");
492
- i0.ɵɵadvance(2);
493
- i0.ɵɵconditional(ctx.isLoading ? 56 : -1);
606
+ i0.ɵɵattribute("aria-pressed", ctx.filters$.value.type === "custom");
607
+ i0.ɵɵadvance(3);
608
+ i0.ɵɵconditional(ctx.isLoading ? 65 : -1);
494
609
  i0.ɵɵadvance();
495
- i0.ɵɵconditional(ctx.error && !ctx.isLoading ? 57 : -1);
610
+ i0.ɵɵconditional(ctx.error && !ctx.isLoading ? 66 : -1);
496
611
  i0.ɵɵadvance();
497
- i0.ɵɵconditional(!ctx.isLoading && !ctx.error ? 58 : -1);
612
+ i0.ɵɵconditional(!ctx.isLoading && !ctx.error ? 67 : -1);
498
613
  i0.ɵɵadvance();
499
614
  i0.ɵɵproperty("data", ctx.roleDialogData)("visible", ctx.showRoleDialog);
500
615
  i0.ɵɵadvance();
501
- i0.ɵɵconditional(ctx.showDeleteConfirm && ctx.selectedRole ? 60 : -1);
502
- } }, dependencies: [i1.RoleDialogComponent, i2.DatePipe], styles: ["@keyframes _ngcontent-%COMP%_shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.role-management-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.action-buttons[_ngcontent-%COMP%] {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 1rem 2rem;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n}\n@media (max-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n justify-content: center;\n flex-wrap: wrap;\n padding: 1rem;\n }\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n.btn-primary[_ngcontent-%COMP%]:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n.btn-secondary[_ngcontent-%COMP%]:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.btn-danger[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #f44336;\n color: white;\n}\n.btn-danger[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n.btn-danger[_ngcontent-%COMP%]:hover {\n background-color: #d32f2f;\n}\n\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 .stats-grid[_ngcontent-%COMP%] {\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;\n}\n.stat-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\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.stat-icon-total[_ngcontent-%COMP%] {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-system[_ngcontent-%COMP%] {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n.stat-icon-custom[_ngcontent-%COMP%] {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n}\n.stat-icon-active[_ngcontent-%COMP%] {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n\n.stat-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n.stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\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 .filters-row[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n.search-container[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 250px;\n position: relative;\n}\n.search-container[_ngcontent-%COMP%] .search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n}\n.search-container[_ngcontent-%COMP%] .search-input[_ngcontent-%COMP%] {\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.search-container[_ngcontent-%COMP%] .search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.filter-group[_ngcontent-%COMP%] .filter-label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n}\n.filter-group[_ngcontent-%COMP%] .filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.filter-group[_ngcontent-%COMP%] .filter-btn[_ngcontent-%COMP%] {\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.filter-group[_ngcontent-%COMP%] .filter-btn[_ngcontent-%COMP%]:hover {\n color: #374151;\n}\n.filter-group[_ngcontent-%COMP%] .filter-btn.active[_ngcontent-%COMP%] {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\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[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n max-height: calc(100vh - 450px);\n overflow-y: auto;\n padding-right: 0.5rem;\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.role-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n.role-card.expanded[_ngcontent-%COMP%] {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n.role-card.expanded[_ngcontent-%COMP%] .expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transform: rotate(180deg);\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.role-header[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\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-details[_ngcontent-%COMP%] .role-name[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n}\n.role-details[_ngcontent-%COMP%] .role-description[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0;\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.role-type-badge.badge-system[_ngcontent-%COMP%] {\n background: rgba(156, 39, 176, 0.1);\n color: #7b1fa2;\n}\n.role-type-badge.badge-custom[_ngcontent-%COMP%] {\n background: rgba(255, 152, 0, 0.1);\n color: #f57c00;\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.action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.action-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n color: #f44336;\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.expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.3s ease;\n}\n\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.role-stats[_ngcontent-%COMP%] .stat-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n}\n.role-stats[_ngcontent-%COMP%] .stat-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6b7280;\n}\n.role-stats[_ngcontent-%COMP%] .stat-item[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n color: #6b7280;\n}\n.role-stats[_ngcontent-%COMP%] .stat-item[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n color: #1f2937;\n font-weight: 500;\n}\n\n.permissions-preview[_ngcontent-%COMP%] {\n padding: 1rem;\n background: #f9fafb;\n border-radius: 8px;\n}\n.permissions-preview[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] {\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.permissions-preview[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #2196f3;\n}\n.permissions-preview[_ngcontent-%COMP%] .permissions-note[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.875rem;\n margin: 0;\n}\n\n.role-card[data-system=true][_ngcontent-%COMP%] .role-icon-wrapper[_ngcontent-%COMP%] {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n color: #6b7280;\n margin: 0;\n}\n\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.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%] {\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.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(2) {\n border-color: transparent #9c27b0 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.error-container[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n.error-container[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n}\n.error-container[_ngcontent-%COMP%] .error-message[_ngcontent-%COMP%] {\n color: #374151;\n margin-bottom: 1.5rem;\n}\n.error-container[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.error-container[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.error-container[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\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: _ngcontent-%COMP%_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-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\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.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%] {\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.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n}\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 1rem 0;\n color: #374151;\n}\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n.modal-body[_ngcontent-%COMP%] .text-warning[_ngcontent-%COMP%] {\n color: #f57c00;\n display: flex;\n align-items: center;\n gap: 0.5rem;\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@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\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@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.text-danger[_ngcontent-%COMP%] {\n color: #f44336;\n}"] });
616
+ i0.ɵɵconditional(ctx.showDeleteConfirm && ctx.selectedRole ? 69 : -1);
617
+ i0.ɵɵadvance();
618
+ i0.ɵɵconditional(ctx.showMobileFilters ? 70 : -1);
619
+ } }, dependencies: [i1.LoadingComponent, i2.RoleDialogComponent, i3.DatePipe], styles: ["\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n \n\n --md-primary: #0076B6;\n --md-on-primary: #FFFFFF;\n --md-primary-container: #AAE7FD;\n --md-on-primary-container: #001F2A;\n\n \n\n --md-secondary: #F5A623;\n --md-on-secondary: #FFFFFF;\n --md-secondary-container: #FFECD6;\n --md-on-secondary-container: #2D1600;\n\n \n\n --md-tertiary: #4CAF50;\n --md-on-tertiary: #FFFFFF;\n --md-tertiary-container: #C8E6C9;\n --md-on-tertiary-container: #002204;\n\n \n\n --md-error: #D32F2F;\n --md-on-error: #FFFFFF;\n --md-error-container: #FFCDD2;\n --md-on-error-container: #410002;\n\n \n\n --md-surface: #FAFCFF;\n --md-surface-dim: #D9DADE;\n --md-surface-bright: #FAFCFF;\n --md-surface-container-lowest: #FFFFFF;\n --md-surface-container-low: #F3F5F9;\n --md-surface-container: #EDF0F4;\n --md-surface-container-high: #E7EAEE;\n --md-surface-container-highest: #E1E3E8;\n --md-on-surface: #191C20;\n --md-on-surface-variant: #43474E;\n --md-outline: #74777F;\n --md-outline-variant: #C4C6D0;\n\n \n\n --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n --md-elevation-2: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n --md-elevation-3: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08);\n --md-elevation-4: 0 6px 12px rgba(0, 0, 0, 0.1), 0 12px 24px rgba(0, 0, 0, 0.08);\n --md-elevation-5: 0 8px 16px rgba(0, 0, 0, 0.12), 0 16px 32px rgba(0, 0, 0, 0.1);\n\n \n\n --md-corner-none: 0;\n --md-corner-extra-small: 4px;\n --md-corner-small: 8px;\n --md-corner-medium: 12px;\n --md-corner-large: 16px;\n --md-corner-extra-large: 28px;\n --md-corner-full: 9999px;\n\n \n\n --md-state-hover: 0.08;\n --md-state-focus: 0.12;\n --md-state-pressed: 0.12;\n\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n\n.role-management-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n position: relative;\n width: 100%;\n background: var(--md-surface);\n}\n\n\n\n\n\n.sticky-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--md-surface);\n border-bottom: 1px solid var(--md-outline-variant);\n box-shadow: var(--md-elevation-1);\n z-index: 10;\n}\n\n\n\n\n\n.scrollable-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--md-surface-container-lowest);\n}\n\n@media (min-width: 768px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem 2.5rem;\n }\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--md-surface);\n}\n\n@media (min-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons[_ngcontent-%COMP%] {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n\n\n\n\n.mj-grid-4[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.75rem;\n padding: 0 1rem 1rem 1rem;\n background: var(--md-surface);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1.25rem 1.5rem;\n gap: 1rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1.25rem;\n }\n}\n\n.mj-card[_ngcontent-%COMP%] {\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n padding: 1rem;\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--md-outline-variant);\n cursor: default;\n pointer-events: none;\n}\n\n@media (min-width: 768px) {\n .mj-card[_ngcontent-%COMP%] {\n padding: 1.125rem 1.25rem;\n }\n}\n\n\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--md-corner-medium);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .stat-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n\n\n.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--md-primary-container);\n color: var(--md-primary);\n}\n\n\n\n.stat-icon-system[_ngcontent-%COMP%] {\n background: var(--md-secondary-container);\n color: #B5751A;\n}\n\n\n\n.stat-icon-custom[_ngcontent-%COMP%] {\n background: var(--md-tertiary-container);\n color: var(--md-tertiary);\n}\n\n\n\n.stat-icon-active[_ngcontent-%COMP%] {\n background: var(--md-primary-container);\n color: var(--md-primary);\n}\n\n.stat-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--md-on-surface);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n }\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface-variant);\n margin-top: 0.25rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n }\n}\n\n\n\n\n\n.filters-section[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--md-surface-container-low);\n margin: 0 1rem 1rem 1rem;\n padding: 1rem;\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n}\n\n@media (min-width: 768px) {\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 1.5rem 1.25rem 1.5rem;\n padding: 1rem 1.25rem;\n }\n}\n\n.filters-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 1.25rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (min-width: 768px) {\n .filters-row[_ngcontent-%COMP%] {\n gap: 1.5rem;\n }\n}\n\n\n\n.mobile-search-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n align-items: center;\n flex: 1;\n min-width: 200px;\n}\n\n\n\n.mj-search[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 200px;\n position: relative;\n}\n\n@media (min-width: 640px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 280px;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 400px;\n max-width: 600px;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 500px;\n max-width: 800px;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n transition: color 0.2s ease;\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n left: 1.25rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-full);\n font-size: 1rem;\n background: var(--md-surface);\n color: var(--md-on-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem 1rem 3.25rem;\n font-size: 1.0625rem;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1.125rem 1.5rem 1.125rem 3.5rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--md-on-surface-variant);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--md-surface);\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:focus {\n box-shadow: var(--md-elevation-1), 0 0 0 3px rgba(0, 118, 182, 0.2);\n }\n}\n\n.mj-search[_ngcontent-%COMP%]:focus-within .mj-search-icon[_ngcontent-%COMP%] {\n color: var(--md-primary);\n}\n\n\n\n.mj-filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.mj-filter-group[_ngcontent-%COMP%] .mj-filter-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--md-on-surface-variant);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-group[_ngcontent-%COMP%] .mj-filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-full);\n padding: 4px;\n gap: 2px;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn-ghost[_ngcontent-%COMP%] {\n border-radius: var(--md-corner-full);\n padding: 0.5rem 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n transition: all 0.2s ease;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn-primary[_ngcontent-%COMP%] {\n background-color: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: #3395C8;\n}\n\n\n\n\n\n.mj-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n font-weight: 600;\n letter-spacing: 0.02em;\n border: none;\n border-radius: var(--md-corner-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.mj-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n\n\n.mj-btn-primary[_ngcontent-%COMP%] {\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.mj-btn-primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #4BA5D4;\n transform: scale(0.98);\n box-shadow: var(--md-elevation-1);\n}\n\n\n\n.mj-btn-secondary[_ngcontent-%COMP%] {\n background: var(--md-surface);\n color: var(--md-primary);\n border: 1px solid var(--md-outline);\n}\n\n.mj-btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.mj-btn-secondary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #005A8C;\n border-color: #005A8C;\n}\n\n\n\n.mj-btn-ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--md-on-surface-variant);\n}\n\n.mj-btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.mj-btn-ghost[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #005A8C;\n}\n\n\n\n.mj-btn-danger[_ngcontent-%COMP%] {\n background: var(--md-error);\n color: var(--md-on-error);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #E57373;\n box-shadow: var(--md-elevation-2);\n}\n\n.mj-btn-danger[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #EF9A9A;\n transform: scale(0.98);\n}\n\n\n\n.mj-btn-sm[_ngcontent-%COMP%] {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n\n\n.mj-btn-icon-only[_ngcontent-%COMP%] {\n padding: 0.625rem;\n min-width: 44px;\n min-height: 44px;\n}\n\n\n\n.mj-btn-icon-mobile[_ngcontent-%COMP%] {\n gap: 0.5rem;\n}\n\n.mj-btn-icon-mobile[_ngcontent-%COMP%] .btn-text[_ngcontent-%COMP%] {\n display: inline;\n}\n\n\n\n\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n overflow: visible;\n position: relative;\n background: var(--md-surface);\n border-radius: var(--md-corner-large);\n box-shadow: var(--md-elevation-1);\n padding: 1.25rem;\n border: 1px solid var(--md-outline-variant);\n}\n\n@media (min-width: 768px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n\n\n\n\n.roles-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n\n\n\n\n.role-card[_ngcontent-%COMP%] {\n background: var(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-large);\n overflow: hidden;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.role-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--md-elevation-2);\n border-color: var(--md-primary);\n}\n\n.role-card.expanded[_ngcontent-%COMP%] {\n box-shadow: var(--md-elevation-3);\n border-color: var(--md-primary);\n}\n\n.role-card.expanded[_ngcontent-%COMP%] .expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.role-header[_ngcontent-%COMP%] {\n padding: 1.25rem 1.5rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: var(--md-surface-container-lowest);\n transition: background-color 0.2s ease;\n}\n\n.role-header[_ngcontent-%COMP%]:hover {\n background: var(--md-surface-container-low);\n}\n\n.role-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex: 1;\n min-width: 0;\n}\n\n.role-icon-wrapper[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n border-radius: var(--md-corner-medium);\n background: var(--md-primary-container);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--md-primary);\n font-size: 1.375rem;\n flex-shrink: 0;\n}\n\n.role-details[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.role-details[_ngcontent-%COMP%] .role-name[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.25rem 0;\n word-break: break-word;\n overflow-wrap: break-word;\n}\n\n.role-details[_ngcontent-%COMP%] .role-description[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (max-width: 639px) {\n .role-details[_ngcontent-%COMP%] .role-description[_ngcontent-%COMP%] {\n white-space: normal;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n }\n}\n\n.role-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex-shrink: 0;\n}\n\n\n\n\n\n.role-type-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n\n\n.role-type-badge.badge-system[_ngcontent-%COMP%] {\n background: var(--md-secondary-container);\n color: #7A4D0C;\n border: 1px solid var(--md-secondary);\n}\n\n\n\n.role-type-badge.badge-custom[_ngcontent-%COMP%] {\n background: var(--md-tertiary-container);\n color: #1B5E20;\n border: 1px solid var(--md-tertiary);\n}\n\n\n\n\n\n.role-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.375rem;\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--md-corner-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n\n\n.role-content[_ngcontent-%COMP%] {\n padding: 1.5rem;\n background: var(--md-surface-container-lowest);\n border-top: 1px solid var(--md-outline-variant);\n animation: _ngcontent-%COMP%_slideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.mobile-actions-bar[_ngcontent-%COMP%] {\n display: none;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.role-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 2rem;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\n}\n\n.role-stats[_ngcontent-%COMP%] .stat-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.9375rem;\n padding: 0.5rem 1rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-small);\n}\n\n.role-stats[_ngcontent-%COMP%] .stat-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n font-size: 1rem;\n}\n\n.role-stats[_ngcontent-%COMP%] .stat-item[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n color: var(--md-on-surface-variant);\n}\n\n.role-stats[_ngcontent-%COMP%] .stat-item[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n color: var(--md-on-surface);\n font-weight: 600;\n}\n\n\n\n\n\n.permissions-preview[_ngcontent-%COMP%] {\n padding: 1.25rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n}\n\n.permissions-preview[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.5rem 0;\n}\n\n.permissions-preview[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n font-size: 1.125rem;\n}\n\n.permissions-preview[_ngcontent-%COMP%] .permissions-note[_ngcontent-%COMP%] {\n font-size: 0.9375rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--md-outline-variant);\n margin-bottom: 1.5rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n\n\n\n\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\n\n\n\n.error-container[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n font-size: 3.5rem;\n color: var(--md-error);\n margin-bottom: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-message[_ngcontent-%COMP%] {\n font-size: 1.0625rem;\n color: var(--md-on-surface);\n margin: 0 0 1.5rem 0;\n}\n\n\n\n\n\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.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 1rem;\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n background: var(--md-surface);\n border-radius: var(--md-corner-extra-large);\n box-shadow: var(--md-elevation-5);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);\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 var(--md-outline-variant);\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--md-corner-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--md-on-surface);\n margin: 0 0 1rem 0;\n line-height: 1.6;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.modal-body[_ngcontent-%COMP%] .text-warning[_ngcontent-%COMP%] {\n color: var(--md-secondary);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: var(--md-secondary-container);\n border-radius: var(--md-corner-small);\n font-weight: 500;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--md-outline-variant);\n background: var(--md-surface-container-low);\n}\n\n\n\n\n\n.text-danger[_ngcontent-%COMP%] {\n color: var(--md-error);\n}\n\n.text-warning[_ngcontent-%COMP%] {\n color: var(--md-secondary);\n}\n\n\n\n\n\n@media (min-width: 1440px) {\n .role-management-container[_ngcontent-%COMP%] {\n max-width: 1920px;\n margin: 0 auto;\n }\n\n .action-buttons[_ngcontent-%COMP%] {\n padding: 1rem 2rem;\n }\n\n .mj-grid-4[_ngcontent-%COMP%] {\n padding: 0 2rem 1.25rem 2rem;\n gap: 1.5rem;\n }\n\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 2rem 1.25rem 2rem;\n padding: 1.25rem 1.5rem;\n }\n\n .content-area[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_fadeIn {\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\n\n\n\n.mj-search-input[_ngcontent-%COMP%]:focus-visible, \nbutton[_ngcontent-%COMP%]:focus-visible, \n.mj-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n.filter-button[_ngcontent-%COMP%] {\n display: none;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n border: 2px solid var(--md-outline-variant);\n background: var(--md-surface);\n color: var(--md-on-surface);\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n min-width: 44px;\n}\n\n.filter-button[_ngcontent-%COMP%]:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.filter-button[_ngcontent-%COMP%]:active {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.filter-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n\n\n\n\n.filter-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.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: flex-end;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 0;\n}\n\n.filter-modal[_ngcontent-%COMP%] {\n background: var(--md-surface);\n border-radius: var(--md-corner-extra-large) var(--md-corner-extra-large) 0 0;\n box-shadow: var(--md-elevation-5);\n width: 100%;\n max-height: 80vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUpFromBottom 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n}\n\n.filter-modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 1.5rem;\n border-bottom: 1px solid var(--md-outline-variant);\n flex-shrink: 0;\n}\n\n.filter-modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n}\n\n.filter-modal-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n font-size: 1.375rem;\n}\n\n.filter-modal-close[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--md-corner-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-modal-close[_ngcontent-%COMP%]:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.filter-modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n flex: 1;\n}\n\n.filter-modal-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n padding: 1.25rem 1.5rem;\n border-top: 1px solid var(--md-outline-variant);\n background: var(--md-surface-container-low);\n flex-shrink: 0;\n}\n\n.filter-modal-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n margin: 0;\n}\n\n\n\n.filter-options-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.filter-group-label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n}\n\n.filter-group-options[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.filter-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.875rem 1rem;\n background: var(--md-surface-container-low);\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.filter-option[_ngcontent-%COMP%]:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container);\n}\n\n.filter-option.selected[_ngcontent-%COMP%] {\n background: var(--md-primary-container);\n border-color: var(--md-primary);\n color: var(--md-primary);\n}\n\n.filter-option[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%], \n.filter-option[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--md-primary);\n flex-shrink: 0;\n}\n\n.filter-option-label[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 1rem;\n font-weight: 500;\n color: var(--md-on-surface);\n}\n\n.filter-option.selected[_ngcontent-%COMP%] .filter-option-label[_ngcontent-%COMP%] {\n color: var(--md-primary);\n font-weight: 600;\n}\n\n\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideUpFromBottom {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n\n\n\n\n@media (max-width: 639px) {\n .sticky-header[_ngcontent-%COMP%] {\n padding: 0;\n }\n\n .action-buttons[_ngcontent-%COMP%] {\n padding: 0.5rem 0.75rem;\n gap: 0.5rem;\n justify-content: flex-end;\n }\n\n .mj-btn-icon-mobile[_ngcontent-%COMP%] {\n padding: 0.5rem 0.75rem;\n min-height: 40px;\n gap: 0;\n }\n\n .mj-btn-icon-mobile[_ngcontent-%COMP%] .btn-text[_ngcontent-%COMP%] {\n display: none;\n }\n\n .mj-btn-icon-mobile[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n\n .mj-grid-4[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 0.5rem 0.5rem 0.5rem;\n padding: 0.75rem;\n border-radius: var(--md-corner-small);\n }\n\n .filters-row[_ngcontent-%COMP%] {\n gap: 0.75rem;\n flex-direction: row;\n align-items: center;\n }\n\n \n\n .mobile-search-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n width: 100%;\n }\n\n .mj-search[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 0.75rem 1rem 0.75rem 2.5rem;\n min-height: 44px;\n font-size: 1rem;\n border-width: 1.5px;\n }\n\n .mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n left: 0.875rem;\n font-size: 1rem;\n }\n\n \n\n .mj-filter-group[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n \n\n .filter-button[_ngcontent-%COMP%] {\n display: inline-flex !important;\n flex-shrink: 0;\n }\n\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 0.75rem;\n }\n\n .content-area[_ngcontent-%COMP%] {\n padding: 0.75rem;\n border-radius: var(--md-corner-medium);\n }\n\n .modal-backdrop[_ngcontent-%COMP%] {\n padding: 0.5rem;\n }\n\n .modal-dialog[_ngcontent-%COMP%] {\n border-radius: var(--md-corner-large);\n max-height: 95vh;\n }\n\n .modal-footer[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .modal-footer[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n\n .roles-list[_ngcontent-%COMP%] {\n gap: 0.75rem;\n }\n\n .role-card[_ngcontent-%COMP%] {\n border-radius: var(--md-corner-medium);\n overflow: hidden;\n }\n\n .role-header[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n gap: 0.75rem;\n padding: 1rem;\n }\n\n .role-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n flex-direction: row;\n align-items: flex-start;\n gap: 0.875rem;\n }\n\n .role-icon-wrapper[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n flex-shrink: 0;\n }\n\n .role-details[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .role-details[_ngcontent-%COMP%] .role-name[_ngcontent-%COMP%] {\n font-size: 1rem;\n line-height: 1.3;\n margin-bottom: 0.125rem;\n }\n\n .role-details[_ngcontent-%COMP%] .role-description[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n -webkit-line-clamp: 1;\n line-clamp: 1;\n }\n\n .role-meta[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: flex-end;\n padding-top: 0;\n border-top: none;\n width: auto;\n }\n\n .role-meta[_ngcontent-%COMP%] .role-type-badge[_ngcontent-%COMP%] {\n display: none;\n }\n\n .role-meta[_ngcontent-%COMP%] .role-actions[_ngcontent-%COMP%] {\n display: none;\n }\n\n .expand-btn[_ngcontent-%COMP%] {\n flex-shrink: 0;\n min-width: 40px;\n min-height: 40px;\n padding: 0.5rem;\n }\n\n .expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n }\n\n .mobile-actions-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.75rem;\n padding: 0.875rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n margin-bottom: 1rem;\n }\n\n .mobile-actions-bar[_ngcontent-%COMP%] .role-type-badge[_ngcontent-%COMP%] {\n padding: 0.375rem 0.75rem;\n font-size: 0.6875rem;\n }\n\n .mobile-action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n }\n\n .mobile-action-buttons[_ngcontent-%COMP%] .mj-btn-sm[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.5rem 0.875rem;\n min-height: 36px;\n }\n\n .mobile-action-buttons[_ngcontent-%COMP%] .mj-btn-sm[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n\n .mobile-action-buttons[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n font-weight: 500;\n }\n\n .role-stats[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 0.5rem;\n margin-bottom: 1rem;\n }\n\n .role-content[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .permissions-preview[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 3rem 1.5rem;\n }\n\n .empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 3rem;\n }\n\n .loading-container[_ngcontent-%COMP%] {\n padding: 3rem 1.5rem;\n }\n}\n\n\n\n@media (max-width: 374px) {\n .action-buttons[_ngcontent-%COMP%] {\n padding: 0.375rem 0.5rem;\n }\n\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 0.375rem 0.375rem 0.375rem;\n padding: 0.5rem;\n }\n\n .mobile-search-container[_ngcontent-%COMP%] {\n gap: 0.375rem;\n }\n\n .filter-button[_ngcontent-%COMP%] {\n padding: 0.625rem;\n min-width: 40px;\n }\n\n .filter-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: none;\n }\n\n .filter-modal-header[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n\n .filter-modal-body[_ngcontent-%COMP%] {\n padding: 1.25rem;\n }\n\n .filter-modal-footer[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 0.5rem;\n }\n\n .content-area[_ngcontent-%COMP%] {\n padding: 0.5rem;\n }\n\n .role-header[_ngcontent-%COMP%] {\n padding: 0.75rem;\n }\n}"] });
503
620
  };
504
621
  RoleManagementComponent = __decorate([
505
622
  RegisterClass(BaseDashboard, 'RoleManagement')
@@ -507,7 +624,7 @@ RoleManagementComponent = __decorate([
507
624
  export { RoleManagementComponent };
508
625
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RoleManagementComponent, [{
509
626
  type: Component,
510
- args: [{ selector: 'mj-role-management', template: "<div class=\"role-management-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button class=\"mj-btn mj-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=\"mj-btn mj-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=\"mj-grid mj-grid-4\">\n <div class=\"mj-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=\"mj-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=\"mj-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=\"mj-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=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.type === 'all'\"\n (click)=\"onTypeFilterChange('all')\"\n >\n All\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.type === 'system'\"\n (click)=\"onTypeFilterChange('system')\"\n >\n System\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"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=\"mj-btn mj-btn-ghost mj-btn-sm\" (click)=\"editRole(role)\" title=\"Edit\" [disabled]=\"isSystemRole(role)\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm text-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 <!-- Role Create/Edit Dialog -->\n <mj-role-dialog \n [data]=\"roleDialogData\"\n [visible]=\"showRoleDialog\"\n (result)=\"onRoleDialogResult($event)\">\n </mj-role-dialog>\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=\"mj-btn mj-btn-secondary\" (click)=\"showDeleteConfirm = false\">Cancel</button>\n <button class=\"mj-btn mj-btn-primary text-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: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.role-management-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.action-buttons {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 1rem 2rem;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n}\n@media (max-width: 768px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n padding: 1rem;\n }\n}\n\n.btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary i {\n font-size: 0.875rem;\n}\n.btn-primary:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n.btn-secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary i {\n font-size: 0.875rem;\n}\n.btn-secondary:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #f44336;\n color: white;\n}\n.btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-danger i {\n font-size: 0.875rem;\n}\n.btn-danger:hover {\n background-color: #d32f2f;\n}\n\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 .stats-grid {\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;\n}\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\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.stat-icon-total {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-system {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n.stat-icon-custom {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n}\n.stat-icon-active {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n\n.stat-content {\n flex: 1;\n}\n.stat-content .stat-value {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content .stat-label {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\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 .filters-row {\n gap: 1rem;\n }\n}\n\n.search-container {\n flex: 1;\n min-width: 250px;\n position: relative;\n}\n.search-container .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n}\n.search-container .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.search-container .search-input:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.filter-group .filter-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n}\n.filter-group .filter-buttons {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.filter-group .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.filter-group .filter-btn:hover {\n color: #374151;\n}\n.filter-group .filter-btn.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.content-area {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\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 display: flex;\n flex-direction: column;\n gap: 1rem;\n max-height: calc(100vh - 450px);\n overflow-y: auto;\n padding-right: 0.5rem;\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.role-card:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n.role-card.expanded {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n.role-card.expanded .expand-btn i {\n transform: rotate(180deg);\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.role-header:hover {\n background: #f3f4f6;\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-details .role-name {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n}\n.role-details .role-description {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0;\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.role-type-badge.badge-system {\n background: rgba(156, 39, 176, 0.1);\n color: #7b1fa2;\n}\n.role-type-badge.badge-custom {\n background: rgba(255, 152, 0, 0.1);\n color: #f57c00;\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.action-btn:hover:not(:disabled) {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.action-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.action-btn-danger:hover:not(:disabled) {\n color: #f44336;\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.expand-btn i {\n transition: transform 0.3s ease;\n}\n\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.role-stats .stat-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n}\n.role-stats .stat-item i {\n color: #6b7280;\n}\n.role-stats .stat-item .stat-label {\n color: #6b7280;\n}\n.role-stats .stat-item .stat-value {\n color: #1f2937;\n font-weight: 500;\n}\n\n.permissions-preview {\n padding: 1rem;\n background: #f9fafb;\n border-radius: 8px;\n}\n.permissions-preview .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.permissions-preview .section-title i {\n color: #2196f3;\n}\n.permissions-preview .permissions-note {\n color: #6b7280;\n font-size: 0.875rem;\n margin: 0;\n}\n\n.role-card[data-system=true] .role-icon-wrapper {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state .empty-icon {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state .empty-subtext {\n color: #6b7280;\n margin: 0;\n}\n\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.loading-spinner .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.loading-spinner .spinner-ring:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner .spinner-ring:nth-child(2) {\n border-color: transparent #9c27b0 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner .spinner-ring:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n.error-container .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n}\n.error-container .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n}\n.error-container .retry-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.error-container .retry-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.error-container .retry-button i {\n font-size: 0.875rem;\n}\n\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-header .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.modal-header .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.modal-header .modal-close:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n.modal-body p {\n margin: 0 0 1rem 0;\n color: #374151;\n}\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n.modal-body .text-warning {\n color: #f57c00;\n display: flex;\n align-items: center;\n gap: 0.5rem;\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@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\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@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 500px;\n }\n}\n.text-danger {\n color: #f44336;\n}\n"] }]
627
+ args: [{ selector: 'mj-role-management', template: "<div class=\"role-management-container\">\n <!-- Sticky Header Section -->\n <div class=\"sticky-header\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\" role=\"toolbar\" aria-label=\"Role management actions\">\n <button\n class=\"mj-btn mj-btn-secondary mj-btn-icon-mobile\"\n (click)=\"refreshData()\"\n [disabled]=\"isLoading\"\n aria-label=\"Refresh role list\"\n >\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Refresh</span>\n </button>\n <button\n class=\"mj-btn mj-btn-primary mj-btn-icon-mobile\"\n (click)=\"createNewRole()\"\n aria-label=\"Add new role\"\n >\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Add Role</span>\n </button>\n </div>\n\n <!-- Stats Cards -->\n <div class=\"mj-grid-4\" role=\"region\" aria-label=\"Role statistics\">\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-total\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-user-tag\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Total roles count\">{{ stats.totalRoles }}</div>\n <div class=\"stat-label\">Total Roles</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-system\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"System roles count\">{{ stats.systemRoles }}</div>\n <div class=\"stat-label\">System Roles</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-custom\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-user-tag\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Custom roles count\">{{ stats.customRoles }}</div>\n <div class=\"stat-label\">Custom Roles</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-active\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-check-circle\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Active roles count\">{{ 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\" role=\"search\" aria-label=\"Filter roles\">\n <div class=\"filters-row\">\n <!-- Mobile: Search + Filter Button Container -->\n <div class=\"mobile-search-container\">\n <!-- Search - Enhanced prominent search box -->\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n class=\"mj-search-input\"\n placeholder=\"Search roles by name or description...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.search\"\n aria-label=\"Search roles by name or description\"\n />\n </div>\n\n <!-- Filter Button (Mobile Only) -->\n <button\n class=\"filter-button\"\n (click)=\"showMobileFilters = true\"\n aria-label=\"Open filters\"\n >\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n <span>Filters</span>\n </button>\n </div>\n\n <!-- Type Filter (Desktop) -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\" id=\"type-filter-label\">Type</label>\n <div class=\"mj-filter-buttons\" role=\"group\" aria-labelledby=\"type-filter-label\">\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.type === 'all'\"\n (click)=\"onTypeFilterChange('all')\"\n [attr.aria-pressed]=\"filters$.value.type === 'all'\"\n >\n All\n </button>\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.type === 'system'\"\n (click)=\"onTypeFilterChange('system')\"\n [attr.aria-pressed]=\"filters$.value.type === 'system'\"\n >\n System\n </button>\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.type === 'custom'\"\n (click)=\"onTypeFilterChange('custom')\"\n [attr.aria-pressed]=\"filters$.value.type === 'custom'\"\n >\n Custom\n </button>\n </div>\n </div>\n </div>\n </div>\n </div><!-- End Sticky Header -->\n\n <!-- Scrollable Content Section -->\n <div class=\"scrollable-content\">\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading roles...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\" aria-live=\"assertive\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\" aria-hidden=\"true\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"mj-btn mj-btn-primary\" (click)=\"loadInitialData()\" aria-label=\"Retry loading roles\">\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></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\" role=\"list\" aria-label=\"Roles list\">\n @for (role of filteredRoles; track role.ID) {\n <div\n class=\"role-card\"\n [class.expanded]=\"isRoleExpanded(role.ID)\"\n role=\"listitem\"\n [attr.aria-expanded]=\"isRoleExpanded(role.ID)\"\n >\n <div\n class=\"role-header\"\n (click)=\"toggleRoleExpansion(role.ID)\"\n tabindex=\"0\"\n (keydown.enter)=\"toggleRoleExpansion(role.ID)\"\n (keydown.space)=\"toggleRoleExpansion(role.ID); $event.preventDefault()\"\n role=\"button\"\n [attr.aria-label]=\"'Toggle details for ' + role.Name\"\n >\n <div class=\"role-info\">\n <div class=\"role-icon-wrapper\" aria-hidden=\"true\">\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\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n (click)=\"editRole(role)\"\n title=\"Edit\"\n [attr.aria-label]=\"'Edit ' + role.Name\"\n [disabled]=\"isSystemRole(role)\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm mj-btn-danger\"\n (click)=\"confirmDeleteRole(role)\"\n title=\"Delete\"\n [attr.aria-label]=\"'Delete ' + role.Name\"\n [disabled]=\"isSystemRole(role)\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button class=\"expand-btn\" aria-label=\"Toggle details\">\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n @if (isRoleExpanded(role.ID)) {\n <div class=\"role-content\">\n <!-- Mobile-only actions bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"role-type-badge\" [class]=\"getRoleTypeClass(role)\">\n {{ getRoleTypeLabel(role) }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n (click)=\"editRole(role)\"\n title=\"Edit\"\n [attr.aria-label]=\"'Edit ' + role.Name\"\n [disabled]=\"isSystemRole(role)\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm mj-btn-danger\"\n (click)=\"confirmDeleteRole(role)\"\n title=\"Delete\"\n [attr.aria-label]=\"'Delete ' + role.Name\"\n [disabled]=\"isSystemRole(role)\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Delete</span>\n </button>\n </div>\n </div>\n\n <div class=\"role-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-users\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Users:</span>\n <span class=\"stat-value\">0</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-calendar\" aria-hidden=\"true\"></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\" aria-hidden=\"true\"></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\" aria-hidden=\"true\"></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\" role=\"status\">\n <i class=\"fa-solid fa-user-tag empty-icon\" aria-hidden=\"true\"></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 </div><!-- End Scrollable Content -->\n\n <!-- Role Create/Edit Dialog -->\n <mj-role-dialog\n [data]=\"roleDialogData\"\n [visible]=\"showRoleDialog\"\n (result)=\"onRoleDialogResult($event)\">\n </mj-role-dialog>\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedRole) {\n <div\n class=\"modal-backdrop\"\n (click)=\"showDeleteConfirm = false\"\n role=\"presentation\"\n >\n <div\n class=\"modal-dialog\"\n (click)=\"$event.stopPropagation()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"delete-dialog-title\"\n aria-describedby=\"delete-dialog-desc\"\n >\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"delete-dialog-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n Confirm Delete\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"showDeleteConfirm = false\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"delete-dialog-desc\">\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\" aria-hidden=\"true\"></i>\n This will affect all users assigned to this role.\n </p>\n </div>\n <div class=\"modal-footer\">\n <!-- Primary action (Delete) on LEFT per MD3 design guide -->\n <button class=\"mj-btn mj-btn-danger\" (click)=\"deleteRole()\" [disabled]=\"isLoading\">\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Deleting...\n } @else {\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n Delete Role\n }\n </button>\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"showDeleteConfirm = false\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Mobile Filter Modal -->\n @if (showMobileFilters) {\n <div\n class=\"filter-modal-backdrop\"\n (click)=\"showMobileFilters = false\"\n role=\"presentation\"\n >\n <div\n class=\"filter-modal\"\n (click)=\"$event.stopPropagation()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"filter-modal-title\"\n >\n <div class=\"filter-modal-header\">\n <h3 class=\"filter-modal-title\" id=\"filter-modal-title\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n Filters\n </h3>\n <button\n class=\"filter-modal-close\"\n (click)=\"showMobileFilters = false\"\n aria-label=\"Close filters\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <div class=\"filter-modal-body\">\n <div class=\"filter-options-container\">\n <!-- Type Filter -->\n <div class=\"filter-group\">\n <h4 class=\"filter-group-label\">Type</h4>\n <div class=\"filter-group-options\">\n <label\n class=\"filter-option\"\n [class.selected]=\"filters$.value.type === 'all'\"\n >\n <input\n type=\"radio\"\n name=\"type\"\n value=\"all\"\n [checked]=\"filters$.value.type === 'all'\"\n (change)=\"onTypeFilterChange('all')\"\n />\n <span class=\"filter-option-label\">All Roles</span>\n </label>\n <label\n class=\"filter-option\"\n [class.selected]=\"filters$.value.type === 'system'\"\n >\n <input\n type=\"radio\"\n name=\"type\"\n value=\"system\"\n [checked]=\"filters$.value.type === 'system'\"\n (change)=\"onTypeFilterChange('system')\"\n />\n <span class=\"filter-option-label\">System Roles</span>\n </label>\n <label\n class=\"filter-option\"\n [class.selected]=\"filters$.value.type === 'custom'\"\n >\n <input\n type=\"radio\"\n name=\"type\"\n value=\"custom\"\n [checked]=\"filters$.value.type === 'custom'\"\n (change)=\"onTypeFilterChange('custom')\"\n />\n <span class=\"filter-option-label\">Custom Roles</span>\n </label>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"filter-modal-footer\">\n <button\n class=\"mj-btn mj-btn-primary\"\n (click)=\"showMobileFilters = false\"\n >\n Apply Filters\n </button>\n <button\n class=\"mj-btn mj-btn-secondary\"\n (click)=\"showMobileFilters = false\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: ["/* =============================================================================\n Role Management Component - Material Design 3\n Custom Color Palette Implementation\n ============================================================================= */\n\n/* -----------------------------------------------------------------------------\n Custom Color Palette - MD3 Color Roles\n ----------------------------------------------------------------------------- */\n:host {\n /* Primary - Deep Blue */\n --md-primary: #0076B6;\n --md-on-primary: #FFFFFF;\n --md-primary-container: #AAE7FD;\n --md-on-primary-container: #001F2A;\n\n /* Secondary - Light Orange */\n --md-secondary: #F5A623;\n --md-on-secondary: #FFFFFF;\n --md-secondary-container: #FFECD6;\n --md-on-secondary-container: #2D1600;\n\n /* Tertiary - Light Green */\n --md-tertiary: #4CAF50;\n --md-on-tertiary: #FFFFFF;\n --md-tertiary-container: #C8E6C9;\n --md-on-tertiary-container: #002204;\n\n /* Error - Red */\n --md-error: #D32F2F;\n --md-on-error: #FFFFFF;\n --md-error-container: #FFCDD2;\n --md-on-error-container: #410002;\n\n /* Surface Colors */\n --md-surface: #FAFCFF;\n --md-surface-dim: #D9DADE;\n --md-surface-bright: #FAFCFF;\n --md-surface-container-lowest: #FFFFFF;\n --md-surface-container-low: #F3F5F9;\n --md-surface-container: #EDF0F4;\n --md-surface-container-high: #E7EAEE;\n --md-surface-container-highest: #E1E3E8;\n --md-on-surface: #191C20;\n --md-on-surface-variant: #43474E;\n --md-outline: #74777F;\n --md-outline-variant: #C4C6D0;\n\n /* Elevation Shadows */\n --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n --md-elevation-2: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n --md-elevation-3: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08);\n --md-elevation-4: 0 6px 12px rgba(0, 0, 0, 0.1), 0 12px 24px rgba(0, 0, 0, 0.08);\n --md-elevation-5: 0 8px 16px rgba(0, 0, 0, 0.12), 0 16px 32px rgba(0, 0, 0, 0.1);\n\n /* Corner Radii */\n --md-corner-none: 0;\n --md-corner-extra-small: 4px;\n --md-corner-small: 8px;\n --md-corner-medium: 12px;\n --md-corner-large: 16px;\n --md-corner-extra-large: 28px;\n --md-corner-full: 9999px;\n\n /* State Layers */\n --md-state-hover: 0.08;\n --md-state-focus: 0.12;\n --md-state-pressed: 0.12;\n\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Container & Layout\n ----------------------------------------------------------------------------- */\n.role-management-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n position: relative;\n width: 100%;\n background: var(--md-surface);\n}\n\n/* -----------------------------------------------------------------------------\n Sticky Header\n ----------------------------------------------------------------------------- */\n.sticky-header {\n flex-shrink: 0;\n background: var(--md-surface);\n border-bottom: 1px solid var(--md-outline-variant);\n box-shadow: var(--md-elevation-1);\n z-index: 10;\n}\n\n/* -----------------------------------------------------------------------------\n Scrollable Content\n ----------------------------------------------------------------------------- */\n.scrollable-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--md-surface-container-lowest);\n}\n\n@media (min-width: 768px) {\n .scrollable-content {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .scrollable-content {\n padding: 2rem 2.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons\n ----------------------------------------------------------------------------- */\n.action-buttons {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--md-surface);\n}\n\n@media (min-width: 768px) {\n .action-buttons {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Statistics Cards\n ----------------------------------------------------------------------------- */\n.mj-grid-4 {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.75rem;\n padding: 0 1rem 1rem 1rem;\n background: var(--md-surface);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4 {\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1.25rem 1.5rem;\n gap: 1rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4 {\n gap: 1.25rem;\n }\n}\n\n.mj-card {\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n padding: 1rem;\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--md-outline-variant);\n cursor: default;\n pointer-events: none;\n}\n\n@media (min-width: 768px) {\n .mj-card {\n padding: 1.125rem 1.25rem;\n }\n}\n\n/* Stat Icon Styles */\n.stat-icon {\n width: 48px;\n height: 48px;\n border-radius: var(--md-corner-medium);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .stat-icon {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n/* Total Roles - Primary */\n.stat-icon-total {\n background: var(--md-primary-container);\n color: var(--md-primary);\n}\n\n/* System Roles - Secondary (Orange) */\n.stat-icon-system {\n background: var(--md-secondary-container);\n color: #B5751A;\n}\n\n/* Custom Roles - Tertiary (Green) */\n.stat-icon-custom {\n background: var(--md-tertiary-container);\n color: var(--md-tertiary);\n}\n\n/* Active Roles - Primary */\n.stat-icon-active {\n background: var(--md-primary-container);\n color: var(--md-primary);\n}\n\n.stat-content {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content .stat-value {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--md-on-surface);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content .stat-value {\n font-size: 2rem;\n }\n}\n\n.stat-content .stat-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface-variant);\n margin-top: 0.25rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n@media (min-width: 768px) {\n .stat-content .stat-label {\n font-size: 0.8125rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Filters Section\n ----------------------------------------------------------------------------- */\n.filters-section {\n flex-shrink: 0;\n background: var(--md-surface-container-low);\n margin: 0 1rem 1rem 1rem;\n padding: 1rem;\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n}\n\n@media (min-width: 768px) {\n .filters-section {\n margin: 0 1.5rem 1.25rem 1.5rem;\n padding: 1rem 1.25rem;\n }\n}\n\n.filters-row {\n display: flex;\n gap: 1.25rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (min-width: 768px) {\n .filters-row {\n gap: 1.5rem;\n }\n}\n\n/* Mobile Search Container */\n.mobile-search-container {\n display: flex;\n gap: 0.75rem;\n align-items: center;\n flex: 1;\n min-width: 200px;\n}\n\n/* Search Input */\n.mj-search {\n flex: 1;\n min-width: 200px;\n position: relative;\n}\n\n@media (min-width: 640px) {\n .mj-search {\n min-width: 280px;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-search {\n min-width: 400px;\n max-width: 600px;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search {\n min-width: 500px;\n max-width: 800px;\n }\n}\n\n.mj-search .mj-search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n transition: color 0.2s ease;\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-icon {\n left: 1.25rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search .mj-search-input {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-full);\n font-size: 1rem;\n background: var(--md-surface);\n color: var(--md-on-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-input {\n padding: 1rem 1.25rem 1rem 3.25rem;\n font-size: 1.0625rem;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search .mj-search-input {\n padding: 1.125rem 1.5rem 1.125rem 3.5rem;\n }\n}\n\n.mj-search .mj-search-input::placeholder {\n color: var(--md-on-surface-variant);\n}\n\n.mj-search .mj-search-input:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.mj-search .mj-search-input:focus {\n outline: none;\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--md-surface);\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-input:focus {\n box-shadow: var(--md-elevation-1), 0 0 0 3px rgba(0, 118, 182, 0.2);\n }\n}\n\n.mj-search:focus-within .mj-search-icon {\n color: var(--md-primary);\n}\n\n/* Filter Group */\n.mj-filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.mj-filter-group .mj-filter-label {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--md-on-surface-variant);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-group .mj-filter-buttons {\n display: flex;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-full);\n padding: 4px;\n gap: 2px;\n}\n\n.mj-filter-buttons .mj-btn-ghost {\n border-radius: var(--md-corner-full);\n padding: 0.5rem 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n transition: all 0.2s ease;\n}\n\n.mj-filter-buttons .mj-btn-ghost:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.mj-filter-buttons .mj-btn-primary {\n background-color: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-filter-buttons .mj-btn-primary:hover:not(:disabled) {\n background-color: #3395C8;\n}\n\n/* -----------------------------------------------------------------------------\n Button System\n ----------------------------------------------------------------------------- */\n.mj-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n font-weight: 600;\n letter-spacing: 0.02em;\n border: none;\n border-radius: var(--md-corner-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.mj-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n/* Primary Button - Dark to Light on hover */\n.mj-btn-primary {\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-btn-primary:hover:not(:disabled) {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.mj-btn-primary:active:not(:disabled) {\n background: #4BA5D4;\n transform: scale(0.98);\n box-shadow: var(--md-elevation-1);\n}\n\n/* Secondary Button - Light to Dark on hover */\n.mj-btn-secondary {\n background: var(--md-surface);\n color: var(--md-primary);\n border: 1px solid var(--md-outline);\n}\n\n.mj-btn-secondary:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.mj-btn-secondary:active:not(:disabled) {\n background: #005A8C;\n border-color: #005A8C;\n}\n\n/* Ghost Button - Light to Dark on hover */\n.mj-btn-ghost {\n background: transparent;\n color: var(--md-on-surface-variant);\n}\n\n.mj-btn-ghost:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.mj-btn-ghost:active:not(:disabled) {\n background: #005A8C;\n}\n\n/* Danger Button - Dark to Light on hover */\n.mj-btn-danger {\n background: var(--md-error);\n color: var(--md-on-error);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-btn-danger:hover:not(:disabled) {\n background: #E57373;\n box-shadow: var(--md-elevation-2);\n}\n\n.mj-btn-danger:active:not(:disabled) {\n background: #EF9A9A;\n transform: scale(0.98);\n}\n\n/* Small Button */\n.mj-btn-sm {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n/* Icon-only Button */\n.mj-btn-icon-only {\n padding: 0.625rem;\n min-width: 44px;\n min-height: 44px;\n}\n\n/* Mobile Icon Button */\n.mj-btn-icon-mobile {\n gap: 0.5rem;\n}\n\n.mj-btn-icon-mobile .btn-text {\n display: inline;\n}\n\n/* -----------------------------------------------------------------------------\n Content Area\n ----------------------------------------------------------------------------- */\n.content-area {\n flex: 1 1 auto;\n overflow: visible;\n position: relative;\n background: var(--md-surface);\n border-radius: var(--md-corner-large);\n box-shadow: var(--md-elevation-1);\n padding: 1.25rem;\n border: 1px solid var(--md-outline-variant);\n}\n\n@media (min-width: 768px) {\n .content-area {\n padding: 1.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Roles List\n ----------------------------------------------------------------------------- */\n.roles-list {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n/* -----------------------------------------------------------------------------\n Role Card\n ----------------------------------------------------------------------------- */\n.role-card {\n background: var(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-large);\n overflow: hidden;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.role-card:hover {\n box-shadow: var(--md-elevation-2);\n border-color: var(--md-primary);\n}\n\n.role-card.expanded {\n box-shadow: var(--md-elevation-3);\n border-color: var(--md-primary);\n}\n\n.role-card.expanded .expand-btn i {\n transform: rotate(180deg);\n}\n\n.role-header {\n padding: 1.25rem 1.5rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: var(--md-surface-container-lowest);\n transition: background-color 0.2s ease;\n}\n\n.role-header:hover {\n background: var(--md-surface-container-low);\n}\n\n.role-info {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex: 1;\n min-width: 0;\n}\n\n.role-icon-wrapper {\n width: 52px;\n height: 52px;\n border-radius: var(--md-corner-medium);\n background: var(--md-primary-container);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--md-primary);\n font-size: 1.375rem;\n flex-shrink: 0;\n}\n\n.role-details {\n flex: 1;\n min-width: 0;\n}\n\n.role-details .role-name {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.25rem 0;\n word-break: break-word;\n overflow-wrap: break-word;\n}\n\n.role-details .role-description {\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (max-width: 639px) {\n .role-details .role-description {\n white-space: normal;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n }\n}\n\n.role-meta {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex-shrink: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Role Type Badge\n ----------------------------------------------------------------------------- */\n.role-type-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n/* System Badge - Orange (Secondary) */\n.role-type-badge.badge-system {\n background: var(--md-secondary-container);\n color: #7A4D0C;\n border: 1px solid var(--md-secondary);\n}\n\n/* Custom Badge - Green (Tertiary) */\n.role-type-badge.badge-custom {\n background: var(--md-tertiary-container);\n color: #1B5E20;\n border: 1px solid var(--md-tertiary);\n}\n\n/* -----------------------------------------------------------------------------\n Role Actions\n ----------------------------------------------------------------------------- */\n.role-actions {\n display: flex;\n gap: 0.375rem;\n}\n\n.expand-btn {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--md-corner-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.expand-btn:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.expand-btn i {\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* -----------------------------------------------------------------------------\n Role Content (Expanded)\n ----------------------------------------------------------------------------- */\n.role-content {\n padding: 1.5rem;\n background: var(--md-surface-container-lowest);\n border-top: 1px solid var(--md-outline-variant);\n animation: slideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.mobile-actions-bar {\n display: none;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.role-stats {\n display: flex;\n gap: 2rem;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\n}\n\n.role-stats .stat-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.9375rem;\n padding: 0.5rem 1rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-small);\n}\n\n.role-stats .stat-item i {\n color: var(--md-primary);\n font-size: 1rem;\n}\n\n.role-stats .stat-item .stat-label {\n color: var(--md-on-surface-variant);\n}\n\n.role-stats .stat-item .stat-value {\n color: var(--md-on-surface);\n font-weight: 600;\n}\n\n/* -----------------------------------------------------------------------------\n Permissions Preview\n ----------------------------------------------------------------------------- */\n.permissions-preview {\n padding: 1.25rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n}\n\n.permissions-preview .section-title {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.5rem 0;\n}\n\n.permissions-preview .section-title i {\n color: var(--md-primary);\n font-size: 1.125rem;\n}\n\n.permissions-preview .permissions-note {\n font-size: 0.9375rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Empty State\n ----------------------------------------------------------------------------- */\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state .empty-icon {\n font-size: 4rem;\n color: var(--md-outline-variant);\n margin-bottom: 1.5rem;\n}\n\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state .empty-subtext {\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Loading State\n ----------------------------------------------------------------------------- */\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/* -----------------------------------------------------------------------------\n Error State\n ----------------------------------------------------------------------------- */\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container .error-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container .error-icon {\n font-size: 3.5rem;\n color: var(--md-error);\n margin-bottom: 1rem;\n}\n\n.error-container .error-message {\n font-size: 1.0625rem;\n color: var(--md-on-surface);\n margin: 0 0 1.5rem 0;\n}\n\n/* -----------------------------------------------------------------------------\n Modal Dialog\n ----------------------------------------------------------------------------- */\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.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 1rem;\n}\n\n.modal-dialog {\n background: var(--md-surface);\n border-radius: var(--md-corner-extra-large);\n box-shadow: var(--md-elevation-5);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);\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 var(--md-outline-variant);\n}\n\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n}\n\n.modal-header .modal-close {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--md-corner-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.modal-header .modal-close:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n\n.modal-body p {\n font-size: 1rem;\n color: var(--md-on-surface);\n margin: 0 0 1rem 0;\n line-height: 1.6;\n}\n\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n\n.modal-body .text-warning {\n color: var(--md-secondary);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: var(--md-secondary-container);\n border-radius: var(--md-corner-small);\n font-weight: 500;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--md-outline-variant);\n background: var(--md-surface-container-low);\n}\n\n/* -----------------------------------------------------------------------------\n Utility Classes\n ----------------------------------------------------------------------------- */\n.text-danger {\n color: var(--md-error);\n}\n\n.text-warning {\n color: var(--md-secondary);\n}\n\n/* -----------------------------------------------------------------------------\n Large Desktop (1440px+)\n ----------------------------------------------------------------------------- */\n@media (min-width: 1440px) {\n .role-management-container {\n max-width: 1920px;\n margin: 0 auto;\n }\n\n .action-buttons {\n padding: 1rem 2rem;\n }\n\n .mj-grid-4 {\n padding: 0 2rem 1.25rem 2rem;\n gap: 1.5rem;\n }\n\n .filters-section {\n margin: 0 2rem 1.25rem 2rem;\n padding: 1.25rem 1.5rem;\n }\n\n .content-area {\n padding: 2rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Animations\n ----------------------------------------------------------------------------- */\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/* -----------------------------------------------------------------------------\n Focus Indicators (Accessibility)\n ----------------------------------------------------------------------------- */\n.mj-search-input:focus-visible,\nbutton:focus-visible,\n.mj-btn:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Filter Button (Mobile Only)\n ----------------------------------------------------------------------------- */\n.filter-button {\n display: none;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n border: 2px solid var(--md-outline-variant);\n background: var(--md-surface);\n color: var(--md-on-surface);\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n min-width: 44px;\n}\n\n.filter-button:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.filter-button:active {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.filter-button i {\n font-size: 1rem;\n}\n\n/* -----------------------------------------------------------------------------\n Filter Modal (Mobile)\n ----------------------------------------------------------------------------- */\n.filter-modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: flex-end;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 0;\n}\n\n.filter-modal {\n background: var(--md-surface);\n border-radius: var(--md-corner-extra-large) var(--md-corner-extra-large) 0 0;\n box-shadow: var(--md-elevation-5);\n width: 100%;\n max-height: 80vh;\n overflow: hidden;\n animation: slideUpFromBottom 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n}\n\n.filter-modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 1.5rem;\n border-bottom: 1px solid var(--md-outline-variant);\n flex-shrink: 0;\n}\n\n.filter-modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n}\n\n.filter-modal-title i {\n color: var(--md-primary);\n font-size: 1.375rem;\n}\n\n.filter-modal-close {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--md-corner-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-modal-close:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.filter-modal-body {\n padding: 1.5rem;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n flex: 1;\n}\n\n.filter-modal-footer {\n display: flex;\n gap: 0.75rem;\n padding: 1.25rem 1.5rem;\n border-top: 1px solid var(--md-outline-variant);\n background: var(--md-surface-container-low);\n flex-shrink: 0;\n}\n\n.filter-modal-footer button {\n flex: 1;\n margin: 0;\n}\n\n/* Filter Options Container (Inside Modal) */\n.filter-options-container {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.filter-group-label {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n}\n\n.filter-group-options {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.filter-option {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.875rem 1rem;\n background: var(--md-surface-container-low);\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.filter-option:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container);\n}\n\n.filter-option.selected {\n background: var(--md-primary-container);\n border-color: var(--md-primary);\n color: var(--md-primary);\n}\n\n.filter-option input[type=\"checkbox\"],\n.filter-option input[type=\"radio\"] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--md-primary);\n flex-shrink: 0;\n}\n\n.filter-option-label {\n flex: 1;\n font-size: 1rem;\n font-weight: 500;\n color: var(--md-on-surface);\n}\n\n.filter-option.selected .filter-option-label {\n color: var(--md-primary);\n font-weight: 600;\n}\n\n/* Animations */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideUpFromBottom {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Reduced Motion (Accessibility)\n ----------------------------------------------------------------------------- */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Mobile (< 640px)\n ----------------------------------------------------------------------------- */\n@media (max-width: 639px) {\n .sticky-header {\n padding: 0;\n }\n\n .action-buttons {\n padding: 0.5rem 0.75rem;\n gap: 0.5rem;\n justify-content: flex-end;\n }\n\n .mj-btn-icon-mobile {\n padding: 0.5rem 0.75rem;\n min-height: 40px;\n gap: 0;\n }\n\n .mj-btn-icon-mobile .btn-text {\n display: none;\n }\n\n .mj-btn-icon-mobile i {\n font-size: 1.125rem;\n }\n\n .mj-grid-4 {\n display: none !important;\n }\n\n .filters-section {\n margin: 0 0.5rem 0.5rem 0.5rem;\n padding: 0.75rem;\n border-radius: var(--md-corner-small);\n }\n\n .filters-row {\n gap: 0.75rem;\n flex-direction: row;\n align-items: center;\n }\n\n /* Mobile search container */\n .mobile-search-container {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n width: 100%;\n }\n\n .mj-search {\n flex: 1;\n min-width: 0;\n }\n\n .mj-search .mj-search-input {\n padding: 0.75rem 1rem 0.75rem 2.5rem;\n min-height: 44px;\n font-size: 1rem;\n border-width: 1.5px;\n }\n\n .mj-search .mj-search-icon {\n left: 0.875rem;\n font-size: 1rem;\n }\n\n /* Hide filter groups on mobile - they go in modal */\n .mj-filter-group {\n display: none !important;\n }\n\n /* Show filter button on mobile */\n .filter-button {\n display: inline-flex !important;\n flex-shrink: 0;\n }\n\n .scrollable-content {\n padding: 0.75rem;\n }\n\n .content-area {\n padding: 0.75rem;\n border-radius: var(--md-corner-medium);\n }\n\n .modal-backdrop {\n padding: 0.5rem;\n }\n\n .modal-dialog {\n border-radius: var(--md-corner-large);\n max-height: 95vh;\n }\n\n .modal-footer {\n flex-direction: column;\n }\n\n .modal-footer .mj-btn {\n width: 100%;\n justify-content: center;\n }\n\n .roles-list {\n gap: 0.75rem;\n }\n\n .role-card {\n border-radius: var(--md-corner-medium);\n overflow: hidden;\n }\n\n .role-header {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n gap: 0.75rem;\n padding: 1rem;\n }\n\n .role-info {\n flex: 1;\n min-width: 0;\n flex-direction: row;\n align-items: flex-start;\n gap: 0.875rem;\n }\n\n .role-icon-wrapper {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n flex-shrink: 0;\n }\n\n .role-details {\n flex: 1;\n min-width: 0;\n }\n\n .role-details .role-name {\n font-size: 1rem;\n line-height: 1.3;\n margin-bottom: 0.125rem;\n }\n\n .role-details .role-description {\n font-size: 0.8125rem;\n -webkit-line-clamp: 1;\n line-clamp: 1;\n }\n\n .role-meta {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: flex-end;\n padding-top: 0;\n border-top: none;\n width: auto;\n }\n\n .role-meta .role-type-badge {\n display: none;\n }\n\n .role-meta .role-actions {\n display: none;\n }\n\n .expand-btn {\n flex-shrink: 0;\n min-width: 40px;\n min-height: 40px;\n padding: 0.5rem;\n }\n\n .expand-btn i {\n font-size: 1rem;\n }\n\n .mobile-actions-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.75rem;\n padding: 0.875rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n margin-bottom: 1rem;\n }\n\n .mobile-actions-bar .role-type-badge {\n padding: 0.375rem 0.75rem;\n font-size: 0.6875rem;\n }\n\n .mobile-action-buttons {\n display: flex;\n gap: 0.5rem;\n }\n\n .mobile-action-buttons .mj-btn-sm {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.5rem 0.875rem;\n min-height: 36px;\n }\n\n .mobile-action-buttons .mj-btn-sm i {\n font-size: 0.875rem;\n }\n\n .mobile-action-buttons .btn-label {\n font-size: 0.8125rem;\n font-weight: 500;\n }\n\n .role-stats {\n flex-direction: column;\n gap: 0.5rem;\n margin-bottom: 1rem;\n }\n\n .role-content {\n padding: 1rem;\n }\n\n .permissions-preview {\n padding: 1rem;\n }\n\n .empty-state {\n padding: 3rem 1.5rem;\n }\n\n .empty-state .empty-icon {\n font-size: 3rem;\n }\n\n .loading-container {\n padding: 3rem 1.5rem;\n }\n}\n\n/* Small Mobile (< 375px) */\n@media (max-width: 374px) {\n .action-buttons {\n padding: 0.375rem 0.5rem;\n }\n\n .filters-section {\n margin: 0 0.375rem 0.375rem 0.375rem;\n padding: 0.5rem;\n }\n\n .mobile-search-container {\n gap: 0.375rem;\n }\n\n .filter-button {\n padding: 0.625rem;\n min-width: 40px;\n }\n\n .filter-button span {\n display: none;\n }\n\n .filter-modal-header {\n padding: 1rem 1.25rem;\n }\n\n .filter-modal-body {\n padding: 1.25rem;\n }\n\n .filter-modal-footer {\n padding: 1rem 1.25rem;\n }\n\n .scrollable-content {\n padding: 0.5rem;\n }\n\n .content-area {\n padding: 0.5rem;\n }\n\n .role-header {\n padding: 0.75rem;\n }\n}\n"] }]
511
628
  }], () => [], null); })();
512
629
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RoleManagementComponent, { className: "RoleManagementComponent", filePath: "src/lib/role-management/role-management.component.ts", lineNumber: 28 }); })();
513
630
  //# sourceMappingURL=role-management.component.js.map