@memberjunction/ng-explorer-settings 3.2.0 → 3.4.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 (72) hide show
  1. package/dist/lib/account-info/account-info.component.d.ts +23 -0
  2. package/dist/lib/account-info/account-info.component.d.ts.map +1 -0
  3. package/dist/lib/account-info/account-info.component.js +155 -0
  4. package/dist/lib/account-info/account-info.component.js.map +1 -0
  5. package/dist/lib/appearance-settings/appearance-settings.component.d.ts +15 -0
  6. package/dist/lib/appearance-settings/appearance-settings.component.d.ts.map +1 -0
  7. package/dist/lib/appearance-settings/appearance-settings.component.js +79 -0
  8. package/dist/lib/appearance-settings/appearance-settings.component.js.map +1 -0
  9. package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts +15 -1
  10. package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts.map +1 -1
  11. package/dist/lib/application-management/application-dialog/application-dialog.component.js +329 -190
  12. package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
  13. package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
  14. package/dist/lib/application-management/application-management.component.js +265 -184
  15. package/dist/lib/application-management/application-management.component.js.map +1 -1
  16. package/dist/lib/application-settings/application-settings.component.d.ts +113 -0
  17. package/dist/lib/application-settings/application-settings.component.d.ts.map +1 -0
  18. package/dist/lib/application-settings/application-settings.component.js +520 -0
  19. package/dist/lib/application-settings/application-settings.component.js.map +1 -0
  20. package/dist/lib/entity-permissions/entity-permissions.component.d.ts +1 -0
  21. package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
  22. package/dist/lib/entity-permissions/entity-permissions.component.js +369 -192
  23. package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
  24. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts.map +1 -1
  25. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +160 -143
  26. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
  27. package/dist/lib/general-settings/general-settings.component.d.ts +14 -0
  28. package/dist/lib/general-settings/general-settings.component.d.ts.map +1 -0
  29. package/dist/lib/general-settings/general-settings.component.js +50 -0
  30. package/dist/lib/general-settings/general-settings.component.js.map +1 -0
  31. package/dist/lib/module.d.ts +28 -30
  32. package/dist/lib/module.d.ts.map +1 -1
  33. package/dist/lib/module.js +75 -68
  34. package/dist/lib/module.js.map +1 -1
  35. package/dist/lib/notification-preferences/notification-preferences.component.d.ts +77 -0
  36. package/dist/lib/notification-preferences/notification-preferences.component.d.ts.map +1 -1
  37. package/dist/lib/notification-preferences/notification-preferences.component.js +153 -77
  38. package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
  39. package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts.map +1 -1
  40. package/dist/lib/role-management/role-dialog/role-dialog.component.js +93 -89
  41. package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
  42. package/dist/lib/role-management/role-management.component.d.ts +1 -0
  43. package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
  44. package/dist/lib/role-management/role-management.component.js +275 -158
  45. package/dist/lib/role-management/role-management.component.js.map +1 -1
  46. package/dist/lib/settings/settings.component.d.ts +47 -3
  47. package/dist/lib/settings/settings.component.d.ts.map +1 -1
  48. package/dist/lib/settings/settings.component.js +339 -269
  49. package/dist/lib/settings/settings.component.js.map +1 -1
  50. package/dist/lib/shared/settings-card.component.d.ts.map +1 -1
  51. package/dist/lib/shared/settings-card.component.js +21 -18
  52. package/dist/lib/shared/settings-card.component.js.map +1 -1
  53. package/dist/lib/sql-logging/sql-logging.component.d.ts +11 -2
  54. package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -1
  55. package/dist/lib/sql-logging/sql-logging.component.js +318 -245
  56. package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
  57. package/dist/lib/user-app-config/user-app-config.component.d.ts +21 -3
  58. package/dist/lib/user-app-config/user-app-config.component.d.ts.map +1 -1
  59. package/dist/lib/user-app-config/user-app-config.component.js +202 -147
  60. package/dist/lib/user-app-config/user-app-config.component.js.map +1 -1
  61. package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
  62. package/dist/lib/user-management/user-dialog/user-dialog.component.js +120 -116
  63. package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
  64. package/dist/lib/user-management/user-management.component.d.ts +32 -2
  65. package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
  66. package/dist/lib/user-management/user-management.component.js +822 -297
  67. package/dist/lib/user-management/user-management.component.js.map +1 -1
  68. package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts +31 -2
  69. package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts.map +1 -1
  70. package/dist/lib/user-profile-settings/user-profile-settings.component.js +213 -80
  71. package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
  72. package/package.json +20 -20
@@ -12,11 +12,12 @@ import { BaseDashboard } from '@memberjunction/ng-shared';
12
12
  import { RegisterClass } from '@memberjunction/global';
13
13
  import * as i0 from "@angular/core";
14
14
  import * as i1 from "@angular/forms";
15
- import * as i2 from "./permission-dialog/permission-dialog.component";
15
+ import * as i2 from "@memberjunction/ng-shared-generic";
16
+ import * as i3 from "./permission-dialog/permission-dialog.component";
16
17
  const _forTrack0 = ($index, $item) => $item.ID;
17
18
  const _forTrack1 = ($index, $item) => $item.entity.ID;
18
- function EntityPermissionsComponent_For_67_Template(rf, ctx) { if (rf & 1) {
19
- i0.ɵɵelementStart(0, "option", 33);
19
+ function EntityPermissionsComponent_For_74_Template(rf, ctx) { if (rf & 1) {
20
+ i0.ɵɵelementStart(0, "option", 48);
20
21
  i0.ɵɵtext(1);
21
22
  i0.ɵɵelementEnd();
22
23
  } if (rf & 2) {
@@ -25,24 +26,21 @@ function EntityPermissionsComponent_For_67_Template(rf, ctx) { if (rf & 1) {
25
26
  i0.ɵɵadvance();
26
27
  i0.ɵɵtextInterpolate(role_r1.Name);
27
28
  } }
28
- function EntityPermissionsComponent_Conditional_68_Template(rf, ctx) { if (rf & 1) {
29
- i0.ɵɵelementStart(0, "div", 34)(1, "div", 38);
30
- i0.ɵɵelement(2, "div", 39)(3, "div", 39)(4, "div", 39);
29
+ function EntityPermissionsComponent_Conditional_76_Template(rf, ctx) { if (rf & 1) {
30
+ i0.ɵɵelementStart(0, "div", 50);
31
+ i0.ɵɵelement(1, "mj-loading", 55);
31
32
  i0.ɵɵelementEnd();
32
- i0.ɵɵelementStart(5, "div", 40);
33
- i0.ɵɵtext(6, "Loading entity permissions...");
34
- i0.ɵɵelementEnd()();
35
33
  } }
36
- function EntityPermissionsComponent_Conditional_69_Template(rf, ctx) { if (rf & 1) {
34
+ function EntityPermissionsComponent_Conditional_77_Template(rf, ctx) { if (rf & 1) {
37
35
  const _r2 = i0.ɵɵgetCurrentView();
38
- i0.ɵɵelementStart(0, "div", 35)(1, "div", 41);
39
- i0.ɵɵelement(2, "i", 42);
40
- i0.ɵɵelementStart(3, "p", 43);
36
+ i0.ɵɵelementStart(0, "div", 51)(1, "div", 56);
37
+ i0.ɵɵelement(2, "i", 57);
38
+ i0.ɵɵelementStart(3, "p", 58);
41
39
  i0.ɵɵtext(4);
42
40
  i0.ɵɵelementEnd();
43
- i0.ɵɵelementStart(5, "button", 44);
44
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_69_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.loadInitialData()); });
45
- i0.ɵɵelement(6, "i", 8);
41
+ i0.ɵɵelementStart(5, "button", 59);
42
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_77_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.loadInitialData()); });
43
+ i0.ɵɵelement(6, "i", 9);
46
44
  i0.ɵɵtext(7, " Try Again ");
47
45
  i0.ɵɵelementEnd()()();
48
46
  } if (rf & 2) {
@@ -50,202 +48,259 @@ function EntityPermissionsComponent_Conditional_69_Template(rf, ctx) { if (rf &
50
48
  i0.ɵɵadvance(4);
51
49
  i0.ɵɵtextInterpolate(ctx_r2.error);
52
50
  } }
53
- function EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Conditional_1_For_13_Template(rf, ctx) { if (rf & 1) {
54
- i0.ɵɵelementStart(0, "div", 69)(1, "span", 70);
51
+ function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Conditional_10_For_15_Template(rf, ctx) { if (rf & 1) {
52
+ i0.ɵɵelementStart(0, "tr", 91)(1, "td", 92);
55
53
  i0.ɵɵtext(2);
56
54
  i0.ɵɵelementEnd();
57
- i0.ɵɵelementStart(3, "span", 71);
55
+ i0.ɵɵelementStart(3, "td", 93);
58
56
  i0.ɵɵelement(4, "i");
59
57
  i0.ɵɵelementEnd();
60
- i0.ɵɵelementStart(5, "span", 71);
58
+ i0.ɵɵelementStart(5, "td", 93);
61
59
  i0.ɵɵelement(6, "i");
62
60
  i0.ɵɵelementEnd();
63
- i0.ɵɵelementStart(7, "span", 71);
61
+ i0.ɵɵelementStart(7, "td", 93);
64
62
  i0.ɵɵelement(8, "i");
65
63
  i0.ɵɵelementEnd();
66
- i0.ɵɵelementStart(9, "span", 71);
64
+ i0.ɵɵelementStart(9, "td", 93);
67
65
  i0.ɵɵelement(10, "i");
68
66
  i0.ɵɵelementEnd()();
69
67
  } if (rf & 2) {
70
- const roleId_r6 = ctx.$implicit;
68
+ const roleId_r7 = ctx.$implicit;
71
69
  const ea_r5 = i0.ɵɵnextContext(3).$implicit;
72
70
  const ctx_r2 = i0.ɵɵnextContext(3);
73
71
  i0.ɵɵadvance(2);
74
- i0.ɵɵtextInterpolate(ctx_r2.getRoleName(roleId_r6));
75
- i0.ɵɵadvance(2);
76
- i0.ɵɵclassMap(ctx_r2.hasPermission(ea_r5, roleId_r6, "canCreate") ? "fa-solid fa-check text-success" : "fa-solid fa-times text-muted");
77
- i0.ɵɵadvance(2);
78
- i0.ɵɵclassMap(ctx_r2.hasPermission(ea_r5, roleId_r6, "canRead") ? "fa-solid fa-check text-success" : "fa-solid fa-times text-muted");
79
- i0.ɵɵadvance(2);
80
- i0.ɵɵclassMap(ctx_r2.hasPermission(ea_r5, roleId_r6, "canUpdate") ? "fa-solid fa-check text-success" : "fa-solid fa-times text-muted");
81
- i0.ɵɵadvance(2);
82
- i0.ɵɵclassMap(ctx_r2.hasPermission(ea_r5, roleId_r6, "canDelete") ? "fa-solid fa-check text-success" : "fa-solid fa-times text-muted");
72
+ i0.ɵɵtextInterpolate(ctx_r2.getRoleName(roleId_r7));
73
+ i0.ɵɵadvance();
74
+ i0.ɵɵattribute("aria-label", "Create: " + (ctx_r2.hasPermission(ea_r5, roleId_r7, "canCreate") ? "allowed" : "denied"));
75
+ i0.ɵɵadvance();
76
+ i0.ɵɵclassMap(ctx_r2.hasPermission(ea_r5, roleId_r7, "canCreate") ? "fa-solid fa-check text-success" : "fa-solid fa-times text-muted");
77
+ i0.ɵɵattribute("aria-hidden", true);
78
+ i0.ɵɵadvance();
79
+ i0.ɵɵattribute("aria-label", "Read: " + (ctx_r2.hasPermission(ea_r5, roleId_r7, "canRead") ? "allowed" : "denied"));
80
+ i0.ɵɵadvance();
81
+ i0.ɵɵclassMap(ctx_r2.hasPermission(ea_r5, roleId_r7, "canRead") ? "fa-solid fa-check text-success" : "fa-solid fa-times text-muted");
82
+ i0.ɵɵattribute("aria-hidden", true);
83
+ i0.ɵɵadvance();
84
+ i0.ɵɵattribute("aria-label", "Update: " + (ctx_r2.hasPermission(ea_r5, roleId_r7, "canUpdate") ? "allowed" : "denied"));
85
+ i0.ɵɵadvance();
86
+ i0.ɵɵclassMap(ctx_r2.hasPermission(ea_r5, roleId_r7, "canUpdate") ? "fa-solid fa-check text-success" : "fa-solid fa-times text-muted");
87
+ i0.ɵɵattribute("aria-hidden", true);
88
+ i0.ɵɵadvance();
89
+ i0.ɵɵattribute("aria-label", "Delete: " + (ctx_r2.hasPermission(ea_r5, roleId_r7, "canDelete") ? "allowed" : "denied"));
90
+ i0.ɵɵadvance();
91
+ i0.ɵɵclassMap(ctx_r2.hasPermission(ea_r5, roleId_r7, "canDelete") ? "fa-solid fa-check text-success" : "fa-solid fa-times text-muted");
92
+ i0.ɵɵattribute("aria-hidden", true);
83
93
  } }
84
- function EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Conditional_1_Template(rf, ctx) { if (rf & 1) {
85
- i0.ɵɵelementStart(0, "div", 64)(1, "div", 66)(2, "span", 67);
86
- i0.ɵɵtext(3, "Role");
94
+ function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Conditional_10_Template(rf, ctx) { if (rf & 1) {
95
+ i0.ɵɵelementStart(0, "table", 84)(1, "thead", 86)(2, "tr", 87)(3, "th", 88);
96
+ i0.ɵɵtext(4, "Role");
87
97
  i0.ɵɵelementEnd();
88
- i0.ɵɵelementStart(4, "span", 68);
89
- i0.ɵɵtext(5, "Create");
98
+ i0.ɵɵelementStart(5, "th", 89);
99
+ i0.ɵɵtext(6, "Create");
90
100
  i0.ɵɵelementEnd();
91
- i0.ɵɵelementStart(6, "span", 68);
92
- i0.ɵɵtext(7, "Read");
101
+ i0.ɵɵelementStart(7, "th", 89);
102
+ i0.ɵɵtext(8, "Read");
93
103
  i0.ɵɵelementEnd();
94
- i0.ɵɵelementStart(8, "span", 68);
95
- i0.ɵɵtext(9, "Update");
104
+ i0.ɵɵelementStart(9, "th", 89);
105
+ i0.ɵɵtext(10, "Update");
96
106
  i0.ɵɵelementEnd();
97
- i0.ɵɵelementStart(10, "span", 68);
98
- i0.ɵɵtext(11, "Delete");
107
+ i0.ɵɵelementStart(11, "th", 89);
108
+ i0.ɵɵtext(12, "Delete");
109
+ i0.ɵɵelementEnd()()();
110
+ i0.ɵɵelementStart(13, "tbody", 90);
111
+ i0.ɵɵrepeaterCreate(14, EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Conditional_10_For_15_Template, 11, 17, "tr", 91, i0.ɵɵrepeaterTrackByIdentity);
99
112
  i0.ɵɵelementEnd()();
100
- i0.ɵɵrepeaterCreate(12, EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Conditional_1_For_13_Template, 11, 9, "div", 69, i0.ɵɵrepeaterTrackByIdentity);
101
- i0.ɵɵelementEnd();
102
113
  } if (rf & 2) {
103
114
  const ea_r5 = i0.ɵɵnextContext(2).$implicit;
104
- i0.ɵɵadvance(12);
115
+ i0.ɵɵadvance(14);
105
116
  i0.ɵɵrepeater(ea_r5.rolePermissions.keys());
106
117
  } }
107
- function EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
118
+ function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Conditional_11_Conditional_1_Template(rf, ctx) { if (rf & 1) {
108
119
  i0.ɵɵtext(0, " This entity is publicly accessible by all users. ");
109
120
  } }
110
- function EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
121
+ function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Conditional_11_Conditional_2_Template(rf, ctx) { if (rf & 1) {
111
122
  i0.ɵɵtext(0, " No specific role permissions configured. Access is restricted to system administrators. ");
112
123
  } }
113
- function EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Conditional_2_Template(rf, ctx) { if (rf & 1) {
114
- i0.ɵɵelementStart(0, "p", 65);
115
- i0.ɵɵtemplate(1, EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Conditional_2_Conditional_1_Template, 1, 0)(2, EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Conditional_2_Conditional_2_Template, 1, 0);
124
+ function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Conditional_11_Template(rf, ctx) { if (rf & 1) {
125
+ i0.ɵɵelementStart(0, "p", 85);
126
+ i0.ɵɵtemplate(1, EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Conditional_11_Conditional_1_Template, 1, 0)(2, EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Conditional_11_Conditional_2_Template, 1, 0);
116
127
  i0.ɵɵelementEnd();
117
128
  } if (rf & 2) {
118
129
  const ea_r5 = i0.ɵɵnextContext(2).$implicit;
119
130
  i0.ɵɵadvance();
120
131
  i0.ɵɵconditional(ea_r5.isPublic ? 1 : 2);
121
132
  } }
122
- function EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
123
- i0.ɵɵelementStart(0, "div", 63);
124
- i0.ɵɵtemplate(1, EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Conditional_1_Template, 14, 0, "div", 64)(2, EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Conditional_2_Template, 3, 1, "p", 65);
133
+ function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
134
+ const _r6 = i0.ɵɵgetCurrentView();
135
+ i0.ɵɵelementStart(0, "div", 80)(1, "div", 81);
136
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r6); return i0.ɵɵresetView($event.stopPropagation()); });
137
+ i0.ɵɵelementStart(2, "span", 73);
138
+ i0.ɵɵelement(3, "i", 74);
139
+ i0.ɵɵtext(4);
140
+ i0.ɵɵelementEnd();
141
+ i0.ɵɵelementStart(5, "div", 82)(6, "button", 76);
142
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r6); const ea_r5 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.editEntityPermissions(ea_r5)); });
143
+ i0.ɵɵelement(7, "i", 77);
144
+ i0.ɵɵelementStart(8, "span", 83);
145
+ i0.ɵɵtext(9, "Edit");
146
+ i0.ɵɵelementEnd()()()();
147
+ i0.ɵɵtemplate(10, EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Conditional_10_Template, 16, 0, "table", 84)(11, EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Conditional_11_Template, 3, 1, "p", 85);
125
148
  i0.ɵɵelementEnd();
126
149
  } if (rf & 2) {
127
150
  const ea_r5 = i0.ɵɵnextContext().$implicit;
151
+ const ctx_r2 = i0.ɵɵnextContext(3);
152
+ i0.ɵɵattribute("aria-label", "Permissions for " + ea_r5.entity.Name);
153
+ i0.ɵɵadvance(2);
154
+ i0.ɵɵclassMap(ctx_r2.getAccessLevelClass(ea_r5));
128
155
  i0.ɵɵadvance();
129
- i0.ɵɵconditional(ea_r5.permissions.length > 0 ? 1 : 2);
156
+ i0.ɵɵclassMap(ctx_r2.getAccessLevelClass(ea_r5) === "access-public" ? "fa-solid fa-globe" : ctx_r2.getAccessLevelClass(ea_r5) === "access-restricted" ? "fa-solid fa-lock" : "fa-solid fa-key");
157
+ i0.ɵɵadvance();
158
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.getAccessLevelLabel(ea_r5), " ");
159
+ i0.ɵɵadvance(2);
160
+ i0.ɵɵattribute("aria-label", "Edit permissions for " + ea_r5.entity.Name);
161
+ i0.ɵɵadvance(4);
162
+ i0.ɵɵconditional(ea_r5.permissions.length > 0 ? 10 : 11);
130
163
  } }
131
- function EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
164
+ function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
132
165
  const _r4 = i0.ɵɵgetCurrentView();
133
- i0.ɵɵelementStart(0, "div", 49)(1, "div", 50);
134
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Template_div_click_1_listener() { const ea_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.toggleEntityExpansion(ea_r5.entity.ID)); });
135
- i0.ɵɵelementStart(2, "div", 51)(3, "div", 52);
136
- i0.ɵɵelement(4, "i", 53);
166
+ i0.ɵɵelementStart(0, "div", 64)(1, "div", 65);
167
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Template_div_click_1_listener() { const ea_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.toggleEntityExpansion(ea_r5.entity.ID)); })("keydown.enter", function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Template_div_keydown_enter_1_listener() { const ea_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.toggleEntityExpansion(ea_r5.entity.ID)); })("keydown.space", function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Template_div_keydown_space_1_listener($event) { const ea_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.toggleEntityExpansion(ea_r5.entity.ID); return i0.ɵɵresetView($event.preventDefault()); });
168
+ i0.ɵɵelementStart(2, "div", 66)(3, "div", 67);
169
+ i0.ɵɵelement(4, "i", 68);
137
170
  i0.ɵɵelementEnd();
138
- i0.ɵɵelementStart(5, "div", 54)(6, "h3", 55);
171
+ i0.ɵɵelementStart(5, "div", 69)(6, "h3", 70);
139
172
  i0.ɵɵtext(7);
140
173
  i0.ɵɵelementEnd();
141
- i0.ɵɵelementStart(8, "p", 56);
174
+ i0.ɵɵelementStart(8, "p", 71);
142
175
  i0.ɵɵtext(9);
143
176
  i0.ɵɵelementEnd()()();
144
- i0.ɵɵelementStart(10, "div", 57)(11, "span", 58);
145
- i0.ɵɵelement(12, "i");
177
+ i0.ɵɵelementStart(10, "div", 72)(11, "span", 73);
178
+ i0.ɵɵelement(12, "i", 74);
146
179
  i0.ɵɵtext(13);
147
180
  i0.ɵɵelementEnd();
148
- i0.ɵɵelementStart(14, "button", 59);
149
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Template_button_click_14_listener($event) { const ea_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.editEntityPermissions(ea_r5); return i0.ɵɵresetView($event.stopPropagation()); })("mousedown", function EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Template_button_mousedown_14_listener($event) { i0.ɵɵrestoreView(_r4); return i0.ɵɵresetView($event.stopPropagation()); });
150
- i0.ɵɵelement(15, "i", 60);
151
- i0.ɵɵelementEnd();
152
- i0.ɵɵelementStart(16, "button", 61);
153
- i0.ɵɵelement(17, "i", 62);
181
+ i0.ɵɵelementStart(14, "div", 75);
182
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Template_div_click_14_listener($event) { i0.ɵɵrestoreView(_r4); return i0.ɵɵresetView($event.stopPropagation()); });
183
+ i0.ɵɵelementStart(15, "button", 76);
184
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Template_button_click_15_listener() { const ea_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.editEntityPermissions(ea_r5)); });
185
+ i0.ɵɵelement(16, "i", 77);
186
+ i0.ɵɵelementEnd()();
187
+ i0.ɵɵelementStart(17, "button", 78);
188
+ i0.ɵɵelement(18, "i", 79);
154
189
  i0.ɵɵelementEnd()()();
155
- i0.ɵɵtemplate(18, EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Conditional_18_Template, 3, 1, "div", 63);
190
+ i0.ɵɵtemplate(19, EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Conditional_19_Template, 12, 8, "div", 80);
156
191
  i0.ɵɵelementEnd();
157
192
  } if (rf & 2) {
158
193
  const ea_r5 = ctx.$implicit;
159
194
  const ctx_r2 = i0.ɵɵnextContext(3);
160
195
  i0.ɵɵclassProp("expanded", ctx_r2.isEntityExpanded(ea_r5.entity.ID));
161
- i0.ɵɵadvance(7);
196
+ i0.ɵɵattribute("aria-expanded", ctx_r2.isEntityExpanded(ea_r5.entity.ID));
197
+ i0.ɵɵadvance();
198
+ i0.ɵɵattribute("aria-label", "Expand permissions for " + ea_r5.entity.Name);
199
+ i0.ɵɵadvance(6);
162
200
  i0.ɵɵtextInterpolate(ea_r5.entity.Name);
163
201
  i0.ɵɵadvance(2);
164
202
  i0.ɵɵtextInterpolate(ea_r5.entity.Description || "No description available");
165
203
  i0.ɵɵadvance(2);
166
204
  i0.ɵɵclassMap(ctx_r2.getAccessLevelClass(ea_r5));
205
+ i0.ɵɵattribute("aria-label", "Access level: " + ctx_r2.getAccessLevelLabel(ea_r5));
167
206
  i0.ɵɵadvance();
168
207
  i0.ɵɵclassMap(ctx_r2.getAccessLevelClass(ea_r5) === "access-public" ? "fa-solid fa-globe" : ctx_r2.getAccessLevelClass(ea_r5) === "access-restricted" ? "fa-solid fa-lock" : "fa-solid fa-key");
169
208
  i0.ɵɵadvance();
170
209
  i0.ɵɵtextInterpolate1(" ", ctx_r2.getAccessLevelLabel(ea_r5), " ");
171
- i0.ɵɵadvance(5);
172
- i0.ɵɵconditional(ctx_r2.isEntityExpanded(ea_r5.entity.ID) ? 18 : -1);
210
+ i0.ɵɵadvance(2);
211
+ i0.ɵɵattribute("aria-label", "Edit permissions for " + ea_r5.entity.Name);
212
+ i0.ɵɵadvance(2);
213
+ i0.ɵɵattribute("aria-label", (ctx_r2.isEntityExpanded(ea_r5.entity.ID) ? "Collapse" : "Expand") + " permissions for " + ea_r5.entity.Name);
214
+ i0.ɵɵadvance(2);
215
+ i0.ɵɵconditional(ctx_r2.isEntityExpanded(ea_r5.entity.ID) ? 19 : -1);
173
216
  } }
174
- function EntityPermissionsComponent_Conditional_70_Conditional_1_Template(rf, ctx) { if (rf & 1) {
175
- i0.ɵɵelementStart(0, "div", 45);
176
- i0.ɵɵrepeaterCreate(1, EntityPermissionsComponent_Conditional_70_Conditional_1_For_2_Template, 19, 10, "div", 48, _forTrack1);
217
+ function EntityPermissionsComponent_Conditional_78_Conditional_1_Template(rf, ctx) { if (rf & 1) {
218
+ i0.ɵɵelementStart(0, "div", 60);
219
+ i0.ɵɵrepeaterCreate(1, EntityPermissionsComponent_Conditional_78_Conditional_1_For_2_Template, 20, 15, "div", 63, _forTrack1);
177
220
  i0.ɵɵelementEnd();
178
221
  } if (rf & 2) {
179
222
  const ctx_r2 = i0.ɵɵnextContext(2);
180
223
  i0.ɵɵadvance();
181
224
  i0.ɵɵrepeater(ctx_r2.filteredEntityAccess);
182
225
  } }
183
- function EntityPermissionsComponent_Conditional_70_Conditional_2_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
184
- i0.ɵɵelementStart(0, "span", 80);
226
+ function EntityPermissionsComponent_Conditional_78_Conditional_2_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
227
+ i0.ɵɵelementStart(0, "span", 102);
185
228
  i0.ɵɵtext(1);
186
229
  i0.ɵɵelementEnd();
187
230
  } if (rf & 2) {
188
- const ea_r8 = i0.ɵɵnextContext().$implicit;
231
+ const ea_r9 = i0.ɵɵnextContext().$implicit;
232
+ i0.ɵɵattribute("aria-label", ea_r9.permissions.length + " permission" + (ea_r9.permissions.length === 1 ? "" : "s"));
189
233
  i0.ɵɵadvance();
190
- i0.ɵɵtextInterpolate2(" ", ea_r8.permissions.length, " permission", ea_r8.permissions.length === 1 ? "" : "s", " ");
234
+ i0.ɵɵtextInterpolate2(" ", ea_r9.permissions.length, " permission", ea_r9.permissions.length === 1 ? "" : "s", " ");
191
235
  } }
192
- function EntityPermissionsComponent_Conditional_70_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
193
- const _r7 = i0.ɵɵgetCurrentView();
194
- i0.ɵɵelementStart(0, "div", 73)(1, "div", 74);
195
- i0.ɵɵelement(2, "i", 53);
196
- i0.ɵɵelementStart(3, "button", 75);
197
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_70_Conditional_2_For_2_Template_button_click_3_listener() { const ea_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.editEntityPermissions(ea_r8)); });
198
- i0.ɵɵelement(4, "i", 60);
236
+ function EntityPermissionsComponent_Conditional_78_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
237
+ const _r8 = i0.ɵɵgetCurrentView();
238
+ i0.ɵɵelementStart(0, "article", 95)(1, "div", 96);
239
+ i0.ɵɵelement(2, "i", 97);
240
+ i0.ɵɵelementStart(3, "button", 76);
241
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_78_Conditional_2_For_2_Template_button_click_3_listener() { const ea_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.editEntityPermissions(ea_r9)); });
242
+ i0.ɵɵelement(4, "i", 77);
199
243
  i0.ɵɵelementEnd()();
200
- i0.ɵɵelementStart(5, "h4", 76);
244
+ i0.ɵɵelementStart(5, "h4", 98);
201
245
  i0.ɵɵtext(6);
202
246
  i0.ɵɵelementEnd();
203
- i0.ɵɵelementStart(7, "p", 77);
247
+ i0.ɵɵelementStart(7, "p", 99);
204
248
  i0.ɵɵtext(8);
205
249
  i0.ɵɵelementEnd();
206
- i0.ɵɵelementStart(9, "div", 78)(10, "span", 79);
207
- i0.ɵɵelement(11, "i");
250
+ i0.ɵɵelementStart(9, "div", 100)(10, "span", 101);
251
+ i0.ɵɵelement(11, "i", 74);
208
252
  i0.ɵɵtext(12);
209
253
  i0.ɵɵelementEnd();
210
- i0.ɵɵtemplate(13, EntityPermissionsComponent_Conditional_70_Conditional_2_For_2_Conditional_13_Template, 2, 2, "span", 80);
254
+ i0.ɵɵtemplate(13, EntityPermissionsComponent_Conditional_78_Conditional_2_For_2_Conditional_13_Template, 2, 3, "span", 102);
211
255
  i0.ɵɵelementEnd()();
212
256
  } if (rf & 2) {
213
- const ea_r8 = ctx.$implicit;
257
+ const ea_r9 = ctx.$implicit;
214
258
  const ctx_r2 = i0.ɵɵnextContext(3);
215
- i0.ɵɵclassMap(ctx_r2.getAccessLevelClass(ea_r8));
216
- i0.ɵɵadvance(6);
217
- i0.ɵɵtextInterpolate(ea_r8.entity.Name);
218
- i0.ɵɵadvance(2);
219
- i0.ɵɵtextInterpolate(ea_r8.entity.Description || "No description");
259
+ i0.ɵɵclassMap(ctx_r2.getAccessLevelClass(ea_r9));
260
+ i0.ɵɵattribute("aria-label", "Entity: " + ea_r9.entity.Name);
261
+ i0.ɵɵadvance(3);
262
+ i0.ɵɵattribute("aria-label", "Edit permissions for " + ea_r9.entity.Name);
220
263
  i0.ɵɵadvance(3);
221
- i0.ɵɵclassMap(ctx_r2.getAccessLevelClass(ea_r8) === "access-public" ? "fa-solid fa-globe" : ctx_r2.getAccessLevelClass(ea_r8) === "access-restricted" ? "fa-solid fa-lock" : "fa-solid fa-key");
264
+ i0.ɵɵtextInterpolate(ea_r9.entity.Name);
265
+ i0.ɵɵadvance(2);
266
+ i0.ɵɵtextInterpolate(ea_r9.entity.Description || "No description");
267
+ i0.ɵɵadvance(2);
268
+ i0.ɵɵattribute("aria-label", "Access level: " + ctx_r2.getAccessLevelLabel(ea_r9));
269
+ i0.ɵɵadvance();
270
+ i0.ɵɵclassMap(ctx_r2.getAccessLevelClass(ea_r9) === "access-public" ? "fa-solid fa-globe" : ctx_r2.getAccessLevelClass(ea_r9) === "access-restricted" ? "fa-solid fa-lock" : "fa-solid fa-key");
222
271
  i0.ɵɵadvance();
223
- i0.ɵɵtextInterpolate1(" ", ctx_r2.getAccessLevelLabel(ea_r8), " ");
272
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.getAccessLevelLabel(ea_r9), " ");
224
273
  i0.ɵɵadvance();
225
- i0.ɵɵconditional(ea_r8.permissions.length > 0 ? 13 : -1);
274
+ i0.ɵɵconditional(ea_r9.permissions.length > 0 ? 13 : -1);
226
275
  } }
227
- function EntityPermissionsComponent_Conditional_70_Conditional_2_Template(rf, ctx) { if (rf & 1) {
228
- i0.ɵɵelementStart(0, "div", 46);
229
- i0.ɵɵrepeaterCreate(1, EntityPermissionsComponent_Conditional_70_Conditional_2_For_2_Template, 14, 8, "div", 72, _forTrack1);
276
+ function EntityPermissionsComponent_Conditional_78_Conditional_2_Template(rf, ctx) { if (rf & 1) {
277
+ i0.ɵɵelementStart(0, "div", 61);
278
+ i0.ɵɵrepeaterCreate(1, EntityPermissionsComponent_Conditional_78_Conditional_2_For_2_Template, 14, 11, "article", 94, _forTrack1);
230
279
  i0.ɵɵelementEnd();
231
280
  } if (rf & 2) {
232
281
  const ctx_r2 = i0.ɵɵnextContext(2);
233
282
  i0.ɵɵadvance();
234
283
  i0.ɵɵrepeater(ctx_r2.filteredEntityAccess);
235
284
  } }
236
- function EntityPermissionsComponent_Conditional_70_Conditional_3_Template(rf, ctx) { if (rf & 1) {
237
- i0.ɵɵelementStart(0, "div", 47);
238
- i0.ɵɵelement(1, "i", 81);
239
- i0.ɵɵelementStart(2, "p", 82);
240
- i0.ɵɵtext(3, "No entities found");
241
- i0.ɵɵelementEnd();
242
- i0.ɵɵelementStart(4, "p", 83);
243
- i0.ɵɵtext(5, "Try adjusting your filters to see more results");
285
+ function EntityPermissionsComponent_Conditional_78_Conditional_3_Template(rf, ctx) { if (rf & 1) {
286
+ const _r10 = i0.ɵɵgetCurrentView();
287
+ i0.ɵɵelementStart(0, "div", 62);
288
+ i0.ɵɵelement(1, "i", 103);
289
+ i0.ɵɵelementStart(2, "h3", 104);
290
+ i0.ɵɵtext(3, "No Permissions Found");
291
+ i0.ɵɵelementEnd();
292
+ i0.ɵɵelementStart(4, "p", 105);
293
+ i0.ɵɵtext(5, "Try adjusting your filters or refresh the data.");
294
+ i0.ɵɵelementEnd();
295
+ i0.ɵɵelementStart(6, "button", 106);
296
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_78_Conditional_3_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.refreshData()); });
297
+ i0.ɵɵelement(7, "i", 9);
298
+ i0.ɵɵtext(8, " Refresh ");
244
299
  i0.ɵɵelementEnd()();
245
300
  } }
246
- function EntityPermissionsComponent_Conditional_70_Template(rf, ctx) { if (rf & 1) {
247
- i0.ɵɵelementStart(0, "div", 36);
248
- i0.ɵɵtemplate(1, EntityPermissionsComponent_Conditional_70_Conditional_1_Template, 3, 0, "div", 45)(2, EntityPermissionsComponent_Conditional_70_Conditional_2_Template, 3, 0, "div", 46)(3, EntityPermissionsComponent_Conditional_70_Conditional_3_Template, 6, 0, "div", 47);
301
+ function EntityPermissionsComponent_Conditional_78_Template(rf, ctx) { if (rf & 1) {
302
+ i0.ɵɵelementStart(0, "div", 52);
303
+ i0.ɵɵtemplate(1, EntityPermissionsComponent_Conditional_78_Conditional_1_Template, 3, 0, "div", 60)(2, EntityPermissionsComponent_Conditional_78_Conditional_2_Template, 3, 0, "div", 61)(3, EntityPermissionsComponent_Conditional_78_Conditional_3_Template, 9, 0, "div", 62);
249
304
  i0.ɵɵelementEnd();
250
305
  } if (rf & 2) {
251
306
  const ctx_r2 = i0.ɵɵnextContext();
@@ -254,6 +309,108 @@ function EntityPermissionsComponent_Conditional_70_Template(rf, ctx) { if (rf &
254
309
  i0.ɵɵadvance(2);
255
310
  i0.ɵɵconditional(ctx_r2.filteredEntityAccess.length === 0 ? 3 : -1);
256
311
  } }
312
+ function EntityPermissionsComponent_Conditional_80_For_39_Template(rf, ctx) { if (rf & 1) {
313
+ const _r12 = i0.ɵɵgetCurrentView();
314
+ i0.ɵɵelementStart(0, "label", 118)(1, "input", 129);
315
+ i0.ɵɵlistener("change", function EntityPermissionsComponent_Conditional_80_For_39_Template_input_change_1_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onRoleFilterChange($event)); });
316
+ i0.ɵɵelementEnd();
317
+ i0.ɵɵelementStart(2, "span", 120);
318
+ i0.ɵɵtext(3);
319
+ i0.ɵɵelementEnd()();
320
+ } if (rf & 2) {
321
+ const role_r13 = ctx.$implicit;
322
+ const ctx_r2 = i0.ɵɵnextContext(2);
323
+ i0.ɵɵclassProp("selected", ctx_r2.filters$.value.roleId === role_r13.ID);
324
+ i0.ɵɵadvance();
325
+ i0.ɵɵproperty("value", role_r13.ID)("checked", ctx_r2.filters$.value.roleId === role_r13.ID);
326
+ i0.ɵɵadvance(2);
327
+ i0.ɵɵtextInterpolate(role_r13.Name);
328
+ } }
329
+ function EntityPermissionsComponent_Conditional_80_Template(rf, ctx) { if (rf & 1) {
330
+ const _r11 = i0.ɵɵgetCurrentView();
331
+ i0.ɵɵelementStart(0, "div", 107);
332
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_80_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showMobileFilters = false); });
333
+ i0.ɵɵelementStart(1, "div", 108);
334
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_80_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); });
335
+ i0.ɵɵelementStart(2, "div", 109)(3, "h3", 110);
336
+ i0.ɵɵelement(4, "i", 37);
337
+ i0.ɵɵtext(5, " Filters ");
338
+ i0.ɵɵelementEnd();
339
+ i0.ɵɵelementStart(6, "button", 111);
340
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_80_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showMobileFilters = false); });
341
+ i0.ɵɵelement(7, "i", 112);
342
+ i0.ɵɵelementEnd()();
343
+ i0.ɵɵelementStart(8, "div", 113)(9, "div", 114)(10, "div", 115)(11, "h4", 116);
344
+ i0.ɵɵtext(12, "Access Level");
345
+ i0.ɵɵelementEnd();
346
+ i0.ɵɵelementStart(13, "div", 117)(14, "label", 118)(15, "input", 119);
347
+ i0.ɵɵlistener("change", function EntityPermissionsComponent_Conditional_80_Template_input_change_15_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAccessLevelChange("all")); });
348
+ i0.ɵɵelementEnd();
349
+ i0.ɵɵelementStart(16, "span", 120);
350
+ i0.ɵɵtext(17, "All Levels");
351
+ i0.ɵɵelementEnd()();
352
+ i0.ɵɵelementStart(18, "label", 118)(19, "input", 121);
353
+ i0.ɵɵlistener("change", function EntityPermissionsComponent_Conditional_80_Template_input_change_19_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAccessLevelChange("public")); });
354
+ i0.ɵɵelementEnd();
355
+ i0.ɵɵelementStart(20, "span", 120);
356
+ i0.ɵɵtext(21, "Public Entities");
357
+ i0.ɵɵelementEnd()();
358
+ i0.ɵɵelementStart(22, "label", 118)(23, "input", 122);
359
+ i0.ɵɵlistener("change", function EntityPermissionsComponent_Conditional_80_Template_input_change_23_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAccessLevelChange("restricted")); });
360
+ i0.ɵɵelementEnd();
361
+ i0.ɵɵelementStart(24, "span", 120);
362
+ i0.ɵɵtext(25, "Restricted Entities");
363
+ i0.ɵɵelementEnd()();
364
+ i0.ɵɵelementStart(26, "label", 118)(27, "input", 123);
365
+ i0.ɵɵlistener("change", function EntityPermissionsComponent_Conditional_80_Template_input_change_27_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAccessLevelChange("custom")); });
366
+ i0.ɵɵelementEnd();
367
+ i0.ɵɵelementStart(28, "span", 120);
368
+ i0.ɵɵtext(29, "Custom Access Entities");
369
+ i0.ɵɵelementEnd()()()();
370
+ i0.ɵɵelementStart(30, "div", 115)(31, "h4", 116);
371
+ i0.ɵɵtext(32, "Filter by Role");
372
+ i0.ɵɵelementEnd();
373
+ i0.ɵɵelementStart(33, "div", 117)(34, "label", 118)(35, "input", 124);
374
+ i0.ɵɵlistener("change", function EntityPermissionsComponent_Conditional_80_Template_input_change_35_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onRoleFilterChange($event)); });
375
+ i0.ɵɵelementEnd();
376
+ i0.ɵɵelementStart(36, "span", 120);
377
+ i0.ɵɵtext(37, "All Roles");
378
+ i0.ɵɵelementEnd()();
379
+ i0.ɵɵrepeaterCreate(38, EntityPermissionsComponent_Conditional_80_For_39_Template, 4, 5, "label", 125, _forTrack0);
380
+ i0.ɵɵelementEnd()()()();
381
+ i0.ɵɵelementStart(40, "div", 126)(41, "button", 127);
382
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_80_Template_button_click_41_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showMobileFilters = false); });
383
+ i0.ɵɵtext(42, " Apply Filters ");
384
+ i0.ɵɵelementEnd();
385
+ i0.ɵɵelementStart(43, "button", 128);
386
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_80_Template_button_click_43_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showMobileFilters = false); });
387
+ i0.ɵɵtext(44, " Cancel ");
388
+ i0.ɵɵelementEnd()()()();
389
+ } if (rf & 2) {
390
+ const ctx_r2 = i0.ɵɵnextContext();
391
+ i0.ɵɵadvance(14);
392
+ i0.ɵɵclassProp("selected", ctx_r2.filters$.value.accessLevel === "all");
393
+ i0.ɵɵadvance();
394
+ i0.ɵɵproperty("checked", ctx_r2.filters$.value.accessLevel === "all");
395
+ i0.ɵɵadvance(3);
396
+ i0.ɵɵclassProp("selected", ctx_r2.filters$.value.accessLevel === "public");
397
+ i0.ɵɵadvance();
398
+ i0.ɵɵproperty("checked", ctx_r2.filters$.value.accessLevel === "public");
399
+ i0.ɵɵadvance(3);
400
+ i0.ɵɵclassProp("selected", ctx_r2.filters$.value.accessLevel === "restricted");
401
+ i0.ɵɵadvance();
402
+ i0.ɵɵproperty("checked", ctx_r2.filters$.value.accessLevel === "restricted");
403
+ i0.ɵɵadvance(3);
404
+ i0.ɵɵclassProp("selected", ctx_r2.filters$.value.accessLevel === "custom");
405
+ i0.ɵɵadvance();
406
+ i0.ɵɵproperty("checked", ctx_r2.filters$.value.accessLevel === "custom");
407
+ i0.ɵɵadvance(7);
408
+ i0.ɵɵclassProp("selected", !ctx_r2.filters$.value.roleId);
409
+ i0.ɵɵadvance();
410
+ i0.ɵɵproperty("checked", !ctx_r2.filters$.value.roleId);
411
+ i0.ɵɵadvance(3);
412
+ i0.ɵɵrepeater(ctx_r2.roles);
413
+ } }
257
414
  let EntityPermissionsComponent = class EntityPermissionsComponent extends BaseDashboard {
258
415
  // State management
259
416
  entityAccess = [];
@@ -280,6 +437,7 @@ let EntityPermissionsComponent = class EntityPermissionsComponent extends BaseDa
280
437
  // UI State
281
438
  expandedEntityId = null;
282
439
  viewMode = 'list';
440
+ showMobileFilters = false;
283
441
  destroy$ = new Subject();
284
442
  metadata = new Metadata();
285
443
  constructor() {
@@ -515,104 +673,117 @@ let EntityPermissionsComponent = class EntityPermissionsComponent extends BaseDa
515
673
  this.viewMode = mode;
516
674
  }
517
675
  static ɵfac = function EntityPermissionsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || EntityPermissionsComponent)(); };
518
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityPermissionsComponent, selectors: [["mj-entity-permissions"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 72, vars: 25, consts: [[1, "entity-permissions-container"], [1, "action-buttons"], [1, "mj-view-toggle"], ["title", "List View", 1, "mj-btn", "mj-btn-ghost", 3, "click"], [1, "fa-solid", "fa-list"], ["title", "Grid View", 1, "mj-btn", "mj-btn-ghost", 3, "click"], [1, "fa-solid", "fa-th"], [1, "mj-btn", "mj-btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-refresh"], [1, "mj-grid", "mj-grid-4"], [1, "mj-card"], [1, "stat-icon", "stat-icon-total"], [1, "fa-solid", "fa-database"], [1, "stat-content"], [1, "stat-value"], [1, "stat-label"], [1, "stat-icon", "stat-icon-public"], [1, "fa-solid", "fa-globe"], [1, "stat-icon", "stat-icon-restricted"], [1, "fa-solid", "fa-lock"], [1, "stat-icon", "stat-icon-permissions"], [1, "fa-solid", "fa-key"], [1, "filters-section"], [1, "filters-row"], [1, "mj-search"], [1, "fa-solid", "fa-search", "mj-search-icon"], ["type", "text", "placeholder", "Search entities by name or description...", 1, "mj-search-input", 3, "input", "value"], [1, "mj-filter-group"], [1, "mj-filter-label"], [1, "mj-filter-buttons"], [1, "mj-btn", "mj-btn-ghost", 3, "click"], [1, "mj-select", 3, "change"], ["value", ""], [3, "value"], [1, "loading-container"], [1, "error-container"], [1, "content-area"], [3, "result", "visible", "data"], [1, "loading-spinner"], [1, "spinner-ring"], [1, "loading-text"], [1, "error-content"], [1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], [1, "mj-btn", "mj-btn-primary", 3, "click"], [1, "entities-list"], [1, "entities-grid"], [1, "empty-state"], [1, "entity-card", 3, "expanded"], [1, "entity-card"], [1, "entity-header", 3, "click"], [1, "entity-info"], [1, "entity-icon-wrapper"], [1, "fa-solid", "fa-table"], [1, "entity-details"], [1, "entity-name"], [1, "entity-description"], [1, "entity-meta"], [1, "access-badge"], ["type", "button", "title", "Edit Permissions", 1, "btn-edit", 3, "click", "mousedown"], [1, "fa-solid", "fa-edit"], [1, "expand-btn"], [1, "fa-solid", "fa-chevron-down"], [1, "entity-content"], [1, "permissions-grid"], [1, "no-permissions"], [1, "permissions-header"], [1, "role-header"], [1, "permission-header"], [1, "permission-row"], [1, "role-name"], [1, "permission-cell"], [1, "entity-grid-card", 3, "class"], [1, "entity-grid-card"], [1, "grid-card-header"], ["type", "button", "title", "Edit Permissions", 1, "btn-edit", 3, "click"], [1, "grid-card-title"], [1, "grid-card-description"], [1, "grid-card-footer"], [1, "access-label"], [1, "permission-count"], [1, "fa-solid", "fa-key", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"]], template: function EntityPermissionsComponent_Template(rf, ctx) { if (rf & 1) {
519
- i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "button", 3);
520
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_3_listener() { return ctx.setViewMode("list"); });
521
- i0.ɵɵelement(4, "i", 4);
676
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityPermissionsComponent, selectors: [["mj-entity-permissions"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 81, vars: 34, consts: [[1, "entity-permissions-container"], [1, "sticky-header"], ["role", "toolbar", "aria-label", "Entity permissions actions", 1, "action-buttons"], [1, "mj-view-toggle"], ["role", "button", "tabindex", "0", "title", "List View", 1, "mj-btn", "mj-btn-ghost", 3, "click", "keydown.enter", "keydown.space"], ["aria-hidden", "true", 1, "fa-solid", "fa-list"], ["role", "button", "tabindex", "0", "title", "Grid View", 1, "mj-btn", "mj-btn-ghost", 3, "click", "keydown.enter", "keydown.space"], ["aria-hidden", "true", 1, "fa-solid", "fa-th"], ["aria-label", "Refresh entity permissions data", "title", "Refresh", 1, "mj-btn", "mj-btn-secondary", "mj-btn-icon-mobile", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-refresh"], [1, "btn-text"], ["role", "region", "aria-label", "Permission statistics", 1, "mj-grid-4"], ["role", "article", "aria-label", "Total entities statistic", 1, "mj-card"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-total"], [1, "fa-solid", "fa-database"], [1, "stat-content"], ["aria-label", "Total entities count", 1, "stat-value"], [1, "stat-label"], ["role", "article", "aria-label", "Public entities statistic", 1, "mj-card"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-public"], [1, "fa-solid", "fa-globe"], ["aria-label", "Public entities count", 1, "stat-value"], ["role", "article", "aria-label", "Restricted entities statistic", 1, "mj-card"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-restricted"], [1, "fa-solid", "fa-lock"], ["aria-label", "Restricted entities count", 1, "stat-value"], ["role", "article", "aria-label", "Total permissions statistic", 1, "mj-card"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-permissions"], [1, "fa-solid", "fa-key"], ["aria-label", "Total permissions count", 1, "stat-value"], ["role", "search", "aria-label", "Entity filters", 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 entities by name or description...", "aria-label", "Search entities", 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", "access-level-label", 1, "mj-filter-label"], ["role", "group", "aria-labelledby", "access-level-label", 1, "mj-filter-buttons"], ["aria-label", "Show all access levels", 1, "mj-btn", "mj-btn-ghost", 3, "click"], ["aria-label", "Show only public entities", 1, "mj-btn", "mj-btn-ghost", 3, "click"], ["aria-label", "Show only restricted entities", 1, "mj-btn", "mj-btn-ghost", 3, "click"], ["aria-label", "Show only custom access entities", 1, "mj-btn", "mj-btn-ghost", 3, "click"], ["for", "role-filter", 1, "mj-filter-label"], ["id", "role-filter", "aria-label", "Filter entities by role", 1, "mj-filter-select", 3, "change"], ["value", ""], [3, "value"], [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", "visible", "data"], ["role", "presentation", 1, "filter-modal-backdrop"], ["text", "Loading entity permissions...", "size", "medium"], [1, "error-content"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], ["aria-label", "Retry loading entity permissions", 1, "mj-btn", "mj-btn-primary", 3, "click"], ["role", "list", "aria-label", "Entity permissions list", 1, "entities-list"], ["role", "list", "aria-label", "Entity permissions grid", 1, "entities-grid"], ["role", "status", 1, "empty-state"], ["role", "listitem", 1, "entity-card", 3, "expanded"], ["role", "listitem", 1, "entity-card"], ["tabindex", "0", "role", "button", 1, "entity-header", 3, "click", "keydown.enter", "keydown.space"], [1, "entity-info"], ["aria-hidden", "true", 1, "entity-icon-wrapper"], [1, "fa-solid", "fa-table"], [1, "entity-details"], [1, "entity-name"], [1, "entity-description"], [1, "entity-meta"], [1, "access-badge"], ["aria-hidden", "true"], [1, "entity-actions", 3, "click"], ["title", "Edit Permissions", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-edit"], [1, "expand-btn"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], ["role", "region", 1, "entity-content"], [1, "mobile-actions-bar", 3, "click"], [1, "mobile-action-buttons"], [1, "btn-label"], ["role", "table", "aria-label", "Role permissions", 1, "permissions-grid"], [1, "no-permissions"], ["role", "rowgroup", 1, "permissions-header"], ["role", "row"], ["scope", "col", "role", "columnheader", 1, "role-header"], ["scope", "col", "role", "columnheader", 1, "permission-header"], ["role", "rowgroup"], ["role", "row", 1, "permission-row"], ["role", "cell", 1, "role-name"], ["role", "cell", 1, "permission-cell"], [1, "entity-grid-card", 3, "class"], [1, "entity-grid-card"], [1, "grid-card-header"], ["aria-hidden", "true", 1, "fa-solid", "fa-table"], [1, "grid-card-title"], [1, "grid-card-description"], [1, "grid-card-footer"], [1, "access-label"], [1, "permission-count"], ["aria-hidden", "true", 1, "fa-solid", "fa-shield-alt", "empty-state-icon"], [1, "empty-text"], [1, "empty-subtext"], ["aria-label", "Refresh permissions data", 1, "mj-btn", "mj-btn-primary", 3, "click"], ["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"], ["aria-hidden", "true", 1, "fa-solid", "fa-times"], [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", "accessLevel", "value", "all", 3, "change", "checked"], [1, "filter-option-label"], ["type", "radio", "name", "accessLevel", "value", "public", 3, "change", "checked"], ["type", "radio", "name", "accessLevel", "value", "restricted", 3, "change", "checked"], ["type", "radio", "name", "accessLevel", "value", "custom", 3, "change", "checked"], ["type", "radio", "name", "role", "value", "", 3, "change", "checked"], [1, "filter-option", 3, "selected"], [1, "filter-modal-footer"], [1, "mj-btn", "mj-btn-primary", 3, "click"], [1, "mj-btn", "mj-btn-secondary", 3, "click"], ["type", "radio", "name", "role", 3, "change", "value", "checked"]], template: function EntityPermissionsComponent_Template(rf, ctx) { if (rf & 1) {
677
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3)(4, "button", 4);
678
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_4_listener() { return ctx.setViewMode("list"); })("keydown.enter", function EntityPermissionsComponent_Template_button_keydown_enter_4_listener() { return ctx.setViewMode("list"); })("keydown.space", function EntityPermissionsComponent_Template_button_keydown_space_4_listener($event) { ctx.setViewMode("list"); return $event.preventDefault(); });
679
+ i0.ɵɵelement(5, "i", 5);
522
680
  i0.ɵɵelementEnd();
523
- i0.ɵɵelementStart(5, "button", 5);
524
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_5_listener() { return ctx.setViewMode("grid"); });
525
- i0.ɵɵelement(6, "i", 6);
526
- i0.ɵɵelementEnd()();
527
- i0.ɵɵelementStart(7, "button", 7);
528
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_7_listener() { return ctx.refreshData(); });
529
- i0.ɵɵelement(8, "i", 8);
530
- i0.ɵɵtext(9, " Refresh ");
681
+ i0.ɵɵelementStart(6, "button", 6);
682
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_6_listener() { return ctx.setViewMode("grid"); })("keydown.enter", function EntityPermissionsComponent_Template_button_keydown_enter_6_listener() { return ctx.setViewMode("grid"); })("keydown.space", function EntityPermissionsComponent_Template_button_keydown_space_6_listener($event) { ctx.setViewMode("grid"); return $event.preventDefault(); });
683
+ i0.ɵɵelement(7, "i", 7);
531
684
  i0.ɵɵelementEnd()();
532
- i0.ɵɵelementStart(10, "div", 9)(11, "div", 10)(12, "div", 11);
533
- i0.ɵɵelement(13, "i", 12);
685
+ i0.ɵɵelementStart(8, "button", 8);
686
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_8_listener() { return ctx.refreshData(); });
687
+ i0.ɵɵelement(9, "i", 9);
688
+ i0.ɵɵelementStart(10, "span", 10);
689
+ i0.ɵɵtext(11, "Refresh");
690
+ i0.ɵɵelementEnd()()();
691
+ i0.ɵɵelementStart(12, "div", 11)(13, "div", 12)(14, "div", 13);
692
+ i0.ɵɵelement(15, "i", 14);
534
693
  i0.ɵɵelementEnd();
535
- i0.ɵɵelementStart(14, "div", 13)(15, "div", 14);
536
- i0.ɵɵtext(16);
694
+ i0.ɵɵelementStart(16, "div", 15)(17, "div", 16);
695
+ i0.ɵɵtext(18);
537
696
  i0.ɵɵelementEnd();
538
- i0.ɵɵelementStart(17, "div", 15);
539
- i0.ɵɵtext(18, "Total Entities");
697
+ i0.ɵɵelementStart(19, "div", 17);
698
+ i0.ɵɵtext(20, "Total Entities");
540
699
  i0.ɵɵelementEnd()()();
541
- i0.ɵɵelementStart(19, "div", 10)(20, "div", 16);
542
- i0.ɵɵelement(21, "i", 17);
700
+ i0.ɵɵelementStart(21, "div", 18)(22, "div", 19);
701
+ i0.ɵɵelement(23, "i", 20);
543
702
  i0.ɵɵelementEnd();
544
- i0.ɵɵelementStart(22, "div", 13)(23, "div", 14);
545
- i0.ɵɵtext(24);
703
+ i0.ɵɵelementStart(24, "div", 15)(25, "div", 21);
704
+ i0.ɵɵtext(26);
546
705
  i0.ɵɵelementEnd();
547
- i0.ɵɵelementStart(25, "div", 15);
548
- i0.ɵɵtext(26, "Public Entities");
706
+ i0.ɵɵelementStart(27, "div", 17);
707
+ i0.ɵɵtext(28, "Public Entities");
549
708
  i0.ɵɵelementEnd()()();
550
- i0.ɵɵelementStart(27, "div", 10)(28, "div", 18);
551
- i0.ɵɵelement(29, "i", 19);
709
+ i0.ɵɵelementStart(29, "div", 22)(30, "div", 23);
710
+ i0.ɵɵelement(31, "i", 24);
552
711
  i0.ɵɵelementEnd();
553
- i0.ɵɵelementStart(30, "div", 13)(31, "div", 14);
554
- i0.ɵɵtext(32);
712
+ i0.ɵɵelementStart(32, "div", 15)(33, "div", 25);
713
+ i0.ɵɵtext(34);
555
714
  i0.ɵɵelementEnd();
556
- i0.ɵɵelementStart(33, "div", 15);
557
- i0.ɵɵtext(34, "Restricted Entities");
715
+ i0.ɵɵelementStart(35, "div", 17);
716
+ i0.ɵɵtext(36, "Restricted Entities");
558
717
  i0.ɵɵelementEnd()()();
559
- i0.ɵɵelementStart(35, "div", 10)(36, "div", 20);
560
- i0.ɵɵelement(37, "i", 21);
718
+ i0.ɵɵelementStart(37, "div", 26)(38, "div", 27);
719
+ i0.ɵɵelement(39, "i", 28);
561
720
  i0.ɵɵelementEnd();
562
- i0.ɵɵelementStart(38, "div", 13)(39, "div", 14);
563
- i0.ɵɵtext(40);
721
+ i0.ɵɵelementStart(40, "div", 15)(41, "div", 29);
722
+ i0.ɵɵtext(42);
564
723
  i0.ɵɵelementEnd();
565
- i0.ɵɵelementStart(41, "div", 15);
566
- i0.ɵɵtext(42, "Total Permissions");
724
+ i0.ɵɵelementStart(43, "div", 17);
725
+ i0.ɵɵtext(44, "Total Permissions");
567
726
  i0.ɵɵelementEnd()()()();
568
- i0.ɵɵelementStart(43, "div", 22)(44, "div", 23)(45, "div", 24);
569
- i0.ɵɵelement(46, "i", 25);
570
- i0.ɵɵelementStart(47, "input", 26);
571
- i0.ɵɵlistener("input", function EntityPermissionsComponent_Template_input_input_47_listener($event) { return ctx.onSearchChange($event); });
727
+ i0.ɵɵelementStart(45, "div", 30)(46, "div", 31)(47, "div", 32)(48, "div", 33);
728
+ i0.ɵɵelement(49, "i", 34);
729
+ i0.ɵɵelementStart(50, "input", 35);
730
+ i0.ɵɵlistener("input", function EntityPermissionsComponent_Template_input_input_50_listener($event) { return ctx.onSearchChange($event); });
572
731
  i0.ɵɵelementEnd()();
573
- i0.ɵɵelementStart(48, "div", 27)(49, "label", 28);
574
- i0.ɵɵtext(50, "Access Level");
732
+ i0.ɵɵelementStart(51, "button", 36);
733
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_51_listener() { return ctx.showMobileFilters = true; });
734
+ i0.ɵɵelement(52, "i", 37);
735
+ i0.ɵɵelementStart(53, "span");
736
+ i0.ɵɵtext(54, "Filters");
737
+ i0.ɵɵelementEnd()()();
738
+ i0.ɵɵelementStart(55, "div", 38)(56, "label", 39);
739
+ i0.ɵɵtext(57, "Access Level");
575
740
  i0.ɵɵelementEnd();
576
- i0.ɵɵelementStart(51, "div", 29)(52, "button", 30);
577
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_52_listener() { return ctx.onAccessLevelChange("all"); });
578
- i0.ɵɵtext(53, " All ");
741
+ i0.ɵɵelementStart(58, "div", 40)(59, "button", 41);
742
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_59_listener() { return ctx.onAccessLevelChange("all"); });
743
+ i0.ɵɵtext(60, " All ");
579
744
  i0.ɵɵelementEnd();
580
- i0.ɵɵelementStart(54, "button", 30);
581
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_54_listener() { return ctx.onAccessLevelChange("public"); });
582
- i0.ɵɵtext(55, " Public ");
745
+ i0.ɵɵelementStart(61, "button", 42);
746
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_61_listener() { return ctx.onAccessLevelChange("public"); });
747
+ i0.ɵɵtext(62, " Public ");
583
748
  i0.ɵɵelementEnd();
584
- i0.ɵɵelementStart(56, "button", 30);
585
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_56_listener() { return ctx.onAccessLevelChange("restricted"); });
586
- i0.ɵɵtext(57, " Restricted ");
749
+ i0.ɵɵelementStart(63, "button", 43);
750
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_63_listener() { return ctx.onAccessLevelChange("restricted"); });
751
+ i0.ɵɵtext(64, " Restricted ");
587
752
  i0.ɵɵelementEnd();
588
- i0.ɵɵelementStart(58, "button", 30);
589
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_58_listener() { return ctx.onAccessLevelChange("custom"); });
590
- i0.ɵɵtext(59, " Custom ");
753
+ i0.ɵɵelementStart(65, "button", 44);
754
+ i0.ɵɵlistener("click", function EntityPermissionsComponent_Template_button_click_65_listener() { return ctx.onAccessLevelChange("custom"); });
755
+ i0.ɵɵtext(66, " Custom ");
591
756
  i0.ɵɵelementEnd()()();
592
- i0.ɵɵelementStart(60, "div", 27)(61, "label", 28);
593
- i0.ɵɵtext(62, "Filter by Role");
757
+ i0.ɵɵelementStart(67, "div", 38)(68, "label", 45);
758
+ i0.ɵɵtext(69, "Filter by Role");
594
759
  i0.ɵɵelementEnd();
595
- i0.ɵɵelementStart(63, "select", 31);
596
- i0.ɵɵlistener("change", function EntityPermissionsComponent_Template_select_change_63_listener($event) { return ctx.onRoleFilterChange($event); });
597
- i0.ɵɵelementStart(64, "option", 32);
598
- i0.ɵɵtext(65, "All Roles");
760
+ i0.ɵɵelementStart(70, "select", 46);
761
+ i0.ɵɵlistener("change", function EntityPermissionsComponent_Template_select_change_70_listener($event) { return ctx.onRoleFilterChange($event); });
762
+ i0.ɵɵelementStart(71, "option", 47);
763
+ i0.ɵɵtext(72, "All Roles");
764
+ i0.ɵɵelementEnd();
765
+ i0.ɵɵrepeaterCreate(73, EntityPermissionsComponent_For_74_Template, 2, 2, "option", 48, _forTrack0);
766
+ i0.ɵɵelementEnd()()()()();
767
+ i0.ɵɵelementStart(75, "div", 49);
768
+ i0.ɵɵtemplate(76, EntityPermissionsComponent_Conditional_76_Template, 2, 0, "div", 50)(77, EntityPermissionsComponent_Conditional_77_Template, 8, 1, "div", 51)(78, EntityPermissionsComponent_Conditional_78_Template, 4, 2, "div", 52);
769
+ i0.ɵɵelementEnd();
770
+ i0.ɵɵelementStart(79, "mj-permission-dialog", 53);
771
+ i0.ɵɵlistener("result", function EntityPermissionsComponent_Template_mj_permission_dialog_result_79_listener($event) { return ctx.onPermissionDialogResult($event); });
772
+ i0.ɵɵelementEnd();
773
+ i0.ɵɵtemplate(80, EntityPermissionsComponent_Conditional_80_Template, 45, 15, "div", 54);
599
774
  i0.ɵɵelementEnd();
600
- i0.ɵɵrepeaterCreate(66, EntityPermissionsComponent_For_67_Template, 2, 2, "option", 33, _forTrack0);
601
- i0.ɵɵelementEnd()()()();
602
- i0.ɵɵtemplate(68, EntityPermissionsComponent_Conditional_68_Template, 7, 0, "div", 34)(69, EntityPermissionsComponent_Conditional_69_Template, 8, 1, "div", 35)(70, EntityPermissionsComponent_Conditional_70_Template, 4, 2, "div", 36);
603
- i0.ɵɵelementStart(71, "mj-permission-dialog", 37);
604
- i0.ɵɵlistener("result", function EntityPermissionsComponent_Template_mj_permission_dialog_result_71_listener($event) { return ctx.onPermissionDialogResult($event); });
605
- i0.ɵɵelementEnd()();
606
775
  } if (rf & 2) {
607
- i0.ɵɵadvance(3);
776
+ i0.ɵɵadvance(4);
608
777
  i0.ɵɵclassProp("mj-btn-primary", ctx.viewMode === "list");
778
+ i0.ɵɵattribute("aria-label", "List view" + (ctx.viewMode === "list" ? " (active)" : ""))("aria-pressed", ctx.viewMode === "list");
609
779
  i0.ɵɵadvance(2);
610
780
  i0.ɵɵclassProp("mj-btn-primary", ctx.viewMode === "grid");
781
+ i0.ɵɵattribute("aria-label", "Grid view" + (ctx.viewMode === "grid" ? " (active)" : ""))("aria-pressed", ctx.viewMode === "grid");
611
782
  i0.ɵɵadvance(2);
612
783
  i0.ɵɵproperty("disabled", ctx.isLoading);
613
784
  i0.ɵɵadvance();
614
785
  i0.ɵɵclassProp("fa-spin", ctx.isLoading);
615
- i0.ɵɵadvance(8);
786
+ i0.ɵɵadvance(9);
616
787
  i0.ɵɵtextInterpolate(ctx.stats.totalEntities);
617
788
  i0.ɵɵadvance(8);
618
789
  i0.ɵɵtextInterpolate(ctx.stats.publicEntities);
@@ -620,27 +791,33 @@ let EntityPermissionsComponent = class EntityPermissionsComponent extends BaseDa
620
791
  i0.ɵɵtextInterpolate(ctx.stats.restrictedEntities);
621
792
  i0.ɵɵadvance(8);
622
793
  i0.ɵɵtextInterpolate(ctx.stats.totalPermissions);
623
- i0.ɵɵadvance(7);
794
+ i0.ɵɵadvance(8);
624
795
  i0.ɵɵproperty("value", ctx.filters$.value.entitySearch);
625
- i0.ɵɵadvance(5);
796
+ i0.ɵɵadvance(9);
626
797
  i0.ɵɵclassProp("mj-btn-primary", ctx.filters$.value.accessLevel === "all");
798
+ i0.ɵɵattribute("aria-pressed", ctx.filters$.value.accessLevel === "all");
627
799
  i0.ɵɵadvance(2);
628
800
  i0.ɵɵclassProp("mj-btn-primary", ctx.filters$.value.accessLevel === "public");
801
+ i0.ɵɵattribute("aria-pressed", ctx.filters$.value.accessLevel === "public");
629
802
  i0.ɵɵadvance(2);
630
803
  i0.ɵɵclassProp("mj-btn-primary", ctx.filters$.value.accessLevel === "restricted");
804
+ i0.ɵɵattribute("aria-pressed", ctx.filters$.value.accessLevel === "restricted");
631
805
  i0.ɵɵadvance(2);
632
806
  i0.ɵɵclassProp("mj-btn-primary", ctx.filters$.value.accessLevel === "custom");
807
+ i0.ɵɵattribute("aria-pressed", ctx.filters$.value.accessLevel === "custom");
633
808
  i0.ɵɵadvance(8);
634
809
  i0.ɵɵrepeater(ctx.roles);
635
- i0.ɵɵadvance(2);
636
- i0.ɵɵconditional(ctx.isLoading ? 68 : -1);
810
+ i0.ɵɵadvance(3);
811
+ i0.ɵɵconditional(ctx.isLoading ? 76 : -1);
637
812
  i0.ɵɵadvance();
638
- i0.ɵɵconditional(ctx.error && !ctx.isLoading ? 69 : -1);
813
+ i0.ɵɵconditional(ctx.error && !ctx.isLoading ? 77 : -1);
639
814
  i0.ɵɵadvance();
640
- i0.ɵɵconditional(!ctx.isLoading && !ctx.error ? 70 : -1);
815
+ i0.ɵɵconditional(!ctx.isLoading && !ctx.error ? 78 : -1);
641
816
  i0.ɵɵadvance();
642
817
  i0.ɵɵproperty("visible", ctx.showPermissionDialog)("data", ctx.permissionDialogData);
643
- } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i2.PermissionDialogComponent], styles: ["@keyframes _ngcontent-%COMP%_shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.entity-permissions-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n max-width: 1400px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n.action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n justify-content: space-between;\n margin-bottom: 1.5rem;\n}\n@media (max-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}\n\n.view-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n\n.view-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.view-btn[_ngcontent-%COMP%]:hover {\n color: #374151;\n}\n.view-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.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\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.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-public[_ngcontent-%COMP%] {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n.stat-icon-restricted[_ngcontent-%COMP%] {\n background: rgba(244, 67, 54, 0.1);\n color: #f44336;\n}\n.stat-icon-permissions[_ngcontent-%COMP%] {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\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\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.filter-group[_ngcontent-%COMP%] .filter-select[_ngcontent-%COMP%] {\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n background: white;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group[_ngcontent-%COMP%] .filter-select[_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.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.entities-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.entity-card[_ngcontent-%COMP%] {\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.3s ease;\n}\n.entity-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n.entity-card.expanded[_ngcontent-%COMP%] {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n.entity-card.expanded[_ngcontent-%COMP%] .expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.entity-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.entity-header[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n}\n\n.entity-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex: 1;\n}\n\n.entity-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.entity-details[_ngcontent-%COMP%] {\n flex: 1;\n}\n.entity-details[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n}\n.entity-details[_ngcontent-%COMP%] .entity-description[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0;\n}\n\n.entity-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.access-badge[_ngcontent-%COMP%] {\n padding: 0.375rem 0.75rem;\n border-radius: 20px;\n font-size: 0.75rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.375rem;\n}\n.access-badge.access-public[_ngcontent-%COMP%] {\n background: rgba(76, 175, 80, 0.1);\n color: #388e3c;\n}\n.access-badge.access-restricted[_ngcontent-%COMP%] {\n background: rgba(244, 67, 54, 0.1);\n color: #d32f2f;\n}\n.access-badge.access-custom[_ngcontent-%COMP%] {\n background: rgba(156, 39, 176, 0.1);\n color: #7b1fa2;\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 {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\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.entity-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.permissions-grid[_ngcontent-%COMP%] {\n background: #f9fafb;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.permissions-header[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 1rem;\n padding: 1rem;\n background: #e5e7eb;\n font-weight: 600;\n color: #374151;\n font-size: 0.875rem;\n}\n\n.permission-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 1rem;\n padding: 1rem;\n border-bottom: 1px solid #e5e7eb;\n transition: background-color 0.2s;\n}\n.permission-row[_ngcontent-%COMP%]:hover {\n background: white;\n}\n.permission-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.role-header[_ngcontent-%COMP%], .permission-header[_ngcontent-%COMP%] {\n text-align: left;\n}\n\n.role-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: #1f2937;\n}\n\n.permission-cell[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.text-success[_ngcontent-%COMP%] {\n color: #4caf50;\n}\n\n.text-muted[_ngcontent-%COMP%] {\n color: #d1d5db;\n}\n\n.no-permissions[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.875rem;\n margin: 0;\n}\n\n.entities-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 1.5rem;\n}\n\n.entity-grid-card[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n padding: 1.5rem;\n transition: all 0.3s ease;\n position: relative;\n}\n.entity-grid-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n.entity-grid-card.access-public[_ngcontent-%COMP%] {\n border-left: 4px solid #4caf50;\n}\n.entity-grid-card.access-restricted[_ngcontent-%COMP%] {\n border-left: 4px solid #f44336;\n}\n.entity-grid-card.access-custom[_ngcontent-%COMP%] {\n border-left: 4px solid #9c27b0;\n}\n\n.grid-card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1rem;\n font-size: 1.5rem;\n color: #2196f3;\n}\n\n.edit-btn[_ngcontent-%COMP%] {\n padding: 0.375rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.edit-btn[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n color: #2196f3;\n}\n\n.grid-card-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.5rem 0;\n}\n\n.grid-card-description[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0 0 1rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.grid-card-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.875rem;\n}\n\n.access-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n font-weight: 500;\n}\n\n.permission-count[_ngcontent-%COMP%] {\n color: #6b7280;\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 #4caf50 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.modal-dialog.modal-large[_ngcontent-%COMP%] {\n max-width: 800px;\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 max-height: 60vh;\n overflow-y: auto;\n}\n.modal-body[_ngcontent-%COMP%] .modal-description[_ngcontent-%COMP%] {\n color: #374151;\n margin: 0 0 1.5rem 0;\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.permission-editor[_ngcontent-%COMP%] {\n padding: 2rem;\n background: #f3f4f6;\n border-radius: 8px;\n text-align: center;\n}\n.permission-editor[_ngcontent-%COMP%] .coming-soon[_ngcontent-%COMP%] {\n color: #6b7280;\n margin: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\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: 800px;\n }\n}\n.btn-edit[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n background: white;\n color: #666666;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n}\n.btn-edit[_ngcontent-%COMP%]:hover {\n background: #f8f9fa;\n border-color: #2196f3;\n color: #2196f3;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n}\n.btn-edit[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n}"] });
818
+ i0.ɵɵadvance();
819
+ i0.ɵɵconditional(ctx.showMobileFilters ? 80 : -1);
820
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i2.LoadingComponent, i3.PermissionDialogComponent], styles: ["\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-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-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 display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n\n.entity-permissions-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n position: relative;\n max-width: 1920px;\n margin: 0 auto;\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-container-lowest);\n padding: 1rem;\n border-bottom: 1px solid var(--md-outline-variant);\n box-shadow: var(--md-elevation-1);\n z-index: 10;\n}\n\n@media (min-width: 640px) {\n .sticky-header[_ngcontent-%COMP%] {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .sticky-header[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .sticky-header[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n }\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-low);\n}\n\n@media (min-width: 640px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n }\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 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-width: 44px;\n min-height: 44px;\n text-decoration: none;\n}\n\n.mj-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\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.mj-btn.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.mj-btn.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.mj-btn.mj-btn-primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #4BA5D4;\n transform: scale(0.98);\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 padding: 0.75rem 1rem;\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-icon-only[_ngcontent-%COMP%] {\n padding: 0.625rem;\n min-width: 44px;\n min-height: 44px;\n}\n\n\n\n.mj-btn-sm[_ngcontent-%COMP%] {\n padding: 0.5rem 0.875rem;\n min-height: 36px;\n min-width: 36px;\n font-size: 0.8125rem;\n}\n\n\n\n.mj-btn-icon-mobile[_ngcontent-%COMP%] {\n padding: 0.75rem 1.5rem;\n}\n\n@media (min-width: 640px) {\n .mj-btn-icon-mobile[_ngcontent-%COMP%] {\n padding: 0.75rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .mj-btn-icon-mobile[_ngcontent-%COMP%] .btn-text[_ngcontent-%COMP%] {\n display: none;\n }\n\n .mj-btn-icon-mobile[_ngcontent-%COMP%] {\n padding: 0.625rem;\n gap: 0;\n }\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n justify-content: space-between;\n margin-bottom: 1rem;\n flex-wrap: wrap;\n align-items: center;\n}\n\n@media (min-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n margin-bottom: 1.25rem;\n }\n}\n\n\n\n\n\n@media (max-width: 639px) {\n .sticky-header[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n }\n\n .action-buttons[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n margin-bottom: 0;\n order: 1;\n width: 100%;\n }\n\n .mj-view-toggle[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-medium);\n padding: 3px;\n gap: 2px;\n }\n\n .mj-view-toggle[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 0.625rem;\n min-width: 36px;\n min-height: 36px;\n border-radius: var(--md-corner-small);\n }\n\n .mj-view-toggle[_ngcontent-%COMP%] .mj-btn.mj-btn-primary[_ngcontent-%COMP%] {\n box-shadow: none;\n }\n\n .action-buttons[_ngcontent-%COMP%] > .mj-btn-secondary[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 0.5rem 0.625rem;\n min-width: 36px;\n min-height: 36px;\n border-radius: var(--md-corner-medium);\n }\n\n .filters-section[_ngcontent-%COMP%] {\n order: 2;\n width: 100%;\n background: #F3F5F9;\n border: 1px solid var(--md-outline-variant);\n padding: 0.75rem;\n margin-bottom: 0.5rem;\n border-radius: var(--md-corner-medium);\n }\n\n .filters-row[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 0.5rem;\n flex-wrap: nowrap;\n }\n\n \n\n .mobile-search-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n flex: 1;\n min-width: 0;\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 border-radius: var(--md-corner-full);\n box-sizing: border-box;\n width: 100%;\n }\n\n .mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n left: 0.875rem;\n font-size: 1rem;\n }\n\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]::placeholder {\n font-size: 0.875rem;\n }\n\n \n\n .mj-filter-group[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .mj-filter-label[_ngcontent-%COMP%] {\n display: none;\n }\n\n .mj-filter-select[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n .filter-button[_ngcontent-%COMP%] {\n display: inline-flex !important;\n flex-shrink: 0;\n }\n}\n\n\n\n\n\n.mj-view-toggle[_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-view-toggle[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\n border-radius: var(--md-corner-full);\n background: transparent;\n color: var(--md-on-surface-variant);\n border: none;\n font-size: 0.875rem;\n font-weight: 500;\n}\n\n.mj-view-toggle[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%]:hover:not(:disabled):not(.mj-btn-primary) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.mj-view-toggle[_ngcontent-%COMP%] .mj-btn.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\n\n\n\n.mj-grid-4[_ngcontent-%COMP%] {\n display: grid;\n gap: 0.75rem;\n margin-bottom: 1rem;\n width: 100%;\n grid-template-columns: repeat(2, 1fr);\n}\n\n@media (max-width: 639px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n@media (min-width: 640px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n grid-template-columns: repeat(4, 1fr);\n gap: 1.25rem;\n margin-bottom: 1.25rem;\n }\n}\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 min-width: 0;\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: 1rem 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-public[_ngcontent-%COMP%] {\n background: var(--md-tertiary-container);\n color: var(--md-tertiary);\n}\n\n\n\n.stat-icon-restricted[_ngcontent-%COMP%] {\n background: var(--md-error-container);\n color: var(--md-error);\n}\n\n\n\n.stat-icon-permissions[_ngcontent-%COMP%] {\n background: var(--md-secondary-container);\n color: #B5751A;\n}\n\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: 1.875rem;\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 text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 0.25rem;\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 background: #F3F5F9;\n border-radius: var(--md-corner-large);\n padding: 1rem;\n margin-bottom: 0;\n border: 1px solid var(--md-outline-variant);\n width: 100%;\n}\n\n@media (min-width: 768px) {\n .filters-section[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .filters-section[_ngcontent-%COMP%] {\n padding: 1.25rem 1.5rem;\n }\n}\n\n\n\n.filters-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (max-width: 639px) {\n .filters-row[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .filters-row[_ngcontent-%COMP%] {\n gap: 1.5rem;\n }\n}\n\n\n\n\n\n.mj-search[_ngcontent-%COMP%] {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n@media (max-width: 639px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 100%;\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 pointer-events: none;\n transition: color 0.2s ease;\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 min-height: 44px;\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.mj-search[_ngcontent-%COMP%]:focus-within .mj-search-icon[_ngcontent-%COMP%] {\n color: var(--md-primary);\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem 1rem 3rem;\n }\n\n .mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n left: 1.125rem;\n font-size: 1.125rem;\n }\n}\n\n\n\n\n\n.mj-filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n justify-content: flex-end;\n}\n\n.mj-filter-label[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n font-weight: 500;\n color: var(--md-on-surface);\n line-height: 1.2;\n}\n\n.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 flex-wrap: wrap;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 500;\n background: transparent;\n color: var(--md-on-surface-variant);\n border: none;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%]:hover:not(:disabled):not(.mj-btn-primary) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn.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@media (max-width: 639px) {\n .mj-filter-buttons[_ngcontent-%COMP%] {\n flex-direction: row;\n flex-wrap: wrap;\n }\n\n .mj-filter-buttons[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n flex: 1;\n min-width: calc(50% - 4px);\n padding: 0.5rem 0.75rem;\n font-size: 0.75rem;\n }\n}\n\n\n\n.mj-filter-select[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 500;\n background: var(--md-surface);\n color: var(--md-on-surface);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n height: 44px;\n min-width: 150px;\n box-sizing: border-box;\n}\n\n.mj-filter-select[_ngcontent-%COMP%]:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.mj-filter-select[_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}\n\n@media (max-width: 639px) {\n .mj-filter-select[_ngcontent-%COMP%] {\n width: 100%;\n }\n}\n\n\n\n\n\n.mobile-search-container[_ngcontent-%COMP%] {\n display: contents;\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.filter-button[_ngcontent-%COMP%] .filter-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -4px;\n right: -4px;\n background: var(--md-error);\n color: var(--md-on-error);\n font-size: 0.625rem;\n font-weight: 700;\n min-width: 18px;\n height: 18px;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\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.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 200px;\n padding: 3rem 1.5rem;\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-container-lowest);\n border-radius: var(--md-corner-large);\n box-shadow: var(--md-elevation-2);\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@media (min-width: 1024px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.75rem;\n }\n}\n\n\n\n\n\n.entities-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n overflow: visible;\n}\n\n@media (min-width: 768px) {\n .entities-list[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n\n\n.entity-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.entity-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--md-elevation-2);\n border-color: var(--md-primary);\n}\n\n.entity-card.expanded[_ngcontent-%COMP%] {\n box-shadow: var(--md-elevation-3);\n border-color: var(--md-primary);\n}\n\n.entity-card.expanded[_ngcontent-%COMP%] .expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n\n\n.entity-header[_ngcontent-%COMP%] {\n padding: 1rem;\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 gap: 0.75rem;\n}\n\n.entity-header[_ngcontent-%COMP%]:hover {\n background: var(--md-surface-container-low);\n}\n\n@media (min-width: 768px) {\n .entity-header[_ngcontent-%COMP%] {\n padding: 1.25rem 1.5rem;\n }\n}\n\n\n\n.entity-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex: 1;\n min-width: 0;\n}\n\n@media (min-width: 768px) {\n .entity-info[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n.entity-icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\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.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-icon-wrapper[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n\n\n.entity-details[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.entity-details[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.25rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .entity-details[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n}\n\n.entity-details[_ngcontent-%COMP%] .entity-description[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\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 (min-width: 768px) {\n .entity-details[_ngcontent-%COMP%] .entity-description[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n\n.entity-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-meta[_ngcontent-%COMP%] {\n gap: 0.75rem;\n }\n}\n\n\n\n\n\n.access-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 white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .access-badge[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\n font-size: 0.8125rem;\n }\n}\n\n\n\n.access-badge.access-public[_ngcontent-%COMP%] {\n background: var(--md-tertiary-container);\n color: #1B5E20;\n border: 1px solid var(--md-tertiary);\n}\n\n\n\n.access-badge.access-restricted[_ngcontent-%COMP%] {\n background: var(--md-error-container);\n color: var(--md-on-error-container);\n border: 1px solid var(--md-error);\n}\n\n\n\n.access-badge.access-custom[_ngcontent-%COMP%] {\n background: var(--md-secondary-container);\n color: #7A4D0C;\n border: 1px solid var(--md-secondary);\n}\n\n\n\n.entity-actions[_ngcontent-%COMP%] {\n display: none;\n}\n\n@media (min-width: 640px) {\n .entity-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n }\n}\n\n@media (max-width: 639px) {\n .entity-meta[_ngcontent-%COMP%] > .access-badge[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\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 cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--md-corner-full);\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%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n\n\n.entity-content[_ngcontent-%COMP%] {\n padding: 1.25rem;\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@media (min-width: 768px) {\n .entity-content[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entity-content[_ngcontent-%COMP%] {\n padding: 1.75rem;\n }\n}\n\n\n\n\n\n.mobile-actions-bar[_ngcontent-%COMP%] {\n display: none;\n}\n\n@media (max-width: 639px) {\n .mobile-actions-bar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.75rem;\n margin: -1.25rem -1.25rem 1rem -1.25rem;\n background: var(--md-surface-container-low);\n border-bottom: 1px solid var(--md-outline-variant);\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[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n }\n\n .mobile-action-buttons[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n }\n}\n\n\n\n\n\n.permissions-grid[_ngcontent-%COMP%] {\n width: 100%;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n overflow: hidden;\n border: 1px solid var(--md-outline-variant);\n border-collapse: collapse;\n}\n\n\n\n.permissions-header[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: var(--md-surface-container-high);\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n@media (min-width: 768px) {\n .permissions-header[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permissions-header[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n font-size: 0.75rem;\n }\n}\n\n\n\n.permission-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--md-outline-variant);\n transition: background-color 0.2s ease;\n}\n\n.permission-row[_ngcontent-%COMP%]:hover {\n background: var(--md-surface-container-lowest);\n}\n\n.permission-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n@media (min-width: 768px) {\n .permission-row[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permission-row[_ngcontent-%COMP%] {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n }\n}\n\n.role-header[_ngcontent-%COMP%], \n.permission-header[_ngcontent-%COMP%] {\n text-align: left;\n}\n\n.permission-header[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.role-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--md-on-surface);\n font-size: 0.875rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 639px) {\n .role-name[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n }\n}\n\n.permission-cell[_ngcontent-%COMP%] {\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n\n\n.text-success[_ngcontent-%COMP%] {\n color: var(--md-tertiary);\n}\n\n.text-muted[_ngcontent-%COMP%] {\n color: var(--md-outline);\n opacity: 0.6;\n}\n\n.no-permissions[_ngcontent-%COMP%] {\n color: var(--md-on-surface-variant);\n font-size: 0.875rem;\n margin: 0;\n padding: 1rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n text-align: center;\n}\n\n\n\n\n\n.entities-grid[_ngcontent-%COMP%] {\n display: grid;\n gap: 0.75rem;\n grid-template-columns: 1fr;\n}\n\n@media (min-width: 640px) {\n .entities-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .entities-grid[_ngcontent-%COMP%] {\n gap: 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entities-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(3, 1fr);\n gap: 1.5rem;\n }\n}\n\n\n\n.entity-grid-card[_ngcontent-%COMP%] {\n background: var(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-large);\n padding: 1.25rem;\n position: relative;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.entity-grid-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--md-elevation-2);\n border-color: var(--md-primary);\n}\n\n\n\n.entity-grid-card.access-public[_ngcontent-%COMP%] {\n border-left: 4px solid var(--md-tertiary);\n}\n\n\n\n.entity-grid-card.access-restricted[_ngcontent-%COMP%] {\n border-left: 4px solid var(--md-error);\n}\n\n\n\n.entity-grid-card.access-custom[_ngcontent-%COMP%] {\n border-left: 4px solid var(--md-secondary);\n}\n\n@media (min-width: 768px) {\n .entity-grid-card[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n\n\n.grid-card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n font-size: 1.5rem;\n color: var(--md-primary);\n}\n\n@media (min-width: 768px) {\n .grid-card-header[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n }\n}\n\n\n\n.grid-card-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.5rem 0;\n}\n\n@media (min-width: 768px) {\n .grid-card-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n}\n\n\n\n.grid-card-description[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--md-on-surface-variant);\n margin: 0 0 0.75rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n@media (min-width: 768px) {\n .grid-card-description[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n margin: 0 0 1rem 0;\n }\n}\n\n\n\n.grid-card-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.8125rem;\n}\n\n\n\n.access-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n font-weight: 500;\n}\n\n.permission-count[_ngcontent-%COMP%] {\n color: var(--md-on-surface-variant);\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n@media (min-width: 768px) {\n .empty-state[_ngcontent-%COMP%] {\n padding: 5rem 2.5rem;\n }\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-state-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--md-outline-variant);\n margin-bottom: 0.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;\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.error-container[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n}\n\n@media (min-width: 768px) {\n .error-container[_ngcontent-%COMP%] {\n padding: 5rem 2.5rem;\n }\n}\n\n.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: 0.5rem;\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@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@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 800px;\n }\n}\n\n\n\n\n\n@media (max-width: 374px) {\n .filters-section[_ngcontent-%COMP%] {\n padding: 0.5rem;\n margin-bottom: 0.375rem;\n }\n\n .filters-row[_ngcontent-%COMP%] {\n gap: 0.375rem;\n }\n\n .mobile-search-container[_ngcontent-%COMP%] {\n gap: 0.375rem;\n }\n\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 0.625rem 0.75rem 0.625rem 2.25rem;\n font-size: 0.875rem;\n }\n\n .mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n left: 0.75rem;\n font-size: 0.875rem;\n }\n\n .filter-button[_ngcontent-%COMP%] {\n padding: 0.625rem;\n min-width: 40px;\n flex-shrink: 0;\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\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}"] });
644
821
  };
645
822
  EntityPermissionsComponent = __decorate([
646
823
  RegisterClass(BaseDashboard, 'EntityPermissions')
@@ -648,7 +825,7 @@ EntityPermissionsComponent = __decorate([
648
825
  export { EntityPermissionsComponent };
649
826
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityPermissionsComponent, [{
650
827
  type: Component,
651
- args: [{ selector: 'mj-entity-permissions', template: "<div class=\"entity-permissions-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <div class=\"mj-view-toggle\">\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"viewMode === 'list'\"\n (click)=\"setViewMode('list')\"\n title=\"List View\"\n >\n <i class=\"fa-solid fa-list\"></i>\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"viewMode === 'grid'\"\n (click)=\"setViewMode('grid')\"\n title=\"Grid View\"\n >\n <i class=\"fa-solid fa-th\"></i>\n </button>\n </div>\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 </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-database\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.totalEntities }}</div>\n <div class=\"stat-label\">Total Entities</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-public\">\n <i class=\"fa-solid fa-globe\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.publicEntities }}</div>\n <div class=\"stat-label\">Public Entities</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-restricted\">\n <i class=\"fa-solid fa-lock\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.restrictedEntities }}</div>\n <div class=\"stat-label\">Restricted Entities</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-permissions\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.totalPermissions }}</div>\n <div class=\"stat-label\">Total Permissions</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\">\n <div class=\"filters-row\">\n <!-- Entity Search -->\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\"></i>\n <input \n type=\"text\" \n class=\"mj-search-input\" \n placeholder=\"Search entities by name or description...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.entitySearch\"\n />\n </div>\n \n <!-- Access Level Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\">Access Level</label>\n <div class=\"mj-filter-buttons\">\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'all'\"\n (click)=\"onAccessLevelChange('all')\"\n >\n All\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'public'\"\n (click)=\"onAccessLevelChange('public')\"\n >\n Public\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'restricted'\"\n (click)=\"onAccessLevelChange('restricted')\"\n >\n Restricted\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'custom'\"\n (click)=\"onAccessLevelChange('custom')\"\n >\n Custom\n </button>\n </div>\n </div>\n \n <!-- Role Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\">Filter by Role</label>\n <select class=\"mj-select\" (change)=\"onRoleFilterChange($event)\">\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\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 entity permissions...</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=\"mj-btn mj-btn-primary\" (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 @if (viewMode === 'list') {\n <!-- List View -->\n <div class=\"entities-list\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <div class=\"entity-card\" [class.expanded]=\"isEntityExpanded(ea.entity.ID)\">\n <div class=\"entity-header\" (click)=\"toggleEntityExpansion(ea.entity.ID)\">\n <div class=\"entity-info\">\n <div class=\"entity-icon-wrapper\">\n <i class=\"fa-solid fa-table\"></i>\n </div>\n <div class=\"entity-details\">\n <h3 class=\"entity-name\">{{ ea.entity.Name }}</h3>\n <p class=\"entity-description\">{{ ea.entity.Description || 'No description available' }}</p>\n </div>\n </div>\n \n <div class=\"entity-meta\">\n <span class=\"access-badge\" [class]=\"getAccessLevelClass(ea)\">\n <i [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' : \n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' : \n 'fa-solid fa-key'\"></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <button \n type=\"button\"\n class=\"btn-edit\" \n (click)=\"editEntityPermissions(ea); $event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\"\n title=\"Edit Permissions\"\n >\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button class=\"expand-btn\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n </div>\n </div>\n \n @if (isEntityExpanded(ea.entity.ID)) {\n <div class=\"entity-content\">\n @if (ea.permissions.length > 0) {\n <div class=\"permissions-grid\">\n <div class=\"permissions-header\">\n <span class=\"role-header\">Role</span>\n <span class=\"permission-header\">Create</span>\n <span class=\"permission-header\">Read</span>\n <span class=\"permission-header\">Update</span>\n <span class=\"permission-header\">Delete</span>\n </div>\n @for (roleId of ea.rolePermissions.keys(); track roleId) {\n <div class=\"permission-row\">\n <span class=\"role-name\">{{ getRoleName(roleId) }}</span>\n <span class=\"permission-cell\">\n <i [class]=\"hasPermission(ea, roleId, 'canCreate') ? \n 'fa-solid fa-check text-success' : \n 'fa-solid fa-times text-muted'\"></i>\n </span>\n <span class=\"permission-cell\">\n <i [class]=\"hasPermission(ea, roleId, 'canRead') ? \n 'fa-solid fa-check text-success' : \n 'fa-solid fa-times text-muted'\"></i>\n </span>\n <span class=\"permission-cell\">\n <i [class]=\"hasPermission(ea, roleId, 'canUpdate') ? \n 'fa-solid fa-check text-success' : \n 'fa-solid fa-times text-muted'\"></i>\n </span>\n <span class=\"permission-cell\">\n <i [class]=\"hasPermission(ea, roleId, 'canDelete') ? \n 'fa-solid fa-check text-success' : \n 'fa-solid fa-times text-muted'\"></i>\n </span>\n </div>\n }\n </div>\n } @else {\n <p class=\"no-permissions\">\n @if (ea.isPublic) {\n This entity is publicly accessible by all users.\n } @else {\n No specific role permissions configured. Access is restricted to system administrators.\n }\n </p>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Grid View -->\n <div class=\"entities-grid\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <div class=\"entity-grid-card\" [class]=\"getAccessLevelClass(ea)\">\n <div class=\"grid-card-header\">\n <i class=\"fa-solid fa-table\"></i>\n <button \n type=\"button\"\n class=\"btn-edit\" \n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n >\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n </div>\n <h4 class=\"grid-card-title\">{{ ea.entity.Name }}</h4>\n <p class=\"grid-card-description\">{{ ea.entity.Description || 'No description' }}</p>\n <div class=\"grid-card-footer\">\n <span class=\"access-label\">\n <i [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' : \n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' : \n 'fa-solid fa-key'\"></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n @if (ea.permissions.length > 0) {\n <span class=\"permission-count\">\n {{ ea.permissions.length }} permission{{ ea.permissions.length === 1 ? '' : 's' }}\n </span>\n }\n </div>\n </div>\n }\n </div>\n }\n \n @if (filteredEntityAccess.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-key empty-icon\"></i>\n <p class=\"empty-text\">No entities found</p>\n <p class=\"empty-subtext\">Try adjusting your filters to see more results</p>\n </div>\n }\n </div>\n }\n\n <!-- Permission Edit Dialog -->\n <mj-permission-dialog\n [visible]=\"showPermissionDialog\"\n [data]=\"permissionDialogData\"\n (result)=\"onPermissionDialogResult($event)\"\n ></mj-permission-dialog>\n</div>", styles: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.entity-permissions-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n max-width: 1400px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: space-between;\n margin-bottom: 1.5rem;\n}\n@media (max-width: 768px) {\n .action-buttons {\n flex-direction: column;\n }\n}\n\n.view-toggle {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n\n.view-btn {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.view-btn:hover {\n color: #374151;\n}\n.view-btn.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\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\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.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-public {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n.stat-icon-restricted {\n background: rgba(244, 67, 54, 0.1);\n color: #f44336;\n}\n.stat-icon-permissions {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\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\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.filter-group .filter-select {\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n background: white;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group .filter-select:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 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.entities-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.entity-card {\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.3s ease;\n}\n.entity-card:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n.entity-card.expanded {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n.entity-card.expanded .expand-btn i {\n transform: rotate(180deg);\n}\n\n.entity-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.entity-header:hover {\n background: #f3f4f6;\n}\n\n.entity-info {\n display: flex;\n align-items: center;\n gap: 1rem;\n flex: 1;\n}\n\n.entity-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.entity-details {\n flex: 1;\n}\n.entity-details .entity-name {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n}\n.entity-details .entity-description {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0;\n}\n\n.entity-meta {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.access-badge {\n padding: 0.375rem 0.75rem;\n border-radius: 20px;\n font-size: 0.75rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.375rem;\n}\n.access-badge.access-public {\n background: rgba(76, 175, 80, 0.1);\n color: #388e3c;\n}\n.access-badge.access-restricted {\n background: rgba(244, 67, 54, 0.1);\n color: #d32f2f;\n}\n.access-badge.access-custom {\n background: rgba(156, 39, 176, 0.1);\n color: #7b1fa2;\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 {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\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.entity-content {\n padding: 1.5rem;\n background: white;\n border-top: 1px solid #e5e7eb;\n animation: slideDown 0.3s ease-out;\n}\n\n.permissions-grid {\n background: #f9fafb;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.permissions-header {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 1rem;\n padding: 1rem;\n background: #e5e7eb;\n font-weight: 600;\n color: #374151;\n font-size: 0.875rem;\n}\n\n.permission-row {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 1rem;\n padding: 1rem;\n border-bottom: 1px solid #e5e7eb;\n transition: background-color 0.2s;\n}\n.permission-row:hover {\n background: white;\n}\n.permission-row:last-child {\n border-bottom: none;\n}\n\n.role-header, .permission-header {\n text-align: left;\n}\n\n.role-name {\n font-weight: 500;\n color: #1f2937;\n}\n\n.permission-cell {\n text-align: center;\n}\n\n.text-success {\n color: #4caf50;\n}\n\n.text-muted {\n color: #d1d5db;\n}\n\n.no-permissions {\n color: #6b7280;\n font-size: 0.875rem;\n margin: 0;\n}\n\n.entities-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 1.5rem;\n}\n\n.entity-grid-card {\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n padding: 1.5rem;\n transition: all 0.3s ease;\n position: relative;\n}\n.entity-grid-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n.entity-grid-card.access-public {\n border-left: 4px solid #4caf50;\n}\n.entity-grid-card.access-restricted {\n border-left: 4px solid #f44336;\n}\n.entity-grid-card.access-custom {\n border-left: 4px solid #9c27b0;\n}\n\n.grid-card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1rem;\n font-size: 1.5rem;\n color: #2196f3;\n}\n\n.edit-btn {\n padding: 0.375rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.edit-btn:hover {\n background: #f3f4f6;\n color: #2196f3;\n}\n\n.grid-card-title {\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.5rem 0;\n}\n\n.grid-card-description {\n font-size: 0.875rem;\n color: #6b7280;\n margin: 0 0 1rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.grid-card-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.875rem;\n}\n\n.access-label {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n font-weight: 500;\n}\n\n.permission-count {\n color: #6b7280;\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 #4caf50 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.modal-dialog.modal-large {\n max-width: 800px;\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 max-height: 60vh;\n overflow-y: auto;\n}\n.modal-body .modal-description {\n color: #374151;\n margin: 0 0 1.5rem 0;\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.permission-editor {\n padding: 2rem;\n background: #f3f4f6;\n border-radius: 8px;\n text-align: center;\n}\n.permission-editor .coming-soon {\n color: #6b7280;\n margin: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\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: 800px;\n }\n}\n.btn-edit {\n width: 36px;\n height: 36px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n background: white;\n color: #666666;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n}\n.btn-edit:hover {\n background: #f8f9fa;\n border-color: #2196f3;\n color: #2196f3;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n}\n.btn-edit:active {\n transform: translateY(0);\n}\n"] }]
828
+ args: [{ selector: 'mj-entity-permissions', template: "<div class=\"entity-permissions-container\">\n <!-- Sticky Header Section - Contains controls that should always be visible -->\n <div class=\"sticky-header\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\" role=\"toolbar\" aria-label=\"Entity permissions actions\">\n <div class=\"mj-view-toggle\">\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"viewMode === 'list'\"\n (click)=\"setViewMode('list')\"\n (keydown.enter)=\"setViewMode('list')\"\n (keydown.space)=\"setViewMode('list'); $event.preventDefault()\"\n [attr.aria-label]=\"'List view' + (viewMode === 'list' ? ' (active)' : '')\"\n [attr.aria-pressed]=\"viewMode === 'list'\"\n role=\"button\"\n tabindex=\"0\"\n title=\"List View\"\n >\n <i class=\"fa-solid fa-list\" aria-hidden=\"true\"></i>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"viewMode === 'grid'\"\n (click)=\"setViewMode('grid')\"\n (keydown.enter)=\"setViewMode('grid')\"\n (keydown.space)=\"setViewMode('grid'); $event.preventDefault()\"\n [attr.aria-label]=\"'Grid view' + (viewMode === 'grid' ? ' (active)' : '')\"\n [attr.aria-pressed]=\"viewMode === 'grid'\"\n role=\"button\"\n tabindex=\"0\"\n title=\"Grid View\"\n >\n <i class=\"fa-solid fa-th\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button\n class=\"mj-btn mj-btn-secondary mj-btn-icon-mobile\"\n (click)=\"refreshData()\"\n [disabled]=\"isLoading\"\n aria-label=\"Refresh entity permissions data\"\n title=\"Refresh\"\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 </div>\n\n <!-- Stats Cards -->\n <div class=\"mj-grid-4\" role=\"region\" aria-label=\"Permission statistics\">\n <div class=\"mj-card\" role=\"article\" aria-label=\"Total entities statistic\">\n <div class=\"stat-icon stat-icon-total\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-database\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Total entities count\">{{ stats.totalEntities }}</div>\n <div class=\"stat-label\">Total Entities</div>\n </div>\n </div>\n\n <div class=\"mj-card\" role=\"article\" aria-label=\"Public entities statistic\">\n <div class=\"stat-icon stat-icon-public\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-globe\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Public entities count\">{{ stats.publicEntities }}</div>\n <div class=\"stat-label\">Public Entities</div>\n </div>\n </div>\n\n <div class=\"mj-card\" role=\"article\" aria-label=\"Restricted entities statistic\">\n <div class=\"stat-icon stat-icon-restricted\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-lock\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Restricted entities count\">{{ stats.restrictedEntities }}</div>\n <div class=\"stat-label\">Restricted Entities</div>\n </div>\n </div>\n\n <div class=\"mj-card\" role=\"article\" aria-label=\"Total permissions statistic\">\n <div class=\"stat-icon stat-icon-permissions\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-key\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Total permissions count\">{{ stats.totalPermissions }}</div>\n <div class=\"stat-label\">Total Permissions</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\" role=\"search\" aria-label=\"Entity filters\">\n <div class=\"filters-row\">\n <!-- Mobile: Search + Filter Button Container -->\n <div class=\"mobile-search-container\">\n <!-- Entity Search -->\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 entities by name or description...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.entitySearch\"\n aria-label=\"Search entities\"\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 <!-- Access Level Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\" id=\"access-level-label\">Access Level</label>\n <div class=\"mj-filter-buttons\" role=\"group\" aria-labelledby=\"access-level-label\">\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'all'\"\n (click)=\"onAccessLevelChange('all')\"\n [attr.aria-pressed]=\"filters$.value.accessLevel === 'all'\"\n aria-label=\"Show all access levels\"\n >\n All\n </button>\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'public'\"\n (click)=\"onAccessLevelChange('public')\"\n [attr.aria-pressed]=\"filters$.value.accessLevel === 'public'\"\n aria-label=\"Show only public entities\"\n >\n Public\n </button>\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'restricted'\"\n (click)=\"onAccessLevelChange('restricted')\"\n [attr.aria-pressed]=\"filters$.value.accessLevel === 'restricted'\"\n aria-label=\"Show only restricted entities\"\n >\n Restricted\n </button>\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.accessLevel === 'custom'\"\n (click)=\"onAccessLevelChange('custom')\"\n [attr.aria-pressed]=\"filters$.value.accessLevel === 'custom'\"\n aria-label=\"Show only custom access entities\"\n >\n Custom\n </button>\n </div>\n </div>\n\n <!-- Role Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\" for=\"role-filter\">Filter by Role</label>\n <select\n id=\"role-filter\"\n class=\"mj-filter-select\"\n (change)=\"onRoleFilterChange($event)\"\n aria-label=\"Filter entities by role\"\n >\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\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 entity permissions...\" 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\n class=\"mj-btn mj-btn-primary\"\n (click)=\"loadInitialData()\"\n aria-label=\"Retry loading entity permissions\"\n >\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 @if (viewMode === 'list') {\n <!-- List View -->\n <div class=\"entities-list\" role=\"list\" aria-label=\"Entity permissions list\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <div\n class=\"entity-card\"\n [class.expanded]=\"isEntityExpanded(ea.entity.ID)\"\n role=\"listitem\"\n [attr.aria-expanded]=\"isEntityExpanded(ea.entity.ID)\"\n >\n <div\n class=\"entity-header\"\n (click)=\"toggleEntityExpansion(ea.entity.ID)\"\n (keydown.enter)=\"toggleEntityExpansion(ea.entity.ID)\"\n (keydown.space)=\"toggleEntityExpansion(ea.entity.ID); $event.preventDefault()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Expand permissions for ' + ea.entity.Name\"\n >\n <div class=\"entity-info\">\n <div class=\"entity-icon-wrapper\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-table\"></i>\n </div>\n <div class=\"entity-details\">\n <h3 class=\"entity-name\">{{ ea.entity.Name }}</h3>\n <p class=\"entity-description\">{{ ea.entity.Description || 'No description available' }}</p>\n </div>\n </div>\n\n <div class=\"entity-meta\">\n <span\n class=\"access-badge\"\n [class]=\"getAccessLevelClass(ea)\"\n [attr.aria-label]=\"'Access level: ' + getAccessLevelLabel(ea)\"\n >\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <div class=\"entity-actions\" (click)=\"$event.stopPropagation()\">\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button\n class=\"expand-btn\"\n [attr.aria-label]=\"(isEntityExpanded(ea.entity.ID) ? 'Collapse' : 'Expand') + ' permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n @if (isEntityExpanded(ea.entity.ID)) {\n <div class=\"entity-content\" role=\"region\" [attr.aria-label]=\"'Permissions for ' + ea.entity.Name\">\n <!-- Mobile-only actions bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"access-badge\" [class]=\"getAccessLevelClass(ea)\">\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n </div>\n </div>\n\n @if (ea.permissions.length > 0) {\n <table class=\"permissions-grid\" role=\"table\" aria-label=\"Role permissions\">\n <thead class=\"permissions-header\" role=\"rowgroup\">\n <tr role=\"row\">\n <th class=\"role-header\" scope=\"col\" role=\"columnheader\">Role</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Create</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Read</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Update</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Delete</th>\n </tr>\n </thead>\n <tbody role=\"rowgroup\">\n @for (roleId of ea.rolePermissions.keys(); track roleId) {\n <tr class=\"permission-row\" role=\"row\">\n <td class=\"role-name\" role=\"cell\">{{ getRoleName(roleId) }}</td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Create: ' + (hasPermission(ea, roleId, 'canCreate') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canCreate') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Read: ' + (hasPermission(ea, roleId, 'canRead') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canRead') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Update: ' + (hasPermission(ea, roleId, 'canUpdate') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canUpdate') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Delete: ' + (hasPermission(ea, roleId, 'canDelete') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canDelete') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <p class=\"no-permissions\">\n @if (ea.isPublic) {\n This entity is publicly accessible by all users.\n } @else {\n No specific role permissions configured. Access is restricted to system administrators.\n }\n </p>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Grid View -->\n <div class=\"entities-grid\" role=\"list\" aria-label=\"Entity permissions grid\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <article\n class=\"entity-grid-card\"\n [class]=\"getAccessLevelClass(ea)\"\n [attr.aria-label]=\"'Entity: ' + ea.entity.Name\"\n >\n <div class=\"grid-card-header\">\n <i class=\"fa-solid fa-table\" aria-hidden=\"true\"></i>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n (click)=\"editEntityPermissions(ea)\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n title=\"Edit Permissions\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <h4 class=\"grid-card-title\">{{ ea.entity.Name }}</h4>\n <p class=\"grid-card-description\">{{ ea.entity.Description || 'No description' }}</p>\n <div class=\"grid-card-footer\">\n <span\n class=\"access-label\"\n [attr.aria-label]=\"'Access level: ' + getAccessLevelLabel(ea)\"\n >\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n @if (ea.permissions.length > 0) {\n <span\n class=\"permission-count\"\n [attr.aria-label]=\"ea.permissions.length + ' permission' + (ea.permissions.length === 1 ? '' : 's')\"\n >\n {{ ea.permissions.length }} permission{{ ea.permissions.length === 1 ? '' : 's' }}\n </span>\n }\n </div>\n </article>\n }\n </div>\n }\n\n @if (filteredEntityAccess.length === 0) {\n <div class=\"empty-state\" role=\"status\">\n <i class=\"fa-solid fa-shield-alt empty-state-icon\" aria-hidden=\"true\"></i>\n <h3 class=\"empty-text\">No Permissions Found</h3>\n <p class=\"empty-subtext\">Try adjusting your filters or refresh the data.</p>\n <button\n class=\"mj-btn mj-btn-primary\"\n (click)=\"refreshData()\"\n aria-label=\"Refresh permissions data\"\n >\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Refresh\n </button>\n </div>\n }\n </div>\n }\n </div><!-- End Scrollable Content -->\n\n <!-- Permission Edit Dialog -->\n <mj-permission-dialog\n [visible]=\"showPermissionDialog\"\n [data]=\"permissionDialogData\"\n (result)=\"onPermissionDialogResult($event)\"\n ></mj-permission-dialog>\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 <!-- Access Level Filter -->\n <div class=\"filter-group\">\n <h4 class=\"filter-group-label\">Access Level</h4>\n <div class=\"filter-group-options\">\n <label\n class=\"filter-option\"\n [class.selected]=\"filters$.value.accessLevel === 'all'\"\n >\n <input\n type=\"radio\"\n name=\"accessLevel\"\n value=\"all\"\n [checked]=\"filters$.value.accessLevel === 'all'\"\n (change)=\"onAccessLevelChange('all')\"\n />\n <span class=\"filter-option-label\">All Levels</span>\n </label>\n <label\n class=\"filter-option\"\n [class.selected]=\"filters$.value.accessLevel === 'public'\"\n >\n <input\n type=\"radio\"\n name=\"accessLevel\"\n value=\"public\"\n [checked]=\"filters$.value.accessLevel === 'public'\"\n (change)=\"onAccessLevelChange('public')\"\n />\n <span class=\"filter-option-label\">Public Entities</span>\n </label>\n <label\n class=\"filter-option\"\n [class.selected]=\"filters$.value.accessLevel === 'restricted'\"\n >\n <input\n type=\"radio\"\n name=\"accessLevel\"\n value=\"restricted\"\n [checked]=\"filters$.value.accessLevel === 'restricted'\"\n (change)=\"onAccessLevelChange('restricted')\"\n />\n <span class=\"filter-option-label\">Restricted Entities</span>\n </label>\n <label\n class=\"filter-option\"\n [class.selected]=\"filters$.value.accessLevel === 'custom'\"\n >\n <input\n type=\"radio\"\n name=\"accessLevel\"\n value=\"custom\"\n [checked]=\"filters$.value.accessLevel === 'custom'\"\n (change)=\"onAccessLevelChange('custom')\"\n />\n <span class=\"filter-option-label\">Custom Access Entities</span>\n </label>\n </div>\n </div>\n\n <!-- Role Filter -->\n <div class=\"filter-group\">\n <h4 class=\"filter-group-label\">Filter by Role</h4>\n <div class=\"filter-group-options\">\n <label class=\"filter-option\" [class.selected]=\"!filters$.value.roleId\">\n <input\n type=\"radio\"\n name=\"role\"\n value=\"\"\n [checked]=\"!filters$.value.roleId\"\n (change)=\"onRoleFilterChange($event)\"\n />\n <span class=\"filter-option-label\">All Roles</span>\n </label>\n @for (role of roles; track role.ID) {\n <label\n class=\"filter-option\"\n [class.selected]=\"filters$.value.roleId === role.ID\"\n >\n <input\n type=\"radio\"\n name=\"role\"\n [value]=\"role.ID\"\n [checked]=\"filters$.value.roleId === role.ID\"\n (change)=\"onRoleFilterChange($event)\"\n />\n <span class=\"filter-option-label\">{{ role.Name }}</span>\n </label>\n }\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 Entity Permissions Component - Material Design 3\n ============================================== */\n\n/* ==============================================\n CSS Custom Properties (Design Tokens)\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-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 */\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-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 /* Host element fills container */\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n/* ==============================================\n Container Layout\n ============================================== */\n.entity-permissions-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n position: relative;\n max-width: 1920px;\n margin: 0 auto;\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-container-lowest);\n padding: 1rem;\n border-bottom: 1px solid var(--md-outline-variant);\n box-shadow: var(--md-elevation-1);\n z-index: 10;\n}\n\n@media (min-width: 640px) {\n .sticky-header {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .sticky-header {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .sticky-header {\n padding: 1.5rem 2rem;\n }\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-low);\n}\n\n@media (min-width: 640px) {\n .scrollable-content {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .scrollable-content {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content {\n padding: 1.5rem 2rem;\n }\n}\n\n/* ==============================================\n Button System - MD3 Style\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 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-width: 44px;\n min-height: 44px;\n text-decoration: none;\n}\n\n.mj-btn:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.mj-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n/* Primary Button - Dark, lightens on hover */\n.mj-btn-primary,\n.mj-btn.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.mj-btn.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.mj-btn.mj-btn-primary:active:not(:disabled) {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n/* Secondary Button - Light, darkens 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 - Transparent, fills on hover */\n.mj-btn-ghost {\n background: transparent;\n color: var(--md-on-surface-variant);\n padding: 0.75rem 1rem;\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/* Icon-only Button */\n.mj-btn-icon-only {\n padding: 0.625rem;\n min-width: 44px;\n min-height: 44px;\n}\n\n/* Small Button */\n.mj-btn-sm {\n padding: 0.5rem 0.875rem;\n min-height: 36px;\n min-width: 36px;\n font-size: 0.8125rem;\n}\n\n/* Icon-only on Mobile Button */\n.mj-btn-icon-mobile {\n padding: 0.75rem 1.5rem;\n}\n\n@media (min-width: 640px) {\n .mj-btn-icon-mobile {\n padding: 0.75rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .mj-btn-icon-mobile .btn-text {\n display: none;\n }\n\n .mj-btn-icon-mobile {\n padding: 0.625rem;\n gap: 0;\n }\n}\n\n/* ==============================================\n Action Buttons\n ============================================== */\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: space-between;\n margin-bottom: 1rem;\n flex-wrap: wrap;\n align-items: center;\n}\n\n@media (min-width: 768px) {\n .action-buttons {\n margin-bottom: 1.25rem;\n }\n}\n\n/* ==============================================\n Mobile Navigation Rail - MD3 Style\n ============================================== */\n@media (max-width: 639px) {\n .sticky-header {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n }\n\n .action-buttons {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n margin-bottom: 0;\n order: 1;\n width: 100%;\n }\n\n .mj-view-toggle {\n flex-shrink: 0;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-medium);\n padding: 3px;\n gap: 2px;\n }\n\n .mj-view-toggle .mj-btn {\n padding: 0.5rem 0.625rem;\n min-width: 36px;\n min-height: 36px;\n border-radius: var(--md-corner-small);\n }\n\n .mj-view-toggle .mj-btn.mj-btn-primary {\n box-shadow: none;\n }\n\n .action-buttons > .mj-btn-secondary {\n flex-shrink: 0;\n padding: 0.5rem 0.625rem;\n min-width: 36px;\n min-height: 36px;\n border-radius: var(--md-corner-medium);\n }\n\n .filters-section {\n order: 2;\n width: 100%;\n background: #F3F5F9;\n border: 1px solid var(--md-outline-variant);\n padding: 0.75rem;\n margin-bottom: 0.5rem;\n border-radius: var(--md-corner-medium);\n }\n\n .filters-row {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 0.5rem;\n flex-wrap: nowrap;\n }\n\n /* Mobile search container */\n .mobile-search-container {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n flex: 1;\n min-width: 0;\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 border-radius: var(--md-corner-full);\n box-sizing: border-box;\n width: 100%;\n }\n\n .mj-search .mj-search-icon {\n left: 0.875rem;\n font-size: 1rem;\n }\n\n .mj-search .mj-search-input::placeholder {\n font-size: 0.875rem;\n }\n\n /* Hide filter groups on mobile - they go in modal */\n .mj-filter-group {\n display: none !important;\n }\n\n .mj-filter-label {\n display: none;\n }\n\n .mj-filter-select {\n display: none;\n }\n\n /* Show filter button on mobile */\n .filter-button {\n display: inline-flex !important;\n flex-shrink: 0;\n }\n}\n\n/* ==============================================\n View Toggle\n ============================================== */\n.mj-view-toggle {\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-view-toggle .mj-btn {\n padding: 0.5rem 1rem;\n border-radius: var(--md-corner-full);\n background: transparent;\n color: var(--md-on-surface-variant);\n border: none;\n font-size: 0.875rem;\n font-weight: 500;\n}\n\n.mj-view-toggle .mj-btn:hover:not(:disabled):not(.mj-btn-primary) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.mj-view-toggle .mj-btn.mj-btn-primary {\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n/* ==============================================\n Stats Grid - Static Display Cards\n ============================================== */\n.mj-grid-4 {\n display: grid;\n gap: 0.75rem;\n margin-bottom: 1rem;\n width: 100%;\n grid-template-columns: repeat(2, 1fr);\n}\n\n@media (max-width: 639px) {\n .mj-grid-4 {\n display: none !important;\n }\n}\n\n@media (min-width: 640px) {\n .mj-grid-4 {\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .mj-grid-4 {\n grid-template-columns: repeat(4, 1fr);\n gap: 1.25rem;\n margin-bottom: 1.25rem;\n }\n}\n\n/* Stat Card - Static (Non-interactive) */\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 min-width: 0;\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: 1rem 1.25rem;\n }\n}\n\n/* Stat Icon Containers */\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 stat - Primary Blue */\n.stat-icon-total {\n background: var(--md-primary-container);\n color: var(--md-primary);\n}\n\n/* Public stat - Tertiary Green */\n.stat-icon-public {\n background: var(--md-tertiary-container);\n color: var(--md-tertiary);\n}\n\n/* Restricted stat - Error Red */\n.stat-icon-restricted {\n background: var(--md-error-container);\n color: var(--md-error);\n}\n\n/* Permissions stat - Secondary Orange */\n.stat-icon-permissions {\n background: var(--md-secondary-container);\n color: #B5751A;\n}\n\n/* Stat Content */\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: 1.875rem;\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 text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 0.25rem;\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 background: #F3F5F9;\n border-radius: var(--md-corner-large);\n padding: 1rem;\n margin-bottom: 0;\n border: 1px solid var(--md-outline-variant);\n width: 100%;\n}\n\n@media (min-width: 768px) {\n .filters-section {\n padding: 1rem 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .filters-section {\n padding: 1.25rem 1.5rem;\n }\n}\n\n/* Filters Row */\n.filters-row {\n display: flex;\n gap: 1rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (max-width: 639px) {\n .filters-row {\n flex-direction: column;\n align-items: stretch;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .filters-row {\n gap: 1.5rem;\n }\n}\n\n/* ==============================================\n Search Input - MD3 Style\n ============================================== */\n.mj-search {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n@media (max-width: 639px) {\n .mj-search {\n min-width: 100%;\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 pointer-events: none;\n transition: color 0.2s ease;\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 min-height: 44px;\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.mj-search:focus-within .mj-search-icon {\n color: var(--md-primary);\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-input {\n padding: 1rem 1.25rem 1rem 3rem;\n }\n\n .mj-search .mj-search-icon {\n left: 1.125rem;\n font-size: 1.125rem;\n }\n}\n\n/* ==============================================\n Filter Group - MD3 Style\n ============================================== */\n.mj-filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n justify-content: flex-end;\n}\n\n.mj-filter-label {\n font-size: 0.8125rem;\n font-weight: 500;\n color: var(--md-on-surface);\n line-height: 1.2;\n}\n\n.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 flex-wrap: wrap;\n}\n\n.mj-filter-buttons .mj-btn {\n padding: 0.5rem 1rem;\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 500;\n background: transparent;\n color: var(--md-on-surface-variant);\n border: none;\n}\n\n.mj-filter-buttons .mj-btn:hover:not(:disabled):not(.mj-btn-primary) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.mj-filter-buttons .mj-btn.mj-btn-primary {\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n@media (max-width: 639px) {\n .mj-filter-buttons {\n flex-direction: row;\n flex-wrap: wrap;\n }\n\n .mj-filter-buttons .mj-btn {\n flex: 1;\n min-width: calc(50% - 4px);\n padding: 0.5rem 0.75rem;\n font-size: 0.75rem;\n }\n}\n\n/* Filter Select Dropdown */\n.mj-filter-select {\n padding: 0.5rem 1rem;\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 500;\n background: var(--md-surface);\n color: var(--md-on-surface);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n height: 44px;\n min-width: 150px;\n box-sizing: border-box;\n}\n\n.mj-filter-select:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.mj-filter-select:focus {\n outline: none;\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n}\n\n@media (max-width: 639px) {\n .mj-filter-select {\n width: 100%;\n }\n}\n\n/* ==============================================\n Mobile Search Container (Desktop Default)\n ============================================== */\n.mobile-search-container {\n display: contents;\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.filter-button .filter-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n background: var(--md-error);\n color: var(--md-on-error);\n font-size: 0.625rem;\n font-weight: 700;\n min-width: 18px;\n height: 18px;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\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 Loading Container\n ============================================== */\n.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 200px;\n padding: 3rem 1.5rem;\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-container-lowest);\n border-radius: var(--md-corner-large);\n box-shadow: var(--md-elevation-2);\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@media (min-width: 1024px) {\n .content-area {\n padding: 1.75rem;\n }\n}\n\n/* ==============================================\n Entities List\n ============================================== */\n.entities-list {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n overflow: visible;\n}\n\n@media (min-width: 768px) {\n .entities-list {\n gap: 1rem;\n }\n}\n\n/* ==============================================\n Entity Card - Interactive\n ============================================== */\n.entity-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.entity-card:hover {\n box-shadow: var(--md-elevation-2);\n border-color: var(--md-primary);\n}\n\n.entity-card.expanded {\n box-shadow: var(--md-elevation-3);\n border-color: var(--md-primary);\n}\n\n.entity-card.expanded .expand-btn i {\n transform: rotate(180deg);\n}\n\n/* Entity Header */\n.entity-header {\n padding: 1rem;\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 gap: 0.75rem;\n}\n\n.entity-header:hover {\n background: var(--md-surface-container-low);\n}\n\n@media (min-width: 768px) {\n .entity-header {\n padding: 1.25rem 1.5rem;\n }\n}\n\n/* Entity Info */\n.entity-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex: 1;\n min-width: 0;\n}\n\n@media (min-width: 768px) {\n .entity-info {\n gap: 1rem;\n }\n}\n\n/* Entity Icon Container - Primary */\n.entity-icon-wrapper {\n width: 48px;\n height: 48px;\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.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-icon-wrapper {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n/* Entity Details */\n.entity-details {\n flex: 1;\n min-width: 0;\n}\n\n.entity-details .entity-name {\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.25rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .entity-details .entity-name {\n font-size: 1.125rem;\n }\n}\n\n.entity-details .entity-description {\n font-size: 0.8125rem;\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 (min-width: 768px) {\n .entity-details .entity-description {\n font-size: 0.875rem;\n }\n}\n\n/* Entity Meta */\n.entity-meta {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-meta {\n gap: 0.75rem;\n }\n}\n\n/* ==============================================\n Access Badges - MD3 Style\n ============================================== */\n.access-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 white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .access-badge {\n padding: 0.5rem 1rem;\n font-size: 0.8125rem;\n }\n}\n\n/* Public Access - Tertiary Green */\n.access-badge.access-public {\n background: var(--md-tertiary-container);\n color: #1B5E20;\n border: 1px solid var(--md-tertiary);\n}\n\n/* Restricted Access - Error Red */\n.access-badge.access-restricted {\n background: var(--md-error-container);\n color: var(--md-on-error-container);\n border: 1px solid var(--md-error);\n}\n\n/* Custom Access - Secondary Orange */\n.access-badge.access-custom {\n background: var(--md-secondary-container);\n color: #7A4D0C;\n border: 1px solid var(--md-secondary);\n}\n\n/* Entity Actions - Hide on mobile */\n.entity-actions {\n display: none;\n}\n\n@media (min-width: 640px) {\n .entity-actions {\n display: flex;\n gap: 0.25rem;\n }\n}\n\n@media (max-width: 639px) {\n .entity-meta > .access-badge {\n display: none;\n }\n}\n\n/* Expand Button */\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 cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--md-corner-full);\n}\n\n.expand-btn:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.expand-btn:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.expand-btn i {\n transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* ==============================================\n Entity Content - Expanded Area\n ============================================== */\n.entity-content {\n padding: 1.25rem;\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@media (min-width: 768px) {\n .entity-content {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entity-content {\n padding: 1.75rem;\n }\n}\n\n/* ==============================================\n Mobile Actions Bar\n ============================================== */\n.mobile-actions-bar {\n display: none;\n}\n\n@media (max-width: 639px) {\n .mobile-actions-bar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.75rem;\n margin: -1.25rem -1.25rem 1rem -1.25rem;\n background: var(--md-surface-container-low);\n border-bottom: 1px solid var(--md-outline-variant);\n }\n\n .mobile-action-buttons {\n display: flex;\n gap: 0.5rem;\n }\n\n .mobile-action-buttons .mj-btn {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n }\n\n .mobile-action-buttons .btn-label {\n font-size: 0.8125rem;\n }\n}\n\n/* ==============================================\n Permissions Grid (Table)\n ============================================== */\n.permissions-grid {\n width: 100%;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n overflow: hidden;\n border: 1px solid var(--md-outline-variant);\n border-collapse: collapse;\n}\n\n/* Permissions Header */\n.permissions-header tr {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: var(--md-surface-container-high);\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n@media (min-width: 768px) {\n .permissions-header tr {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permissions-header tr {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n font-size: 0.75rem;\n }\n}\n\n/* Permission Row */\n.permission-row {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--md-outline-variant);\n transition: background-color 0.2s ease;\n}\n\n.permission-row:hover {\n background: var(--md-surface-container-lowest);\n}\n\n.permission-row:last-child {\n border-bottom: none;\n}\n\n@media (min-width: 768px) {\n .permission-row {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permission-row {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n }\n}\n\n.role-header,\n.permission-header {\n text-align: left;\n}\n\n.permission-header {\n text-align: center;\n}\n\n.role-name {\n font-weight: 500;\n color: var(--md-on-surface);\n font-size: 0.875rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 639px) {\n .role-name {\n font-size: 0.75rem;\n }\n}\n\n.permission-cell {\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Success text - Tertiary Green */\n.text-success {\n color: var(--md-tertiary);\n}\n\n.text-muted {\n color: var(--md-outline);\n opacity: 0.6;\n}\n\n.no-permissions {\n color: var(--md-on-surface-variant);\n font-size: 0.875rem;\n margin: 0;\n padding: 1rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n text-align: center;\n}\n\n/* ==============================================\n Entities Grid (Grid View)\n ============================================== */\n.entities-grid {\n display: grid;\n gap: 0.75rem;\n grid-template-columns: 1fr;\n}\n\n@media (min-width: 640px) {\n .entities-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .entities-grid {\n gap: 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entities-grid {\n grid-template-columns: repeat(3, 1fr);\n gap: 1.5rem;\n }\n}\n\n/* Entity Grid Card */\n.entity-grid-card {\n background: var(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-large);\n padding: 1.25rem;\n position: relative;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.entity-grid-card:hover {\n box-shadow: var(--md-elevation-2);\n border-color: var(--md-primary);\n}\n\n/* Public - Green border */\n.entity-grid-card.access-public {\n border-left: 4px solid var(--md-tertiary);\n}\n\n/* Restricted - Red border */\n.entity-grid-card.access-restricted {\n border-left: 4px solid var(--md-error);\n}\n\n/* Custom - Orange border */\n.entity-grid-card.access-custom {\n border-left: 4px solid var(--md-secondary);\n}\n\n@media (min-width: 768px) {\n .entity-grid-card {\n padding: 1.5rem;\n }\n}\n\n/* Grid Card Header */\n.grid-card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n font-size: 1.5rem;\n color: var(--md-primary);\n}\n\n@media (min-width: 768px) {\n .grid-card-header {\n margin-bottom: 1rem;\n }\n}\n\n/* Grid Card Title */\n.grid-card-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.5rem 0;\n}\n\n@media (min-width: 768px) {\n .grid-card-title {\n font-size: 1.125rem;\n }\n}\n\n/* Grid Card Description */\n.grid-card-description {\n font-size: 0.8125rem;\n color: var(--md-on-surface-variant);\n margin: 0 0 0.75rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n@media (min-width: 768px) {\n .grid-card-description {\n font-size: 0.875rem;\n margin: 0 0 1rem 0;\n }\n}\n\n/* Grid Card Footer */\n.grid-card-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.8125rem;\n}\n\n/* Access Label */\n.access-label {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n font-weight: 500;\n}\n\n.permission-count {\n color: var(--md-on-surface-variant);\n}\n\n/* ==============================================\n Empty State\n ============================================== */\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n@media (min-width: 768px) {\n .empty-state {\n padding: 5rem 2.5rem;\n }\n}\n\n.empty-state .empty-state-icon {\n font-size: 4rem;\n color: var(--md-outline-variant);\n margin-bottom: 0.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;\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 Error Container\n ============================================== */\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n}\n\n@media (min-width: 768px) {\n .error-container {\n padding: 5rem 2.5rem;\n }\n}\n\n.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: 0.5rem;\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 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@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 800px;\n }\n}\n\n/* ==============================================\n Very Small Mobile (< 375px)\n ============================================== */\n@media (max-width: 374px) {\n .filters-section {\n padding: 0.5rem;\n margin-bottom: 0.375rem;\n }\n\n .filters-row {\n gap: 0.375rem;\n }\n\n .mobile-search-container {\n gap: 0.375rem;\n }\n\n .mj-search .mj-search-input {\n padding: 0.625rem 0.75rem 0.625rem 2.25rem;\n font-size: 0.875rem;\n }\n\n .mj-search .mj-search-icon {\n left: 0.75rem;\n font-size: 0.875rem;\n }\n\n .filter-button {\n padding: 0.625rem;\n min-width: 40px;\n flex-shrink: 0;\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\n/* ==============================================\n Reduced Motion Support\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"] }]
652
829
  }], () => [], null); })();
653
830
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityPermissionsComponent, { className: "EntityPermissionsComponent", filePath: "src/lib/entity-permissions/entity-permissions.component.ts", lineNumber: 48 }); })();
654
831
  //# sourceMappingURL=entity-permissions.component.js.map