@memberjunction/ng-explorer-settings 5.35.0 → 5.36.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 (23) hide show
  1. package/dist/lib/application-management/application-management.component.d.ts +0 -1
  2. package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
  3. package/dist/lib/application-management/application-management.component.js +151 -206
  4. package/dist/lib/application-management/application-management.component.js.map +1 -1
  5. package/dist/lib/entity-permissions/entity-permissions.component.d.ts +8 -3
  6. package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
  7. package/dist/lib/entity-permissions/entity-permissions.component.js +247 -411
  8. package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
  9. package/dist/lib/module.d.ts +1 -1
  10. package/dist/lib/module.d.ts.map +1 -1
  11. package/dist/lib/module.js +31 -4
  12. package/dist/lib/module.js.map +1 -1
  13. package/dist/lib/role-management/role-management.component.d.ts +0 -2
  14. package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
  15. package/dist/lib/role-management/role-management.component.js +136 -259
  16. package/dist/lib/role-management/role-management.component.js.map +1 -1
  17. package/dist/lib/sql-logging/sql-logging.component.js +221 -224
  18. package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
  19. package/dist/lib/user-management/user-management.component.d.ts +12 -3
  20. package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
  21. package/dist/lib/user-management/user-management.component.js +356 -463
  22. package/dist/lib/user-management/user-management.component.js.map +1 -1
  23. package/package.json +19 -19
@@ -18,11 +18,11 @@ import * as i4 from "@memberjunction/ng-shared-generic";
18
18
  import * as i5 from "@memberjunction/ng-ui-components";
19
19
  const _forTrack0 = ($index, $item) => $item.id;
20
20
  const _forTrack1 = ($index, $item) => $item.value;
21
- function SqlLoggingComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
21
+ function SqlLoggingComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
22
22
  const _r1 = i0.ɵɵgetCurrentView();
23
- i0.ɵɵelementStart(0, "button", 10);
24
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openStartSessionDialog()); });
25
- i0.ɵɵelement(1, "i", 11);
23
+ i0.ɵɵelementStart(0, "button", 9);
24
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openStartSessionDialog()); });
25
+ i0.ɵɵelement(1, "i", 10);
26
26
  i0.ɵɵtext(2, " Start New Session ");
27
27
  i0.ɵɵelementEnd();
28
28
  } if (rf & 2) {
@@ -30,55 +30,55 @@ function SqlLoggingComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
30
30
  i0.ɵɵproperty("disabled", ctx_r1.loading || ctx_r1.activeSessions.length >= ((ctx_r1.sqlLoggingConfig == null ? null : ctx_r1.sqlLoggingConfig.maxActiveSessions) || 5));
31
31
  i0.ɵɵattribute("aria-label", "Start new SQL logging session" + (ctx_r1.activeSessions.length >= ((ctx_r1.sqlLoggingConfig == null ? null : ctx_r1.sqlLoggingConfig.maxActiveSessions) || 5) ? " (maximum sessions reached)" : ""));
32
32
  } }
33
- function SqlLoggingComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
33
+ function SqlLoggingComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
34
34
  const _r3 = i0.ɵɵgetCurrentView();
35
- i0.ɵɵelementStart(0, "div", 5)(1, "button", 12);
36
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_6_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStats = !ctx_r1.showStats); });
37
- i0.ɵɵelementStart(2, "div", 13)(3, "div", 14);
38
- i0.ɵɵelement(4, "i", 15);
35
+ i0.ɵɵelementStart(0, "div", 4)(1, "button", 11);
36
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_5_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStats = !ctx_r1.showStats); });
37
+ i0.ɵɵelementStart(2, "div", 12)(3, "div", 13);
38
+ i0.ɵɵelement(4, "i", 14);
39
39
  i0.ɵɵelementEnd();
40
- i0.ɵɵelementStart(5, "div", 16)(6, "h3", 17);
40
+ i0.ɵɵelementStart(5, "div", 15)(6, "h3", 16);
41
41
  i0.ɵɵtext(7, "Statistics");
42
42
  i0.ɵɵelementEnd();
43
- i0.ɵɵelementStart(8, "p", 18);
43
+ i0.ɵɵelementStart(8, "p", 17);
44
44
  i0.ɵɵtext(9, "View session statistics and metrics");
45
45
  i0.ɵɵelementEnd()()();
46
- i0.ɵɵelement(10, "i", 19);
46
+ i0.ɵɵelement(10, "i", 18);
47
47
  i0.ɵɵelementEnd();
48
- i0.ɵɵelementStart(11, "div", 20)(12, "div", 21)(13, "div", 22);
49
- i0.ɵɵelement(14, "i", 23);
48
+ i0.ɵɵelementStart(11, "div", 19)(12, "div", 20)(13, "div", 21);
49
+ i0.ɵɵelement(14, "i", 22);
50
50
  i0.ɵɵelementEnd();
51
- i0.ɵɵelementStart(15, "div", 24)(16, "div", 25);
51
+ i0.ɵɵelementStart(15, "div", 23)(16, "div", 24);
52
52
  i0.ɵɵtext(17);
53
53
  i0.ɵɵelementEnd();
54
- i0.ɵɵelementStart(18, "div", 26);
54
+ i0.ɵɵelementStart(18, "div", 25);
55
55
  i0.ɵɵtext(19, "Status");
56
56
  i0.ɵɵelementEnd()()();
57
- i0.ɵɵelementStart(20, "div", 21)(21, "div", 27);
58
- i0.ɵɵelement(22, "i", 28);
57
+ i0.ɵɵelementStart(20, "div", 20)(21, "div", 26);
58
+ i0.ɵɵelement(22, "i", 27);
59
59
  i0.ɵɵelementEnd();
60
- i0.ɵɵelementStart(23, "div", 24)(24, "div", 25);
60
+ i0.ɵɵelementStart(23, "div", 23)(24, "div", 24);
61
61
  i0.ɵɵtext(25);
62
62
  i0.ɵɵelementEnd();
63
- i0.ɵɵelementStart(26, "div", 26);
63
+ i0.ɵɵelementStart(26, "div", 25);
64
64
  i0.ɵɵtext(27, "Active Sessions");
65
65
  i0.ɵɵelementEnd()()();
66
- i0.ɵɵelementStart(28, "div", 21)(29, "div", 29);
67
- i0.ɵɵelement(30, "i", 30);
66
+ i0.ɵɵelementStart(28, "div", 20)(29, "div", 28);
67
+ i0.ɵɵelement(30, "i", 29);
68
68
  i0.ɵɵelementEnd();
69
- i0.ɵɵelementStart(31, "div", 24)(32, "div", 25);
69
+ i0.ɵɵelementStart(31, "div", 23)(32, "div", 24);
70
70
  i0.ɵɵtext(33);
71
71
  i0.ɵɵelementEnd();
72
- i0.ɵɵelementStart(34, "div", 26);
72
+ i0.ɵɵelementStart(34, "div", 25);
73
73
  i0.ɵɵtext(35, "Max Sessions");
74
74
  i0.ɵɵelementEnd()()();
75
- i0.ɵɵelementStart(36, "div", 21)(37, "div", 31);
76
- i0.ɵɵelement(38, "i", 32);
75
+ i0.ɵɵelementStart(36, "div", 20)(37, "div", 30);
76
+ i0.ɵɵelement(38, "i", 31);
77
77
  i0.ɵɵelementEnd();
78
- i0.ɵɵelementStart(39, "div", 24)(40, "div", 25);
78
+ i0.ɵɵelementStart(39, "div", 23)(40, "div", 24);
79
79
  i0.ɵɵtext(41);
80
80
  i0.ɵɵelementEnd();
81
- i0.ɵɵelementStart(42, "div", 26);
81
+ i0.ɵɵelementStart(42, "div", 25);
82
82
  i0.ɵɵtext(43, "Total Statements");
83
83
  i0.ɵɵelementEnd()()()()();
84
84
  } if (rf & 2) {
@@ -105,37 +105,37 @@ function SqlLoggingComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
105
105
  i0.ɵɵadvance();
106
106
  i0.ɵɵtextInterpolate1(" ", ctx_r1.getTotalStatementCount(), " ");
107
107
  } }
108
- function SqlLoggingComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
109
- i0.ɵɵelementStart(0, "div", 6);
110
- i0.ɵɵelement(1, "mj-loading", 33);
108
+ function SqlLoggingComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
109
+ i0.ɵɵelementStart(0, "div", 5);
110
+ i0.ɵɵelement(1, "mj-loading", 32);
111
111
  i0.ɵɵelementEnd();
112
112
  } }
113
- function SqlLoggingComponent_Conditional_8_Conditional_1_Template(rf, ctx) { if (rf & 1) {
113
+ function SqlLoggingComponent_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
114
114
  const _r4 = i0.ɵɵgetCurrentView();
115
- i0.ɵɵelementStart(0, "div", 34);
116
- i0.ɵɵelement(1, "i", 37);
117
- i0.ɵɵelementStart(2, "p", 38);
115
+ i0.ɵɵelementStart(0, "div", 33);
116
+ i0.ɵɵelement(1, "i", 36);
117
+ i0.ɵɵelementStart(2, "p", 37);
118
118
  i0.ɵɵtext(3, "Access Denied");
119
119
  i0.ɵɵelementEnd();
120
- i0.ɵɵelementStart(4, "p", 39);
120
+ i0.ɵɵelementStart(4, "p", 38);
121
121
  i0.ɵɵtext(5, "SQL logging requires Owner privileges. Please contact your system administrator for access.");
122
122
  i0.ɵɵelementEnd();
123
- i0.ɵɵelementStart(6, "button", 40);
124
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_1_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.refreshUserPermissions()); });
125
- i0.ɵɵelement(7, "i", 41);
123
+ i0.ɵɵelementStart(6, "button", 39);
124
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_7_Conditional_1_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.refreshUserPermissions()); });
125
+ i0.ɵɵelement(7, "i", 40);
126
126
  i0.ɵɵtext(8, " Refresh Permissions ");
127
127
  i0.ɵɵelementEnd()();
128
128
  } }
129
- function SqlLoggingComponent_Conditional_8_Conditional_2_Template(rf, ctx) { if (rf & 1) {
130
- i0.ɵɵelementStart(0, "div", 34);
131
- i0.ɵɵelement(1, "i", 42);
132
- i0.ɵɵelementStart(2, "p", 38);
129
+ function SqlLoggingComponent_Conditional_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
130
+ i0.ɵɵelementStart(0, "div", 33);
131
+ i0.ɵɵelement(1, "i", 41);
132
+ i0.ɵɵelementStart(2, "p", 37);
133
133
  i0.ɵɵtext(3, "SQL Logging Disabled");
134
134
  i0.ɵɵelementEnd();
135
- i0.ɵɵelementStart(4, "p", 39);
135
+ i0.ɵɵelementStart(4, "p", 38);
136
136
  i0.ɵɵtext(5, "SQL logging is not enabled in the server configuration.");
137
137
  i0.ɵɵelementEnd();
138
- i0.ɵɵelementStart(6, "div", 43)(7, "h4");
138
+ i0.ɵɵelementStart(6, "div", 42)(7, "h4");
139
139
  i0.ɵɵtext(8, "To enable SQL logging:");
140
140
  i0.ɵɵelementEnd();
141
141
  i0.ɵɵelementStart(9, "ol")(10, "li");
@@ -152,68 +152,68 @@ function SqlLoggingComponent_Conditional_8_Conditional_2_Template(rf, ctx) { if
152
152
  i0.ɵɵtext(18, "Refresh this page");
153
153
  i0.ɵɵelementEnd()()()();
154
154
  } }
155
- function SqlLoggingComponent_Conditional_8_Conditional_3_Template(rf, ctx) { if (rf & 1) {
155
+ function SqlLoggingComponent_Conditional_7_Conditional_3_Template(rf, ctx) { if (rf & 1) {
156
156
  const _r5 = i0.ɵɵgetCurrentView();
157
- i0.ɵɵelementStart(0, "div", 35);
158
- i0.ɵɵelement(1, "i", 44);
159
- i0.ɵɵelementStart(2, "p", 38);
157
+ i0.ɵɵelementStart(0, "div", 34);
158
+ i0.ɵɵelement(1, "i", 43);
159
+ i0.ɵɵelementStart(2, "p", 37);
160
160
  i0.ɵɵtext(3, "No Active Sessions");
161
161
  i0.ɵɵelementEnd();
162
- i0.ɵɵelementStart(4, "p", 39);
162
+ i0.ɵɵelementStart(4, "p", 38);
163
163
  i0.ɵɵtext(5, "Start a new SQL logging session to begin capturing SQL statements.");
164
164
  i0.ɵɵelementEnd();
165
- i0.ɵɵelementStart(6, "button", 45);
166
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_3_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openStartSessionDialog()); });
167
- i0.ɵɵelement(7, "i", 11);
165
+ i0.ɵɵelementStart(6, "button", 44);
166
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_7_Conditional_3_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openStartSessionDialog()); });
167
+ i0.ɵɵelement(7, "i", 10);
168
168
  i0.ɵɵtext(8, " Start New Session ");
169
169
  i0.ɵɵelementEnd()();
170
170
  } }
171
- function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_5_Template(rf, ctx) { if (rf & 1) {
171
+ function SqlLoggingComponent_Conditional_7_Conditional_4_Conditional_5_Template(rf, ctx) { if (rf & 1) {
172
172
  const _r6 = i0.ɵɵgetCurrentView();
173
- i0.ɵɵelementStart(0, "button", 53);
174
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openStopAllSessionsConfirm()); });
175
- i0.ɵɵelement(1, "i", 54);
173
+ i0.ɵɵelementStart(0, "button", 52);
174
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_7_Conditional_4_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openStopAllSessionsConfirm()); });
175
+ i0.ɵɵelement(1, "i", 53);
176
176
  i0.ɵɵtext(2, " Stop All ");
177
177
  i0.ɵɵelementEnd();
178
178
  } if (rf & 2) {
179
179
  const ctx_r1 = i0.ɵɵnextContext(3);
180
180
  i0.ɵɵproperty("disabled", ctx_r1.loading);
181
181
  } }
182
- function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Conditional_15_Template(rf, ctx) { if (rf & 1) {
183
- i0.ɵɵelementStart(0, "span", 64);
184
- i0.ɵɵelement(1, "i", 67);
182
+ function SqlLoggingComponent_Conditional_7_Conditional_4_For_8_Conditional_15_Template(rf, ctx) { if (rf & 1) {
183
+ i0.ɵɵelementStart(0, "span", 63);
184
+ i0.ɵɵelement(1, "i", 66);
185
185
  i0.ɵɵtext(2, " User Filtered ");
186
186
  i0.ɵɵelementEnd();
187
187
  } }
188
- function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Conditional_16_Template(rf, ctx) { if (rf & 1) {
189
- i0.ɵɵelementStart(0, "span", 65);
190
- i0.ɵɵelement(1, "i", 68);
188
+ function SqlLoggingComponent_Conditional_7_Conditional_4_For_8_Conditional_16_Template(rf, ctx) { if (rf & 1) {
189
+ i0.ɵɵelementStart(0, "span", 64);
190
+ i0.ɵɵelement(1, "i", 67);
191
191
  i0.ɵɵtext(2, " Migration ");
192
192
  i0.ɵɵelementEnd();
193
193
  } }
194
- function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template(rf, ctx) { if (rf & 1) {
194
+ function SqlLoggingComponent_Conditional_7_Conditional_4_For_8_Template(rf, ctx) { if (rf & 1) {
195
195
  const _r7 = i0.ɵɵgetCurrentView();
196
- i0.ɵɵelementStart(0, "div", 55);
197
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template_div_click_0_listener() { const session_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectSession(session_r8)); })("keydown.enter", function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template_div_keydown_enter_0_listener() { const session_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectSession(session_r8)); })("keydown.space", function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template_div_keydown_space_0_listener($event) { const session_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); ctx_r1.selectSession(session_r8); return i0.ɵɵresetView($event.preventDefault()); });
198
- i0.ɵɵelementStart(1, "div", 56)(2, "div", 57)(3, "h4", 58);
196
+ i0.ɵɵelementStart(0, "div", 54);
197
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_7_Conditional_4_For_8_Template_div_click_0_listener() { const session_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectSession(session_r8)); })("keydown.enter", function SqlLoggingComponent_Conditional_7_Conditional_4_For_8_Template_div_keydown_enter_0_listener() { const session_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectSession(session_r8)); })("keydown.space", function SqlLoggingComponent_Conditional_7_Conditional_4_For_8_Template_div_keydown_space_0_listener($event) { const session_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); ctx_r1.selectSession(session_r8); return i0.ɵɵresetView($event.preventDefault()); });
198
+ i0.ɵɵelementStart(1, "div", 55)(2, "div", 56)(3, "h4", 57);
199
199
  i0.ɵɵtext(4);
200
200
  i0.ɵɵelementEnd();
201
- i0.ɵɵelementStart(5, "div", 59)(6, "span", 60);
202
- i0.ɵɵelement(7, "i", 61);
201
+ i0.ɵɵelementStart(5, "div", 58)(6, "span", 59);
202
+ i0.ɵɵelement(7, "i", 60);
203
203
  i0.ɵɵtext(8);
204
204
  i0.ɵɵelementEnd();
205
- i0.ɵɵelementStart(9, "span", 60);
206
- i0.ɵɵelement(10, "i", 32);
205
+ i0.ɵɵelementStart(9, "span", 59);
206
+ i0.ɵɵelement(10, "i", 31);
207
207
  i0.ɵɵtext(11);
208
208
  i0.ɵɵelementEnd()()();
209
- i0.ɵɵelementStart(12, "button", 62);
210
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template_button_click_12_listener($event) { const session_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openStopSessionConfirm(session_r8, $event)); });
211
- i0.ɵɵelement(13, "i", 54);
209
+ i0.ɵɵelementStart(12, "button", 61);
210
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_7_Conditional_4_For_8_Template_button_click_12_listener($event) { const session_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openStopSessionConfirm(session_r8, $event)); });
211
+ i0.ɵɵelement(13, "i", 53);
212
212
  i0.ɵɵelementEnd()();
213
- i0.ɵɵelementStart(14, "div", 63);
214
- i0.ɵɵconditionalCreate(15, SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Conditional_15_Template, 3, 0, "span", 64);
215
- i0.ɵɵconditionalCreate(16, SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Conditional_16_Template, 3, 0, "span", 65);
216
- i0.ɵɵelementStart(17, "span", 66);
213
+ i0.ɵɵelementStart(14, "div", 62);
214
+ i0.ɵɵconditionalCreate(15, SqlLoggingComponent_Conditional_7_Conditional_4_For_8_Conditional_15_Template, 3, 0, "span", 63);
215
+ i0.ɵɵconditionalCreate(16, SqlLoggingComponent_Conditional_7_Conditional_4_For_8_Conditional_16_Template, 3, 0, "span", 64);
216
+ i0.ɵɵelementStart(17, "span", 65);
217
217
  i0.ɵɵtext(18);
218
218
  i0.ɵɵelementEnd()()();
219
219
  } if (rf & 2) {
@@ -236,26 +236,26 @@ function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template(rf, ctx)
236
236
  i0.ɵɵadvance(2);
237
237
  i0.ɵɵtextInterpolate1(" ", (session_r8.options == null ? null : session_r8.options.statementTypes) || "both", " ");
238
238
  } }
239
- function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template(rf, ctx) { if (rf & 1) {
239
+ function SqlLoggingComponent_Conditional_7_Conditional_4_Conditional_10_Template(rf, ctx) { if (rf & 1) {
240
240
  const _r9 = i0.ɵɵgetCurrentView();
241
- i0.ɵɵelementStart(0, "div", 47)(1, "h3", 48);
241
+ i0.ɵɵelementStart(0, "div", 46)(1, "h3", 47);
242
242
  i0.ɵɵtext(2);
243
243
  i0.ɵɵelementEnd();
244
- i0.ɵɵelementStart(3, "div", 69)(4, "label", 70)(5, "input", 71);
245
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template_input_ngModelChange_5_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.autoRefresh, $event) || (ctx_r1.autoRefresh = $event); return i0.ɵɵresetView($event); });
244
+ i0.ɵɵelementStart(3, "div", 68)(4, "label", 69)(5, "input", 70);
245
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_7_Conditional_4_Conditional_10_Template_input_ngModelChange_5_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.autoRefresh, $event) || (ctx_r1.autoRefresh = $event); return i0.ɵɵresetView($event); });
246
246
  i0.ɵɵelementEnd();
247
247
  i0.ɵɵtext(6, " Auto-refresh ");
248
248
  i0.ɵɵelementEnd();
249
- i0.ɵɵelementStart(7, "button", 72);
250
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.loadSessionLog(ctx_r1.selectedSession)); });
251
- i0.ɵɵelement(8, "i", 41);
249
+ i0.ɵɵelementStart(7, "button", 71);
250
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_7_Conditional_4_Conditional_10_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.loadSessionLog(ctx_r1.selectedSession)); });
251
+ i0.ɵɵelement(8, "i", 40);
252
252
  i0.ɵɵelementEnd();
253
- i0.ɵɵelementStart(9, "button", 73);
254
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleLogViewerExpand()); });
255
- i0.ɵɵelement(10, "i", 74);
253
+ i0.ɵɵelementStart(9, "button", 72);
254
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_7_Conditional_4_Conditional_10_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleLogViewerExpand()); });
255
+ i0.ɵɵelement(10, "i", 73);
256
256
  i0.ɵɵelementEnd()()();
257
- i0.ɵɵelementStart(11, "div", 75);
258
- i0.ɵɵelement(12, "mj-code-editor", 76);
257
+ i0.ɵɵelementStart(11, "div", 74);
258
+ i0.ɵɵelement(12, "mj-code-editor", 75);
259
259
  i0.ɵɵelementEnd();
260
260
  } if (rf & 2) {
261
261
  const ctx_r1 = i0.ɵɵnextContext(3);
@@ -272,27 +272,27 @@ function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template
272
272
  i0.ɵɵadvance(2);
273
273
  i0.ɵɵproperty("value", ctx_r1.logContent)("readonly", true)("disabled", true)("language", "sql")("setup", "basic")("lineWrapping", true)("highlightWhitespace", false);
274
274
  } }
275
- function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_11_Template(rf, ctx) { if (rf & 1) {
276
- i0.ɵɵelementStart(0, "div", 35);
277
- i0.ɵɵelement(1, "i", 77);
278
- i0.ɵɵelementStart(2, "p", 38);
275
+ function SqlLoggingComponent_Conditional_7_Conditional_4_Conditional_11_Template(rf, ctx) { if (rf & 1) {
276
+ i0.ɵɵelementStart(0, "div", 34);
277
+ i0.ɵɵelement(1, "i", 76);
278
+ i0.ɵɵelementStart(2, "p", 37);
279
279
  i0.ɵɵtext(3, "Select a Session");
280
280
  i0.ɵɵelementEnd();
281
- i0.ɵɵelementStart(4, "p", 39);
281
+ i0.ɵɵelementStart(4, "p", 38);
282
282
  i0.ɵɵtext(5, "Choose a session from the list to view its SQL log.");
283
283
  i0.ɵɵelementEnd()();
284
284
  } }
285
- function SqlLoggingComponent_Conditional_8_Conditional_4_Template(rf, ctx) { if (rf & 1) {
286
- i0.ɵɵelementStart(0, "div", 36)(1, "div", 46)(2, "div", 47)(3, "h3", 48);
285
+ function SqlLoggingComponent_Conditional_7_Conditional_4_Template(rf, ctx) { if (rf & 1) {
286
+ i0.ɵɵelementStart(0, "div", 35)(1, "div", 45)(2, "div", 46)(3, "h3", 47);
287
287
  i0.ɵɵtext(4, "Active Sessions");
288
288
  i0.ɵɵelementEnd();
289
- i0.ɵɵconditionalCreate(5, SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_5_Template, 3, 1, "button", 49);
289
+ i0.ɵɵconditionalCreate(5, SqlLoggingComponent_Conditional_7_Conditional_4_Conditional_5_Template, 3, 1, "button", 48);
290
290
  i0.ɵɵelementEnd();
291
- i0.ɵɵelementStart(6, "div", 50);
292
- i0.ɵɵrepeaterCreate(7, SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template, 19, 11, "div", 51, _forTrack0);
291
+ i0.ɵɵelementStart(6, "div", 49);
292
+ i0.ɵɵrepeaterCreate(7, SqlLoggingComponent_Conditional_7_Conditional_4_For_8_Template, 19, 11, "div", 50, _forTrack0);
293
293
  i0.ɵɵelementEnd()();
294
- i0.ɵɵelementStart(9, "div", 52);
295
- i0.ɵɵconditionalCreate(10, SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template, 13, 17)(11, SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_11_Template, 6, 0, "div", 35);
294
+ i0.ɵɵelementStart(9, "div", 51);
295
+ i0.ɵɵconditionalCreate(10, SqlLoggingComponent_Conditional_7_Conditional_4_Conditional_10_Template, 13, 17)(11, SqlLoggingComponent_Conditional_7_Conditional_4_Conditional_11_Template, 6, 0, "div", 34);
296
296
  i0.ɵɵelementEnd()();
297
297
  } if (rf & 2) {
298
298
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -305,17 +305,17 @@ function SqlLoggingComponent_Conditional_8_Conditional_4_Template(rf, ctx) { if
305
305
  i0.ɵɵadvance();
306
306
  i0.ɵɵconditional(ctx_r1.selectedSession ? 10 : 11);
307
307
  } }
308
- function SqlLoggingComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
309
- i0.ɵɵelementStart(0, "div", 7);
310
- i0.ɵɵconditionalCreate(1, SqlLoggingComponent_Conditional_8_Conditional_1_Template, 9, 0, "div", 34)(2, SqlLoggingComponent_Conditional_8_Conditional_2_Template, 19, 0, "div", 34)(3, SqlLoggingComponent_Conditional_8_Conditional_3_Template, 9, 0, "div", 35)(4, SqlLoggingComponent_Conditional_8_Conditional_4_Template, 12, 4, "div", 36);
308
+ function SqlLoggingComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
309
+ i0.ɵɵelementStart(0, "div", 6);
310
+ i0.ɵɵconditionalCreate(1, SqlLoggingComponent_Conditional_7_Conditional_1_Template, 9, 0, "div", 33)(2, SqlLoggingComponent_Conditional_7_Conditional_2_Template, 19, 0, "div", 33)(3, SqlLoggingComponent_Conditional_7_Conditional_3_Template, 9, 0, "div", 34)(4, SqlLoggingComponent_Conditional_7_Conditional_4_Template, 12, 4, "div", 35);
311
311
  i0.ɵɵelementEnd();
312
312
  } if (rf & 2) {
313
313
  const ctx_r1 = i0.ɵɵnextContext();
314
314
  i0.ɵɵadvance();
315
315
  i0.ɵɵconditional(!ctx_r1.isOwner ? 1 : !ctx_r1.configEnabled ? 2 : ctx_r1.activeSessions.length === 0 ? 3 : 4);
316
316
  } }
317
- function SqlLoggingComponent_Conditional_9_For_29_Template(rf, ctx) { if (rf & 1) {
318
- i0.ɵɵelementStart(0, "option", 96);
317
+ function SqlLoggingComponent_Conditional_8_For_29_Template(rf, ctx) { if (rf & 1) {
318
+ i0.ɵɵelementStart(0, "option", 95);
319
319
  i0.ɵɵtext(1);
320
320
  i0.ɵɵelementEnd();
321
321
  } if (rf & 2) {
@@ -324,8 +324,8 @@ function SqlLoggingComponent_Conditional_9_For_29_Template(rf, ctx) { if (rf & 1
324
324
  i0.ɵɵadvance();
325
325
  i0.ɵɵtextInterpolate(option_r11.text);
326
326
  } }
327
- function SqlLoggingComponent_Conditional_9_For_51_Template(rf, ctx) { if (rf & 1) {
328
- i0.ɵɵelementStart(0, "option", 96);
327
+ function SqlLoggingComponent_Conditional_8_For_51_Template(rf, ctx) { if (rf & 1) {
328
+ i0.ɵɵelementStart(0, "option", 95);
329
329
  i0.ɵɵtext(1);
330
330
  i0.ɵɵelementEnd();
331
331
  } if (rf & 2) {
@@ -334,15 +334,15 @@ function SqlLoggingComponent_Conditional_9_For_51_Template(rf, ctx) { if (rf & 1
334
334
  i0.ɵɵadvance();
335
335
  i0.ɵɵtextInterpolate(option_r12.text);
336
336
  } }
337
- function SqlLoggingComponent_Conditional_9_Conditional_64_Template(rf, ctx) { if (rf & 1) {
337
+ function SqlLoggingComponent_Conditional_8_Conditional_64_Template(rf, ctx) { if (rf & 1) {
338
338
  const _r13 = i0.ɵɵgetCurrentView();
339
- i0.ɵɵelementStart(0, "div", 87)(1, "label", 115);
339
+ i0.ɵɵelementStart(0, "div", 86)(1, "label", 114);
340
340
  i0.ɵɵtext(2, "Default Schema Name");
341
341
  i0.ɵɵelementEnd();
342
- i0.ɵɵelementStart(3, "input", 116);
343
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Conditional_64_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.defaultSchemaName, $event) || (ctx_r1.newSessionOptions.defaultSchemaName = $event); return i0.ɵɵresetView($event); });
342
+ i0.ɵɵelementStart(3, "input", 115);
343
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Conditional_64_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.defaultSchemaName, $event) || (ctx_r1.newSessionOptions.defaultSchemaName = $event); return i0.ɵɵresetView($event); });
344
344
  i0.ɵɵelementEnd();
345
- i0.ɵɵelementStart(4, "div", 117);
345
+ i0.ɵɵelementStart(4, "div", 116);
346
346
  i0.ɵɵtext(5, "Schema name to replace with ${flyway:defaultSchema} placeholder.");
347
347
  i0.ɵɵelementEnd()();
348
348
  } if (rf & 2) {
@@ -350,117 +350,117 @@ function SqlLoggingComponent_Conditional_9_Conditional_64_Template(rf, ctx) { if
350
350
  i0.ɵɵadvance(3);
351
351
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newSessionOptions.defaultSchemaName);
352
352
  } }
353
- function SqlLoggingComponent_Conditional_9_Conditional_73_Template(rf, ctx) { if (rf & 1) {
354
- i0.ɵɵelement(0, "i", 118);
353
+ function SqlLoggingComponent_Conditional_8_Conditional_73_Template(rf, ctx) { if (rf & 1) {
354
+ i0.ɵɵelement(0, "i", 117);
355
355
  i0.ɵɵtext(1, " Starting... ");
356
356
  } }
357
- function SqlLoggingComponent_Conditional_9_Conditional_74_Template(rf, ctx) { if (rf & 1) {
358
- i0.ɵɵelement(0, "i", 11);
357
+ function SqlLoggingComponent_Conditional_8_Conditional_74_Template(rf, ctx) { if (rf & 1) {
358
+ i0.ɵɵelement(0, "i", 10);
359
359
  i0.ɵɵtext(1, " Start Session ");
360
360
  } }
361
- function SqlLoggingComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
361
+ function SqlLoggingComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
362
362
  const _r10 = i0.ɵɵgetCurrentView();
363
- i0.ɵɵelementStart(0, "div", 78);
364
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStartSessionDialog = false); });
365
- i0.ɵɵelementStart(1, "div", 79);
366
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r10); return i0.ɵɵresetView($event.stopPropagation()); });
367
- i0.ɵɵelementStart(2, "div", 80)(3, "h3", 81);
368
- i0.ɵɵelement(4, "i", 11);
363
+ i0.ɵɵelementStart(0, "div", 77);
364
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStartSessionDialog = false); });
365
+ i0.ɵɵelementStart(1, "div", 78);
366
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r10); return i0.ɵɵresetView($event.stopPropagation()); });
367
+ i0.ɵɵelementStart(2, "div", 79)(3, "h3", 80);
368
+ i0.ɵɵelement(4, "i", 10);
369
369
  i0.ɵɵtext(5, " Start SQL Logging Session ");
370
370
  i0.ɵɵelementEnd();
371
- i0.ɵɵelementStart(6, "div", 82)(7, "button", 83);
372
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleStartDialogFullscreen()); });
373
- i0.ɵɵelement(8, "i", 74);
371
+ i0.ɵɵelementStart(6, "div", 81)(7, "button", 82);
372
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleStartDialogFullscreen()); });
373
+ i0.ɵɵelement(8, "i", 73);
374
374
  i0.ɵɵelementEnd();
375
- i0.ɵɵelementStart(9, "button", 84);
376
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStartSessionDialog = false); });
377
- i0.ɵɵelement(10, "i", 85);
375
+ i0.ɵɵelementStart(9, "button", 83);
376
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStartSessionDialog = false); });
377
+ i0.ɵɵelement(10, "i", 84);
378
378
  i0.ɵɵelementEnd()()();
379
- i0.ɵɵelementStart(11, "div", 86)(12, "div", 87)(13, "label", 88);
379
+ i0.ɵɵelementStart(11, "div", 85)(12, "div", 86)(13, "label", 87);
380
380
  i0.ɵɵtext(14, "Session Name");
381
381
  i0.ɵɵelementEnd();
382
- i0.ɵɵelementStart(15, "input", 89);
383
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_15_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.sessionName, $event) || (ctx_r1.newSessionOptions.sessionName = $event); return i0.ɵɵresetView($event); });
382
+ i0.ɵɵelementStart(15, "input", 88);
383
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Template_input_ngModelChange_15_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.sessionName, $event) || (ctx_r1.newSessionOptions.sessionName = $event); return i0.ɵɵresetView($event); });
384
384
  i0.ɵɵelementEnd();
385
- i0.ɵɵelementStart(16, "div", 90);
385
+ i0.ɵɵelementStart(16, "div", 89);
386
386
  i0.ɵɵtext(17, "A descriptive name to identify this logging session");
387
387
  i0.ɵɵelementEnd()();
388
- i0.ɵɵelementStart(18, "div", 87)(19, "label", 91);
388
+ i0.ɵɵelementStart(18, "div", 86)(19, "label", 90);
389
389
  i0.ɵɵtext(20, "File Name");
390
390
  i0.ɵɵelementEnd();
391
- i0.ɵɵelementStart(21, "input", 92);
392
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_21_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.fileName, $event) || (ctx_r1.newSessionOptions.fileName = $event); return i0.ɵɵresetView($event); });
391
+ i0.ɵɵelementStart(21, "input", 91);
392
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Template_input_ngModelChange_21_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.fileName, $event) || (ctx_r1.newSessionOptions.fileName = $event); return i0.ɵɵresetView($event); });
393
393
  i0.ɵɵelementEnd();
394
- i0.ɵɵelementStart(22, "div", 93);
394
+ i0.ɵɵelementStart(22, "div", 92);
395
395
  i0.ɵɵtext(23, "The SQL log will be saved to this file");
396
396
  i0.ɵɵelementEnd()();
397
- i0.ɵɵelementStart(24, "div", 87)(25, "label", 94);
397
+ i0.ɵɵelementStart(24, "div", 86)(25, "label", 93);
398
398
  i0.ɵɵtext(26, "Statement Types");
399
399
  i0.ɵɵelementEnd();
400
- i0.ɵɵelementStart(27, "select", 95);
401
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_select_ngModelChange_27_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.statementTypes, $event) || (ctx_r1.newSessionOptions.statementTypes = $event); return i0.ɵɵresetView($event); });
402
- i0.ɵɵrepeaterCreate(28, SqlLoggingComponent_Conditional_9_For_29_Template, 2, 2, "option", 96, _forTrack1);
400
+ i0.ɵɵelementStart(27, "select", 94);
401
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Template_select_ngModelChange_27_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.statementTypes, $event) || (ctx_r1.newSessionOptions.statementTypes = $event); return i0.ɵɵresetView($event); });
402
+ i0.ɵɵrepeaterCreate(28, SqlLoggingComponent_Conditional_8_For_29_Template, 2, 2, "option", 95, _forTrack1);
403
403
  i0.ɵɵelementEnd();
404
- i0.ɵɵelementStart(30, "div", 97);
404
+ i0.ɵɵelementStart(30, "div", 96);
405
405
  i0.ɵɵtext(31, "Filter which types of SQL statements to capture");
406
406
  i0.ɵɵelementEnd()();
407
- i0.ɵɵelementStart(32, "div", 98)(33, "label", 70)(34, "input", 99);
408
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_34_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.filterToCurrentUser, $event) || (ctx_r1.newSessionOptions.filterToCurrentUser = $event); return i0.ɵɵresetView($event); });
407
+ i0.ɵɵelementStart(32, "div", 97)(33, "label", 69)(34, "input", 98);
408
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Template_input_ngModelChange_34_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.filterToCurrentUser, $event) || (ctx_r1.newSessionOptions.filterToCurrentUser = $event); return i0.ɵɵresetView($event); });
409
409
  i0.ɵɵelementEnd();
410
410
  i0.ɵɵtext(35, " Filter to my SQL statements only ");
411
411
  i0.ɵɵelementEnd();
412
- i0.ɵɵelementStart(36, "label", 70)(37, "input", 99);
413
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.formatAsMigration, $event) || (ctx_r1.newSessionOptions.formatAsMigration = $event); return i0.ɵɵresetView($event); });
412
+ i0.ɵɵelementStart(36, "label", 69)(37, "input", 98);
413
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Template_input_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.formatAsMigration, $event) || (ctx_r1.newSessionOptions.formatAsMigration = $event); return i0.ɵɵresetView($event); });
414
414
  i0.ɵɵelementEnd();
415
415
  i0.ɵɵtext(38, " Format as migration file ");
416
416
  i0.ɵɵelementEnd();
417
- i0.ɵɵelementStart(39, "label", 70)(40, "input", 99);
418
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_40_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.prettyPrint, $event) || (ctx_r1.newSessionOptions.prettyPrint = $event); return i0.ɵɵresetView($event); });
417
+ i0.ɵɵelementStart(39, "label", 69)(40, "input", 98);
418
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Template_input_ngModelChange_40_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.prettyPrint, $event) || (ctx_r1.newSessionOptions.prettyPrint = $event); return i0.ɵɵresetView($event); });
419
419
  i0.ɵɵelementEnd();
420
420
  i0.ɵɵtext(41, " Pretty print SQL statements ");
421
421
  i0.ɵɵelementEnd()();
422
- i0.ɵɵelementStart(42, "div", 100)(43, "h4", 101);
423
- i0.ɵɵelement(44, "i", 102);
422
+ i0.ɵɵelementStart(42, "div", 99)(43, "h4", 100);
423
+ i0.ɵɵelement(44, "i", 101);
424
424
  i0.ɵɵtext(45, " SQL Pattern Filtering ");
425
425
  i0.ɵɵelementEnd();
426
- i0.ɵɵelementStart(46, "div", 87)(47, "label", 103);
426
+ i0.ɵɵelementStart(46, "div", 86)(47, "label", 102);
427
427
  i0.ɵɵtext(48, "Filter Mode");
428
428
  i0.ɵɵelementEnd();
429
- i0.ɵɵelementStart(49, "select", 104);
430
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_select_ngModelChange_49_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.filterType, $event) || (ctx_r1.newSessionOptions.filterType = $event); return i0.ɵɵresetView($event); });
431
- i0.ɵɵrepeaterCreate(50, SqlLoggingComponent_Conditional_9_For_51_Template, 2, 2, "option", 96, _forTrack1);
429
+ i0.ɵɵelementStart(49, "select", 103);
430
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Template_select_ngModelChange_49_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.filterType, $event) || (ctx_r1.newSessionOptions.filterType = $event); return i0.ɵɵresetView($event); });
431
+ i0.ɵɵrepeaterCreate(50, SqlLoggingComponent_Conditional_8_For_51_Template, 2, 2, "option", 95, _forTrack1);
432
432
  i0.ɵɵelementEnd();
433
- i0.ɵɵelementStart(52, "div", 105);
433
+ i0.ɵɵelementStart(52, "div", 104);
434
434
  i0.ɵɵtext(53, "Exclude: Skip SQL matching any pattern. Include: Only log SQL matching a pattern.");
435
435
  i0.ɵɵelementEnd()();
436
- i0.ɵɵelementStart(54, "div", 87)(55, "label", 106);
436
+ i0.ɵɵelementStart(54, "div", 86)(55, "label", 105);
437
437
  i0.ɵɵtext(56, "Filter Patterns (one per line or comma-separated)");
438
438
  i0.ɵɵelementEnd();
439
- i0.ɵɵelementStart(57, "textarea", 107);
440
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_textarea_ngModelChange_57_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.filterPatterns, $event) || (ctx_r1.newSessionOptions.filterPatterns = $event); return i0.ɵɵresetView($event); });
439
+ i0.ɵɵelementStart(57, "textarea", 106);
440
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Template_textarea_ngModelChange_57_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.filterPatterns, $event) || (ctx_r1.newSessionOptions.filterPatterns = $event); return i0.ɵɵresetView($event); });
441
441
  i0.ɵɵelementEnd();
442
- i0.ɵɵelementStart(58, "div", 108);
442
+ i0.ɵɵelementStart(58, "div", 107);
443
443
  i0.ɵɵtext(59, "Supports wildcards (*) and regex (/pattern/flags). Example: *spCreate* matches any SP starting with spCreate.");
444
444
  i0.ɵɵelementEnd()()();
445
- i0.ɵɵelementStart(60, "div", 100)(61, "h4", 101);
446
- i0.ɵɵelement(62, "i", 109);
445
+ i0.ɵɵelementStart(60, "div", 99)(61, "h4", 100);
446
+ i0.ɵɵelement(62, "i", 108);
447
447
  i0.ɵɵtext(63, " Advanced Options ");
448
448
  i0.ɵɵelementEnd();
449
- i0.ɵɵconditionalCreate(64, SqlLoggingComponent_Conditional_9_Conditional_64_Template, 6, 1, "div", 87);
450
- i0.ɵɵelementStart(65, "div", 110)(66, "label", 70)(67, "input", 99);
451
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_67_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.verboseOutput, $event) || (ctx_r1.newSessionOptions.verboseOutput = $event); return i0.ɵɵresetView($event); });
449
+ i0.ɵɵconditionalCreate(64, SqlLoggingComponent_Conditional_8_Conditional_64_Template, 6, 1, "div", 86);
450
+ i0.ɵɵelementStart(65, "div", 109)(66, "label", 69)(67, "input", 98);
451
+ i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Template_input_ngModelChange_67_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.verboseOutput, $event) || (ctx_r1.newSessionOptions.verboseOutput = $event); return i0.ɵɵresetView($event); });
452
452
  i0.ɵɵelementEnd();
453
453
  i0.ɵɵtext(68, " Verbose Debug Output ");
454
454
  i0.ɵɵelementEnd();
455
- i0.ɵɵelementStart(69, "div", 111);
455
+ i0.ɵɵelementStart(69, "div", 110);
456
456
  i0.ɵɵtext(70, "Log detailed filter decisions to server console (for debugging).");
457
457
  i0.ɵɵelementEnd()()()();
458
- i0.ɵɵelementStart(71, "div", 112)(72, "button", 113);
459
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_button_click_72_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.startNewSession()); });
460
- i0.ɵɵconditionalCreate(73, SqlLoggingComponent_Conditional_9_Conditional_73_Template, 2, 0)(74, SqlLoggingComponent_Conditional_9_Conditional_74_Template, 2, 0);
458
+ i0.ɵɵelementStart(71, "div", 111)(72, "button", 112);
459
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Template_button_click_72_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.startNewSession()); });
460
+ i0.ɵɵconditionalCreate(73, SqlLoggingComponent_Conditional_8_Conditional_73_Template, 2, 0)(74, SqlLoggingComponent_Conditional_8_Conditional_74_Template, 2, 0);
461
461
  i0.ɵɵelementEnd();
462
- i0.ɵɵelementStart(75, "button", 114);
463
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_button_click_75_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStartSessionDialog = false); });
462
+ i0.ɵɵelementStart(75, "button", 113);
463
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Template_button_click_75_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStartSessionDialog = false); });
464
464
  i0.ɵɵtext(76, "Cancel");
465
465
  i0.ɵɵelementEnd()()()();
466
466
  } if (rf & 2) {
@@ -500,13 +500,13 @@ function SqlLoggingComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
500
500
  i0.ɵɵadvance();
501
501
  i0.ɵɵconditional(ctx_r1.loading ? 73 : 74);
502
502
  } }
503
- function SqlLoggingComponent_Conditional_10_Conditional_6_Template(rf, ctx) { if (rf & 1) {
503
+ function SqlLoggingComponent_Conditional_9_Conditional_6_Template(rf, ctx) { if (rf & 1) {
504
504
  i0.ɵɵtext(0, " Stop All Sessions? ");
505
505
  } }
506
- function SqlLoggingComponent_Conditional_10_Conditional_7_Template(rf, ctx) { if (rf & 1) {
506
+ function SqlLoggingComponent_Conditional_9_Conditional_7_Template(rf, ctx) { if (rf & 1) {
507
507
  i0.ɵɵtext(0, " Stop Session? ");
508
508
  } }
509
- function SqlLoggingComponent_Conditional_10_Conditional_9_Template(rf, ctx) { if (rf & 1) {
509
+ function SqlLoggingComponent_Conditional_9_Conditional_9_Template(rf, ctx) { if (rf & 1) {
510
510
  i0.ɵɵtext(0, " Are you sure you want to stop ");
511
511
  i0.ɵɵelementStart(1, "strong");
512
512
  i0.ɵɵtext(2);
@@ -517,13 +517,13 @@ function SqlLoggingComponent_Conditional_10_Conditional_9_Template(rf, ctx) { if
517
517
  i0.ɵɵadvance(2);
518
518
  i0.ɵɵtextInterpolate1("all ", ctx_r1.activeSessions.length, " active");
519
519
  } }
520
- function SqlLoggingComponent_Conditional_10_Conditional_10_Template(rf, ctx) { if (rf & 1) {
520
+ function SqlLoggingComponent_Conditional_9_Conditional_10_Template(rf, ctx) { if (rf & 1) {
521
521
  i0.ɵɵtext(0, " Are you sure you want to stop the session ");
522
522
  i0.ɵɵelementStart(1, "strong");
523
523
  i0.ɵɵtext(2);
524
524
  i0.ɵɵelementEnd();
525
525
  i0.ɵɵtext(3, "? ");
526
- i0.ɵɵelementStart(4, "span", 129);
526
+ i0.ɵɵelementStart(4, "span", 128);
527
527
  i0.ɵɵtext(5);
528
528
  i0.ɵɵelementEnd();
529
529
  } if (rf & 2) {
@@ -533,45 +533,45 @@ function SqlLoggingComponent_Conditional_10_Conditional_10_Template(rf, ctx) { i
533
533
  i0.ɵɵadvance(3);
534
534
  i0.ɵɵtextInterpolate1(" This session has captured ", ctx_r1.sessionToStop.statementCount, " SQL statements. ");
535
535
  } }
536
- function SqlLoggingComponent_Conditional_10_Conditional_13_Template(rf, ctx) { if (rf & 1) {
537
- i0.ɵɵelement(0, "i", 118);
536
+ function SqlLoggingComponent_Conditional_9_Conditional_13_Template(rf, ctx) { if (rf & 1) {
537
+ i0.ɵɵelement(0, "i", 117);
538
538
  i0.ɵɵtext(1, " Stopping... ");
539
539
  } }
540
- function SqlLoggingComponent_Conditional_10_Conditional_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
540
+ function SqlLoggingComponent_Conditional_9_Conditional_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
541
541
  i0.ɵɵtext(0, " Stop All Sessions ");
542
542
  } }
543
- function SqlLoggingComponent_Conditional_10_Conditional_14_Conditional_2_Template(rf, ctx) { if (rf & 1) {
543
+ function SqlLoggingComponent_Conditional_9_Conditional_14_Conditional_2_Template(rf, ctx) { if (rf & 1) {
544
544
  i0.ɵɵtext(0, " Stop Session ");
545
545
  } }
546
- function SqlLoggingComponent_Conditional_10_Conditional_14_Template(rf, ctx) { if (rf & 1) {
547
- i0.ɵɵelement(0, "i", 54);
548
- i0.ɵɵconditionalCreate(1, SqlLoggingComponent_Conditional_10_Conditional_14_Conditional_1_Template, 1, 0)(2, SqlLoggingComponent_Conditional_10_Conditional_14_Conditional_2_Template, 1, 0);
546
+ function SqlLoggingComponent_Conditional_9_Conditional_14_Template(rf, ctx) { if (rf & 1) {
547
+ i0.ɵɵelement(0, "i", 53);
548
+ i0.ɵɵconditionalCreate(1, SqlLoggingComponent_Conditional_9_Conditional_14_Conditional_1_Template, 1, 0)(2, SqlLoggingComponent_Conditional_9_Conditional_14_Conditional_2_Template, 1, 0);
549
549
  } if (rf & 2) {
550
550
  const ctx_r1 = i0.ɵɵnextContext(2);
551
551
  i0.ɵɵadvance();
552
552
  i0.ɵɵconditional(ctx_r1.isStoppingAll ? 1 : 2);
553
553
  } }
554
- function SqlLoggingComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
554
+ function SqlLoggingComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
555
555
  const _r14 = i0.ɵɵgetCurrentView();
556
- i0.ɵɵelementStart(0, "div", 119);
557
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_10_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelStopConfirm()); });
558
- i0.ɵɵelementStart(1, "div", 120);
559
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_10_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r14); return i0.ɵɵresetView($event.stopPropagation()); });
560
- i0.ɵɵelementStart(2, "div", 121);
561
- i0.ɵɵelement(3, "i", 122);
562
- i0.ɵɵelementEnd();
563
- i0.ɵɵelementStart(4, "div", 123)(5, "h3", 124);
564
- i0.ɵɵconditionalCreate(6, SqlLoggingComponent_Conditional_10_Conditional_6_Template, 1, 0)(7, SqlLoggingComponent_Conditional_10_Conditional_7_Template, 1, 0);
565
- i0.ɵɵelementEnd();
566
- i0.ɵɵelementStart(8, "p", 125);
567
- i0.ɵɵconditionalCreate(9, SqlLoggingComponent_Conditional_10_Conditional_9_Template, 4, 1)(10, SqlLoggingComponent_Conditional_10_Conditional_10_Template, 6, 2);
556
+ i0.ɵɵelementStart(0, "div", 118);
557
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelStopConfirm()); });
558
+ i0.ɵɵelementStart(1, "div", 119);
559
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r14); return i0.ɵɵresetView($event.stopPropagation()); });
560
+ i0.ɵɵelementStart(2, "div", 120);
561
+ i0.ɵɵelement(3, "i", 121);
562
+ i0.ɵɵelementEnd();
563
+ i0.ɵɵelementStart(4, "div", 122)(5, "h3", 123);
564
+ i0.ɵɵconditionalCreate(6, SqlLoggingComponent_Conditional_9_Conditional_6_Template, 1, 0)(7, SqlLoggingComponent_Conditional_9_Conditional_7_Template, 1, 0);
565
+ i0.ɵɵelementEnd();
566
+ i0.ɵɵelementStart(8, "p", 124);
567
+ i0.ɵɵconditionalCreate(9, SqlLoggingComponent_Conditional_9_Conditional_9_Template, 4, 1)(10, SqlLoggingComponent_Conditional_9_Conditional_10_Template, 6, 2);
568
568
  i0.ɵɵelementEnd()();
569
- i0.ɵɵelementStart(11, "div", 126)(12, "button", 127);
570
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_10_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmStopSession()); });
571
- i0.ɵɵconditionalCreate(13, SqlLoggingComponent_Conditional_10_Conditional_13_Template, 2, 0)(14, SqlLoggingComponent_Conditional_10_Conditional_14_Template, 3, 1);
569
+ i0.ɵɵelementStart(11, "div", 125)(12, "button", 126);
570
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmStopSession()); });
571
+ i0.ɵɵconditionalCreate(13, SqlLoggingComponent_Conditional_9_Conditional_13_Template, 2, 0)(14, SqlLoggingComponent_Conditional_9_Conditional_14_Template, 3, 1);
572
572
  i0.ɵɵelementEnd();
573
- i0.ɵɵelementStart(15, "button", 128);
574
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_10_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelStopConfirm()); });
573
+ i0.ɵɵelementStart(15, "button", 127);
574
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelStopConfirm()); });
575
575
  i0.ɵɵtext(16, "Cancel");
576
576
  i0.ɵɵelementEnd()()()();
577
577
  } if (rf & 2) {
@@ -1245,38 +1245,35 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
1245
1245
  static ɵfac = function SqlLoggingComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SqlLoggingComponent)(i0.ɵɵdirectiveInject(i1.SharedService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
1246
1246
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SqlLoggingComponent, selectors: [["mj-sql-logging"]], hostBindings: function SqlLoggingComponent_HostBindings(rf, ctx) { if (rf & 1) {
1247
1247
  i0.ɵɵlistener("keydown.escape", function SqlLoggingComponent_keydown_escape_HostBindingHandler() { return ctx.onEscapeKey(); }, i0.ɵɵresolveDocument);
1248
- } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 11, vars: 9, consts: [[1, "sql-logging-container"], ["role", "toolbar", "aria-label", "SQL logging actions", 1, "action-buttons"], ["aria-label", "Refresh sessions", 1, "btn-secondary", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-refresh"], [1, "btn-primary", 3, "disabled"], [1, "stats-toggle-container"], ["role", "status", "aria-live", "polite", "aria-busy", "true", 1, "loading-container"], [1, "content-area"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "start-session-dialog-title", 1, "modal-backdrop"], ["role", "alertdialog", "aria-modal", "true", "aria-labelledby", "stop-dialog-title", "aria-describedby", "stop-dialog-desc", 1, "modal-backdrop"], [1, "btn-primary", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-play"], ["aria-controls", "stats-grid-content", 1, "stats-toggle-button", 3, "click"], [1, "stats-toggle-left"], [1, "stats-toggle-icon"], ["aria-hidden", "true", 1, "fa-solid", "fa-chart-line"], [1, "stats-toggle-text"], [1, "stats-toggle-title"], [1, "stats-toggle-subtitle"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down", "stats-toggle-arrow"], ["id", "stats-grid-content", "role", "region", "aria-label", "SQL logging statistics", 1, "stats-grid"], [1, "stat-card"], [1, "stat-icon", "stat-icon-status"], ["aria-hidden", "true", 1, "fa-solid", "fa-power-off"], [1, "stat-content"], [1, "stat-value"], [1, "stat-label"], [1, "stat-icon", "stat-icon-active"], ["aria-hidden", "true", 1, "fa-solid", "fa-play-circle"], [1, "stat-icon", "stat-icon-limit"], ["aria-hidden", "true", 1, "fa-solid", "fa-gauge-high"], [1, "stat-icon", "stat-icon-total"], ["aria-hidden", "true", 1, "fa-solid", "fa-database"], ["text", "Loading SQL logging configuration...", "size", "medium"], ["role", "alert", 1, "empty-state"], ["role", "status", 1, "empty-state"], [1, "sessions-layout"], ["aria-hidden", "true", 1, "fa-solid", "fa-lock", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], ["aria-label", "Refresh user permissions", 1, "btn-secondary", 2, "margin-top", "1rem", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-sync"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "empty-icon", "warning"], [1, "info-box"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-code", "empty-icon"], ["aria-label", "Start a new SQL logging session", 1, "btn-primary", 2, "margin-top", "1rem", 3, "click"], ["role", "region", "aria-label", "Active sessions list", 1, "sessions-panel"], [1, "panel-header"], [1, "panel-title"], ["aria-label", "Stop all active sessions", 1, "btn-danger", "btn-small", 3, "disabled"], ["role", "list", "aria-label", "SQL logging sessions", 1, "sessions-list"], ["role", "listitem", "tabindex", "0", 1, "session-card", 3, "selected"], ["role", "region", "aria-label", "SQL log viewer", 1, "log-viewer-panel"], ["aria-label", "Stop all active sessions", 1, "btn-danger", "btn-small", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-stop"], ["role", "listitem", "tabindex", "0", 1, "session-card", 3, "click", "keydown.enter", "keydown.space"], [1, "session-header"], [1, "session-info"], [1, "session-title"], [1, "session-meta"], [1, "meta-item"], ["aria-hidden", "true", 1, "fa-solid", "fa-clock"], ["mjButton", "", "variant", "danger", "size", "sm", 3, "click"], [1, "session-badges"], [1, "badge", "badge-user"], [1, "badge", "badge-migration"], [1, "badge", "badge-type"], ["aria-hidden", "true", 1, "fa-solid", "fa-user"], ["aria-hidden", "true", 1, "fa-solid", "fa-code-branch"], [1, "panel-actions"], [1, "checkbox-label"], ["type", "checkbox", "aria-label", "Enable auto-refresh", 3, "ngModelChange", "ngModel"], ["mjButton", "", "variant", "flat", "size", "sm", "aria-label", "Refresh log content", 3, "click"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid"], [1, "log-content"], ["aria-label", "SQL log content", 2, "height", "100%", 3, "value", "readonly", "disabled", "language", "setup", "lineWrapping", "highlightWhitespace"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-left", "empty-icon"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "start-session-dialog-title", 1, "modal-backdrop", 3, "click"], [1, "modal-dialog", "modal-large", 3, "click"], [1, "modal-header"], ["id", "start-session-dialog-title", 1, "modal-title"], [1, "modal-header-actions"], ["type", "button", 1, "modal-action-btn", 3, "click"], ["aria-label", "Close dialog", 1, "modal-close", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-times"], [1, "modal-body"], [1, "form-group"], ["for", "session-name", 1, "form-label"], ["type", "text", "id", "session-name", "placeholder", "Enter a descriptive name for this session", "aria-describedby", "session-name-hint", 1, "form-input", 3, "ngModelChange", "ngModel"], ["id", "session-name-hint", 1, "form-hint"], ["for", "file-name", 1, "form-label"], ["type", "text", "id", "file-name", "placeholder", "sql-log-2024-01-01.sql", "aria-describedby", "file-name-hint", 1, "form-input", 3, "ngModelChange", "ngModel"], ["id", "file-name-hint", 1, "form-hint"], ["for", "statement-types", 1, "form-label"], ["id", "statement-types", "aria-describedby", "statement-types-hint", 1, "form-select", 3, "ngModelChange", "ngModel"], [3, "value"], ["id", "statement-types-hint", 1, "form-hint"], ["role", "group", "aria-label", "Session options", 1, "form-checkboxes"], ["type", "checkbox", 3, "ngModelChange", "ngModel"], [1, "form-section"], [1, "form-section-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-filter"], ["for", "filter-type", 1, "form-label"], ["id", "filter-type", "aria-describedby", "filter-type-hint", 1, "form-select", 3, "ngModelChange", "ngModel"], ["id", "filter-type-hint", 1, "form-hint"], ["for", "filter-patterns", 1, "form-label"], ["id", "filter-patterns", "rows", "4", "placeholder", "Examples:\n*AIPrompt*\n/spCreate.*Run/i\nSELECT * FROM vwMetadata", "aria-describedby", "filter-patterns-hint", 1, "form-textarea", 3, "ngModelChange", "ngModel"], ["id", "filter-patterns-hint", 1, "form-hint"], ["aria-hidden", "true", 1, "fa-solid", "fa-cog"], [1, "form-checkboxes"], [1, "form-hint", 2, "margin-left", "1.75rem"], [1, "modal-footer"], ["aria-label", "Start the SQL logging session", 1, "btn-primary", 3, "click", "disabled"], ["aria-label", "Cancel and close dialog", 1, "btn-secondary", 3, "click"], ["for", "default-schema", 1, "form-label"], ["type", "text", "id", "default-schema", "placeholder", "__mj", "aria-describedby", "default-schema-hint", 1, "form-input", 3, "ngModelChange", "ngModel"], ["id", "default-schema-hint", 1, "form-hint"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["role", "alertdialog", "aria-modal", "true", "aria-labelledby", "stop-dialog-title", "aria-describedby", "stop-dialog-desc", 1, "modal-backdrop", 3, "click"], [1, "confirm-dialog", 3, "click"], [1, "confirm-dialog-icon"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle"], [1, "confirm-dialog-content"], ["id", "stop-dialog-title", 1, "confirm-dialog-title"], ["id", "stop-dialog-desc", 1, "confirm-dialog-message"], [1, "confirm-dialog-actions"], [1, "btn-danger", 3, "click", "disabled"], ["aria-label", "Cancel and keep sessions running", 1, "btn-secondary", 3, "click", "disabled"], [1, "confirm-dialog-details"]], template: function SqlLoggingComponent_Template(rf, ctx) { if (rf & 1) {
1249
- i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "button", 2);
1250
- i0.ɵɵlistener("click", function SqlLoggingComponent_Template_button_click_2_listener() { return ctx.loadActiveSessions(); });
1251
- i0.ɵɵelement(3, "i", 3);
1252
- i0.ɵɵtext(4, " Refresh ");
1248
+ } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 10, vars: 7, consts: [["Role", "region", "AriaLabel", "SQL logging actions", "Title", "SQL Logging", "Subtitle", "Capture and download SQL statements executed by the API"], ["actions", ""], [3, "Clicked", "Loading"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "disabled"], [1, "stats-toggle-container"], ["role", "status", "aria-live", "polite", "aria-busy", "true", 1, "loading-container"], [1, "content-area"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "start-session-dialog-title", 1, "modal-backdrop"], ["role", "alertdialog", "aria-modal", "true", "aria-labelledby", "stop-dialog-title", "aria-describedby", "stop-dialog-desc", 1, "modal-backdrop"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-play"], ["aria-controls", "stats-grid-content", 1, "stats-toggle-button", 3, "click"], [1, "stats-toggle-left"], [1, "stats-toggle-icon"], ["aria-hidden", "true", 1, "fa-solid", "fa-chart-line"], [1, "stats-toggle-text"], [1, "stats-toggle-title"], [1, "stats-toggle-subtitle"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down", "stats-toggle-arrow"], ["id", "stats-grid-content", "role", "region", "aria-label", "SQL logging statistics", 1, "stats-grid"], [1, "stat-card"], [1, "stat-icon", "stat-icon-status"], ["aria-hidden", "true", 1, "fa-solid", "fa-power-off"], [1, "stat-content"], [1, "stat-value"], [1, "stat-label"], [1, "stat-icon", "stat-icon-active"], ["aria-hidden", "true", 1, "fa-solid", "fa-play-circle"], [1, "stat-icon", "stat-icon-limit"], ["aria-hidden", "true", 1, "fa-solid", "fa-gauge-high"], [1, "stat-icon", "stat-icon-total"], ["aria-hidden", "true", 1, "fa-solid", "fa-database"], ["text", "Loading SQL logging configuration...", "size", "medium"], ["role", "alert", 1, "empty-state"], ["role", "status", 1, "empty-state"], [1, "sessions-layout"], ["aria-hidden", "true", 1, "fa-solid", "fa-lock", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], ["mjButton", "", "variant", "secondary", "size", "md", "aria-label", "Refresh user permissions", 2, "margin-top", "1rem", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-sync"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "empty-icon", "warning"], [1, "info-box"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-code", "empty-icon"], ["mjButton", "", "variant", "primary", "size", "md", "aria-label", "Start a new SQL logging session", 2, "margin-top", "1rem", 3, "click"], ["role", "region", "aria-label", "Active sessions list", 1, "sessions-panel"], [1, "panel-header"], [1, "panel-title"], ["mjButton", "", "variant", "danger", "size", "sm", "aria-label", "Stop all active sessions", 3, "disabled"], ["role", "list", "aria-label", "SQL logging sessions", 1, "sessions-list"], ["role", "listitem", "tabindex", "0", 1, "session-card", 3, "selected"], ["role", "region", "aria-label", "SQL log viewer", 1, "log-viewer-panel"], ["mjButton", "", "variant", "danger", "size", "sm", "aria-label", "Stop all active sessions", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-stop"], ["role", "listitem", "tabindex", "0", 1, "session-card", 3, "click", "keydown.enter", "keydown.space"], [1, "session-header"], [1, "session-info"], [1, "session-title"], [1, "session-meta"], [1, "meta-item"], ["aria-hidden", "true", 1, "fa-solid", "fa-clock"], ["mjButton", "", "variant", "danger", "size", "sm", 3, "click"], [1, "session-badges"], [1, "badge", "badge-user"], [1, "badge", "badge-migration"], [1, "badge", "badge-type"], ["aria-hidden", "true", 1, "fa-solid", "fa-user"], ["aria-hidden", "true", 1, "fa-solid", "fa-code-branch"], [1, "panel-actions"], [1, "checkbox-label"], ["type", "checkbox", "aria-label", "Enable auto-refresh", 3, "ngModelChange", "ngModel"], ["mjButton", "", "variant", "flat", "size", "sm", "aria-label", "Refresh log content", 3, "click"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid"], [1, "log-content"], ["aria-label", "SQL log content", 2, "height", "100%", 3, "value", "readonly", "disabled", "language", "setup", "lineWrapping", "highlightWhitespace"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-left", "empty-icon"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "start-session-dialog-title", 1, "modal-backdrop", 3, "click"], [1, "modal-dialog", "modal-large", 3, "click"], [1, "modal-header"], ["id", "start-session-dialog-title", 1, "modal-title"], [1, "modal-header-actions"], ["type", "button", 1, "modal-action-btn", 3, "click"], ["aria-label", "Close dialog", 1, "modal-close", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-times"], [1, "modal-body"], [1, "form-group"], ["for", "session-name", 1, "form-label"], ["type", "text", "id", "session-name", "placeholder", "Enter a descriptive name for this session", "aria-describedby", "session-name-hint", 1, "form-input", 3, "ngModelChange", "ngModel"], ["id", "session-name-hint", 1, "form-hint"], ["for", "file-name", 1, "form-label"], ["type", "text", "id", "file-name", "placeholder", "sql-log-2024-01-01.sql", "aria-describedby", "file-name-hint", 1, "form-input", 3, "ngModelChange", "ngModel"], ["id", "file-name-hint", 1, "form-hint"], ["for", "statement-types", 1, "form-label"], ["id", "statement-types", "aria-describedby", "statement-types-hint", 1, "form-select", 3, "ngModelChange", "ngModel"], [3, "value"], ["id", "statement-types-hint", 1, "form-hint"], ["role", "group", "aria-label", "Session options", 1, "form-checkboxes"], ["type", "checkbox", 3, "ngModelChange", "ngModel"], [1, "form-section"], [1, "form-section-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-filter"], ["for", "filter-type", 1, "form-label"], ["id", "filter-type", "aria-describedby", "filter-type-hint", 1, "form-select", 3, "ngModelChange", "ngModel"], ["id", "filter-type-hint", 1, "form-hint"], ["for", "filter-patterns", 1, "form-label"], ["id", "filter-patterns", "rows", "4", "placeholder", "Examples:\n*AIPrompt*\n/spCreate.*Run/i\nSELECT * FROM vwMetadata", "aria-describedby", "filter-patterns-hint", 1, "form-textarea", 3, "ngModelChange", "ngModel"], ["id", "filter-patterns-hint", 1, "form-hint"], ["aria-hidden", "true", 1, "fa-solid", "fa-cog"], [1, "form-checkboxes"], [1, "form-hint", 2, "margin-left", "1.75rem"], [1, "modal-footer"], ["mjButton", "", "variant", "primary", "size", "md", "aria-label", "Start the SQL logging session", 3, "click", "disabled"], ["mjButton", "", "variant", "secondary", "size", "md", "aria-label", "Cancel and close dialog", 3, "click"], ["for", "default-schema", 1, "form-label"], ["type", "text", "id", "default-schema", "placeholder", "__mj", "aria-describedby", "default-schema-hint", 1, "form-input", 3, "ngModelChange", "ngModel"], ["id", "default-schema-hint", 1, "form-hint"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["role", "alertdialog", "aria-modal", "true", "aria-labelledby", "stop-dialog-title", "aria-describedby", "stop-dialog-desc", 1, "modal-backdrop", 3, "click"], [1, "confirm-dialog", 3, "click"], [1, "confirm-dialog-icon"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle"], [1, "confirm-dialog-content"], ["id", "stop-dialog-title", 1, "confirm-dialog-title"], ["id", "stop-dialog-desc", 1, "confirm-dialog-message"], [1, "confirm-dialog-actions"], ["mjButton", "", "variant", "danger", "size", "md", 3, "click", "disabled"], ["mjButton", "", "variant", "secondary", "size", "md", "aria-label", "Cancel and keep sessions running", 3, "click", "disabled"], [1, "confirm-dialog-details"]], template: function SqlLoggingComponent_Template(rf, ctx) { if (rf & 1) {
1249
+ i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1)(2, "mj-refresh-button", 2);
1250
+ i0.ɵɵlistener("Clicked", function SqlLoggingComponent_Template_mj_refresh_button_Clicked_2_listener() { return ctx.loadActiveSessions(); });
1253
1251
  i0.ɵɵelementEnd();
1254
- i0.ɵɵconditionalCreate(5, SqlLoggingComponent_Conditional_5_Template, 3, 2, "button", 4);
1255
- i0.ɵɵelementEnd();
1256
- i0.ɵɵconditionalCreate(6, SqlLoggingComponent_Conditional_6_Template, 44, 13, "div", 5);
1257
- i0.ɵɵconditionalCreate(7, SqlLoggingComponent_Conditional_7_Template, 2, 0, "div", 6);
1258
- i0.ɵɵconditionalCreate(8, SqlLoggingComponent_Conditional_8_Template, 5, 1, "div", 7);
1259
- i0.ɵɵconditionalCreate(9, SqlLoggingComponent_Conditional_9_Template, 77, 19, "div", 8);
1260
- i0.ɵɵconditionalCreate(10, SqlLoggingComponent_Conditional_10_Template, 17, 6, "div", 9);
1252
+ i0.ɵɵconditionalCreate(3, SqlLoggingComponent_Conditional_3_Template, 3, 2, "button", 3);
1253
+ i0.ɵɵelementEnd()();
1254
+ i0.ɵɵelementStart(4, "mj-page-body-interior");
1255
+ i0.ɵɵconditionalCreate(5, SqlLoggingComponent_Conditional_5_Template, 44, 13, "div", 4);
1256
+ i0.ɵɵconditionalCreate(6, SqlLoggingComponent_Conditional_6_Template, 2, 0, "div", 5);
1257
+ i0.ɵɵconditionalCreate(7, SqlLoggingComponent_Conditional_7_Template, 5, 1, "div", 6);
1258
+ i0.ɵɵconditionalCreate(8, SqlLoggingComponent_Conditional_8_Template, 77, 19, "div", 7);
1259
+ i0.ɵɵconditionalCreate(9, SqlLoggingComponent_Conditional_9_Template, 17, 6, "div", 8);
1261
1260
  i0.ɵɵelementEnd();
1262
1261
  } if (rf & 2) {
1263
1262
  i0.ɵɵadvance(2);
1264
- i0.ɵɵproperty("disabled", ctx.loading);
1263
+ i0.ɵɵproperty("Loading", ctx.loading);
1265
1264
  i0.ɵɵadvance();
1266
- i0.ɵɵclassProp("fa-spin", ctx.loading);
1265
+ i0.ɵɵconditional(ctx.isOwner && ctx.configEnabled ? 3 : -1);
1267
1266
  i0.ɵɵadvance(2);
1268
1267
  i0.ɵɵconditional(ctx.isOwner && ctx.configEnabled ? 5 : -1);
1269
1268
  i0.ɵɵadvance();
1270
- i0.ɵɵconditional(ctx.isOwner && ctx.configEnabled ? 6 : -1);
1271
- i0.ɵɵadvance();
1272
- i0.ɵɵconditional(ctx.loading && !ctx.activeSessions.length ? 7 : -1);
1269
+ i0.ɵɵconditional(ctx.loading && !ctx.activeSessions.length ? 6 : -1);
1273
1270
  i0.ɵɵadvance();
1274
- i0.ɵɵconditional(!ctx.loading || ctx.activeSessions.length > 0 ? 8 : -1);
1271
+ i0.ɵɵconditional(!ctx.loading || ctx.activeSessions.length > 0 ? 7 : -1);
1275
1272
  i0.ɵɵadvance();
1276
- i0.ɵɵconditional(ctx.showStartSessionDialog ? 9 : -1);
1273
+ i0.ɵɵconditional(ctx.showStartSessionDialog ? 8 : -1);
1277
1274
  i0.ɵɵadvance();
1278
- i0.ɵɵconditional(ctx.showStopConfirmDialog ? 10 : -1);
1279
- } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent, i4.LoadingComponent, i5.MJButtonDirective], styles: ["\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n\n.sticky-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n\n\n\n\n.scrollable-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem 2.5rem;\n }\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons[_ngcontent-%COMP%] {\n justify-content: center;\n flex-wrap: wrap;\n }\n\n .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.5rem 0.75rem;\n min-height: 40px;\n gap: 0;\n border-radius: var(--mj-radius-full);\n }\n\n .mj-btn-icon-mobile[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n}\n\n\n\n\n\n.mj-grid-4[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 1rem 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1rem 1.5rem;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n.mj-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\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\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\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.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\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(--mj-text-primary);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n }\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\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 flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.75rem;\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 1.5rem 1rem 1.5rem;\n padding: 1rem 1.25rem;\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 (min-width: 768px) {\n .filters-row[_ngcontent-%COMP%] {\n gap: 1.5rem;\n }\n}\n\n.mj-filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.mj-filter-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-full);\n padding: 4px;\n gap: 2px;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n border-radius: var(--mj-radius-full);\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn-primary[_ngcontent-%COMP%] {\n background-color: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n box-shadow: var(--mj-shadow-sm);\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 (min-width: 640px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 280px;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 400px;\n max-width: 600px;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 500px;\n max-width: 800px;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n left: 1.25rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n font-size: 1rem;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem 1rem 3.25rem;\n font-size: 1.0625rem;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1.125rem 1.5rem 1.125rem 3.5rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-secondary);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--mj-bg-page);\n}\n\n.mj-search[_ngcontent-%COMP%]:focus-within .mj-search-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\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(--mj-bg-page);\n border-radius: var(--mj-radius-xl);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem;\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n\n\n\n\n.expand-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--mj-radius-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n\n\n\n\n.status-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(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success);\n}\n\n.status-badge.status-inactive[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n}\n\n.status-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n}\n\n\n\n\n\n.mobile-actions-bar[_ngcontent-%COMP%] {\n display: none;\n}\n\n.mobile-action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--mj-border-default);\n margin-bottom: 1.5rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n\n\n\n\n.error-container[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n font-size: 3.5rem;\n color: var(--mj-status-error);\n margin-bottom: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-message[_ngcontent-%COMP%] {\n font-size: 1.0625rem;\n color: var(--mj-text-primary);\n margin: 0 0 1.5rem 0;\n}\n\n\n\n\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUp 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--mj-text-primary);\n margin: 0 0 1rem 0;\n line-height: 1.5;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (max-width: 639px) {\n .modal-dialog[_ngcontent-%COMP%] {\n width: 95%;\n max-height: 85vh;\n }\n\n .modal-header[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n\n .modal-body[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .modal-footer[_ngcontent-%COMP%] {\n padding: 1rem;\n flex-direction: column;\n }\n\n .modal-footer[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}\n\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(--mj-radius-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.mj-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n\n\n.mj-btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.mj-btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-light);\n box-shadow: var(--mj-shadow-md);\n}\n\n.mj-btn-primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-color-brand-400);\n transform: scale(0.98);\n}\n\n\n\n.mj-btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-color-neutral-400);\n}\n\n.mj-btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.mj-btn-secondary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-color-brand-700);\n border-color: var(--mj-color-brand-700);\n}\n\n\n\n.mj-btn-ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.mj-btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.mj-btn-ghost[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-color-brand-700);\n}\n\n\n\n.mj-btn-danger[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.mj-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-color-error-300);\n box-shadow: var(--mj-shadow-md);\n}\n\n.mj-btn-danger[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-color-error-200);\n transform: scale(0.98);\n}\n\n\n\n.mj-btn-sm[_ngcontent-%COMP%] {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n\n\n.mj-btn-icon-only[_ngcontent-%COMP%] {\n padding: 0.625rem;\n min-width: 44px;\n min-height: 44px;\n}\n\n\n\n.mj-btn-icon-mobile[_ngcontent-%COMP%] {\n gap: 0.5rem;\n}\n\n.mj-btn-icon-mobile[_ngcontent-%COMP%] .btn-text[_ngcontent-%COMP%] {\n display: inline;\n}\n\n\n\n.mj-btn-ghost.mj-btn-danger[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-status-error);\n box-shadow: none;\n}\n\n.mj-btn-ghost.mj-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\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(--mj-border-default);\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n border-radius: var(--mj-radius-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(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.filter-button[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.filter-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n\n\n\n\n.filter-modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: flex-end;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 0;\n}\n\n.filter-modal[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl) var(--mj-radius-2xl) 0 0;\n box-shadow: var(--mj-shadow-2xl);\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(--mj-border-default);\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(--mj-text-primary);\n margin: 0;\n}\n\n.filter-modal-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-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(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-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(--mj-brand-primary);\n color: var(--mj-brand-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(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\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(--mj-text-primary);\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(--mj-bg-surface-sunken);\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\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(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-option.selected[_ngcontent-%COMP%] {\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-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(--mj-brand-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(--mj-text-primary);\n}\n\n.filter-option.selected[_ngcontent-%COMP%] .filter-option-label[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n\n\n\n\n.text-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.text-warning[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-500);\n}\n\n.text-success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\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 transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\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.mj-search-input[_ngcontent-%COMP%]:focus-visible, \nbutton[_ngcontent-%COMP%]:focus-visible, \n.mj-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}", "\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n\n\n\n\n.sql-logging-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n position: relative;\n background: var(--mj-bg-page);\n padding: 1rem;\n}\n\n@media (min-width: 640px) {\n .sql-logging-container[_ngcontent-%COMP%] {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .sql-logging-container[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .sql-logging-container[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .sql-logging-container[_ngcontent-%COMP%] {\n padding: 2rem 2.5rem;\n max-width: 1920px;\n margin: 0 auto;\n }\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n padding: 0;\n background: transparent;\n}\n\n@media (max-width: 639px) {\n .action-buttons[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n \n\n .action-buttons[_ngcontent-%COMP%] .btn-primary[_ngcontent-%COMP%], \n .action-buttons[_ngcontent-%COMP%] .btn-secondary[_ngcontent-%COMP%] {\n font-size: 0;\n padding: 0.75rem;\n min-width: 48px;\n min-height: 48px;\n gap: 0;\n }\n\n .action-buttons[_ngcontent-%COMP%] .btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n .action-buttons[_ngcontent-%COMP%] .btn-secondary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n\n .stats-toggle-button[_ngcontent-%COMP%] {\n padding: 0.875rem 1rem;\n }\n\n .stats-toggle-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n }\n\n .stats-toggle-title[_ngcontent-%COMP%] {\n font-size: 0.9375rem;\n }\n\n .stats-toggle-subtitle[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n }\n\n .stats-toggle-arrow[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n}\n\n\n\n\n\n.btn-primary[_ngcontent-%COMP%], \n.btn-secondary[_ngcontent-%COMP%], \n.btn-danger[_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(--mj-radius-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n min-width: 44px;\n}\n\n\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-light);\n box-shadow: var(--mj-shadow-md);\n}\n\n.btn-primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-color-brand-300);\n transform: scale(0.98);\n}\n\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\n\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary-active);\n border-color: var(--mj-brand-primary-active);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.btn-secondary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\n\n\n.btn-danger[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-brand-on-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-color-error-300);\n box-shadow: var(--mj-shadow-md);\n}\n\n.btn-danger[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-color-error-200);\n transform: scale(0.98);\n}\n\n.btn-danger[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.btn-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\n.btn-danger.btn-small[_ngcontent-%COMP%] {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n\n\n\n\n.stats-toggle-container[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.stats-toggle-button[_ngcontent-%COMP%] {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.stats-toggle-button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.stats-toggle-button.expanded[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-accent-subtle);\n margin-bottom: 1rem;\n}\n\n.stats-toggle-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.stats-toggle-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n.stats-toggle-button.expanded[_ngcontent-%COMP%] .stats-toggle-icon[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.stats-toggle-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.stats-toggle-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.stats-toggle-button.expanded[_ngcontent-%COMP%] .stats-toggle-title[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.stats-toggle-subtitle[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.stats-toggle-arrow[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n color: var(--mj-text-secondary);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.stats-toggle-button.expanded[_ngcontent-%COMP%] .stats-toggle-arrow[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n color: var(--mj-brand-primary);\n}\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr;\n gap: 0.75rem;\n width: 100%;\n overflow: hidden;\n max-height: 0;\n opacity: 0;\n transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.stats-grid.visible[_ngcontent-%COMP%] {\n max-height: 1000px;\n opacity: 1;\n margin-bottom: 1.5rem;\n}\n\n@media (min-width: 640px) {\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .stats-toggle-button[_ngcontent-%COMP%] {\n display: none;\n }\n\n .stats-grid[_ngcontent-%COMP%] {\n max-height: none;\n opacity: 1;\n margin-bottom: 1.5rem;\n gap: 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(4, 1fr);\n gap: 1.5rem;\n }\n}\n\n@media (min-width: 1440px) {\n .stats-grid[_ngcontent-%COMP%] {\n gap: 2rem;\n }\n}\n\n\n\n.stat-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1.25rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\n cursor: default;\n}\n\n\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n font-size: 1.5rem;\n}\n\n@media (max-width: 639px) {\n .stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 1.25rem;\n }\n}\n\n.stat-icon-status[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n\n.stat-icon-active[_ngcontent-%COMP%] {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-limit[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n\n.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n\n\n\n@media (max-width: 639px) {\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n font-weight: 700;\n }\n}\n\n\n\n\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n box-shadow: none;\n}\n\n@media (min-width: 640px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.25rem;\n }\n}\n\n\n\n\n\n.sessions-layout[_ngcontent-%COMP%] {\n display: flex;\n gap: 1.5rem;\n min-height: 400px;\n overflow: visible;\n}\n\n@media (max-width: 767px) {\n .sessions-layout[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 1rem;\n min-height: auto;\n }\n}\n\n@media (min-width: 768px) and (max-width: 1023px) {\n .sessions-layout[_ngcontent-%COMP%] {\n gap: 1.25rem;\n }\n}\n\n\n\n\n\n.sessions-panel[_ngcontent-%COMP%] {\n flex: 0 0 380px;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n background: var(--mj-bg-surface);\n max-height: 600px;\n}\n\n@media (max-width: 767px) {\n .sessions-panel[_ngcontent-%COMP%] {\n flex: none;\n max-height: 350px;\n }\n}\n\n@media (min-width: 768px) and (max-width: 1023px) {\n .sessions-panel[_ngcontent-%COMP%] {\n flex: 0 0 320px;\n }\n}\n\n@media (min-width: 1440px) {\n .sessions-panel[_ngcontent-%COMP%] {\n flex: 0 0 420px;\n }\n}\n\n.panel-header[_ngcontent-%COMP%] {\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-shrink: 0;\n gap: 0.5rem;\n}\n\n@media (max-width: 639px) {\n .panel-header[_ngcontent-%COMP%] {\n padding: 0.75rem;\n flex-wrap: wrap;\n }\n}\n\n.panel-header[_ngcontent-%COMP%] .panel-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n flex-shrink: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (max-width: 639px) {\n .panel-header[_ngcontent-%COMP%] .panel-title[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n max-width: 50%;\n }\n}\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .panel-actions[_ngcontent-%COMP%] {\n gap: 0.25rem;\n }\n\n .panel-actions[_ngcontent-%COMP%] .checkbox-label[_ngcontent-%COMP%] {\n font-size: 0;\n gap: 0;\n min-height: 36px;\n padding: 0;\n }\n\n .panel-actions[_ngcontent-%COMP%] .checkbox-label[_ngcontent-%COMP%]::after {\n content: \"Auto\";\n font-size: 0.75rem;\n margin-left: 0.25rem;\n }\n}\n\n.sessions-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n min-height: 0;\n position: relative;\n padding: 0.75rem;\n}\n\n\n\n\n\n.session-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 1rem;\n margin-bottom: 0.75rem;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.session-card[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.session-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-sm);\n border-color: var(--mj-brand-primary);\n}\n\n.session-card.selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-brand-accent-subtle);\n}\n\n.session-card[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.session-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.75rem;\n}\n\n.session-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.session-info[_ngcontent-%COMP%] .session-title[_ngcontent-%COMP%] {\n margin: 0 0 0.5rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.session-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n flex-wrap: wrap;\n}\n\n.session-meta[_ngcontent-%COMP%] .meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.session-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n margin-top: 0.5rem;\n}\n\n\n\n\n\n.badge[_ngcontent-%COMP%] {\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n}\n\n.badge-user[_ngcontent-%COMP%] {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.badge-migration[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success);\n}\n\n.badge-type[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning);\n}\n\n\n\n\n\n.action-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n border-radius: var(--mj-radius-full);\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: flex;\n align-items: center;\n justify-content: center;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.action-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.action-btn-danger[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n color: var(--mj-brand-on-primary);\n}\n\n\n\n\n\n.log-viewer-panel[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n background: var(--mj-bg-surface);\n min-height: 400px;\n}\n\n@media (max-width: 767px) {\n .log-viewer-panel[_ngcontent-%COMP%] {\n min-height: 350px;\n }\n}\n\n\n\n.log-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 300px;\n height: 100%;\n position: relative;\n background: var(--mj-text-primary);\n color: var(--mj-border-strong);\n}\n\n.log-content[_ngcontent-%COMP%] .cm-editor {\n height: 100%;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n font-size: 0.875rem;\n}\n\n.log-content[_ngcontent-%COMP%] .cm-scroller {\n font-family: inherit;\n}\n\n.log-content[_ngcontent-%COMP%] .cm-content {\n background: var(--mj-text-primary);\n color: var(--mj-border-strong);\n}\n\n.log-content[_ngcontent-%COMP%] .cm-gutters {\n background: var(--mj-text-primary);\n color: var(--mj-text-disabled);\n border-right: 1px solid var(--mj-text-secondary);\n}\n\n.log-content[_ngcontent-%COMP%] .cm-activeLineGutter {\n background: var(--mj-text-primary);\n}\n\n.log-content[_ngcontent-%COMP%] .cm-activeLine {\n background: rgba(255, 255, 255, 0.04);\n}\n\n\n\n.log-viewer-panel.expanded[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n border-radius: 0;\n margin: 0;\n max-height: none;\n height: 100vh;\n animation: _ngcontent-%COMP%_expandIn 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.log-viewer-panel.expanded[_ngcontent-%COMP%] .panel-header[_ngcontent-%COMP%] {\n border-radius: 0;\n}\n\n.log-viewer-panel.expanded[_ngcontent-%COMP%] .log-content[_ngcontent-%COMP%] {\n max-height: calc(100vh - 60px);\n min-height: calc(100vh - 60px);\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] .empty-icon.warning[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n max-width: 400px;\n}\n\n\n\n\n\n.info-box[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n padding: 1.5rem;\n margin-top: 1.5rem;\n text-align: left;\n max-width: 500px;\n border: 1px solid var(--mj-border-default);\n}\n\n.info-box[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 1rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.info-box[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n margin: 0;\n padding-left: 1.25rem;\n font-size: 1rem;\n color: var(--mj-text-primary);\n}\n\n.info-box[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin-bottom: 0.5rem;\n}\n\n.info-box[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-active);\n padding: 0.125rem 0.5rem;\n border-radius: var(--mj-radius-sm);\n font-size: 0.8125rem;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n color: var(--mj-text-primary);\n}\n\n\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n min-height: 300px;\n}\n\n.loading-text[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin-top: 1rem;\n}\n\n\n\n\n\n.modal-backdrop[_ngcontent-%COMP%] {\n background: var(--mj-bg-overlay);\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n width: 90%;\n display: flex;\n flex-direction: column;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.modal-dialog.modal-large[_ngcontent-%COMP%] {\n max-width: 700px;\n}\n\n\n\n.modal-dialog.fullscreen[_ngcontent-%COMP%] {\n max-width: 100vw;\n width: 100vw;\n max-height: 100vh;\n height: 100vh;\n border-radius: 0;\n margin: 0;\n}\n\n@media (max-width: 639px) {\n .modal-dialog[_ngcontent-%COMP%] {\n width: 95%;\n max-height: 85vh;\n border-radius: var(--mj-radius-2xl);\n }\n\n .modal-dialog.fullscreen[_ngcontent-%COMP%] {\n border-radius: 0;\n max-height: 100vh;\n }\n}\n\n.modal-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-header[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n}\n\n\n\n.modal-header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n flex-shrink: 0;\n}\n\n.modal-action-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.125rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.modal-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-action-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.modal-body[_ngcontent-%COMP%] {\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n flex: 1;\n}\n\n@media (max-width: 639px) {\n .modal-body[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n justify-content: flex-end;\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-footer[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n\n .modal-footer[_ngcontent-%COMP%] .btn-primary[_ngcontent-%COMP%], \n .modal-footer[_ngcontent-%COMP%] .btn-secondary[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}\n\n\n\n\n\n.form-group[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.form-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n margin-bottom: 0.5rem;\n}\n\n.form-input[_ngcontent-%COMP%], \n.form-select[_ngcontent-%COMP%], \n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n min-height: 44px;\n padding: 0.875rem 1rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n font-size: 1rem;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.form-input[_ngcontent-%COMP%]:hover, \n.form-select[_ngcontent-%COMP%]:hover, \n.form-textarea[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.form-input[_ngcontent-%COMP%]:focus, \n.form-select[_ngcontent-%COMP%]:focus, \n.form-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.form-input[_ngcontent-%COMP%]::placeholder, \n.form-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-secondary);\n opacity: 0.7;\n}\n\n.form-select[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.form-hint[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin-top: 0.375rem;\n}\n\n.form-checkboxes[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n font-size: 1rem;\n color: var(--mj-text-primary);\n cursor: pointer;\n min-height: 44px;\n padding: 0.25rem 0;\n}\n\n.checkbox-label[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n\n\n.form-section[_ngcontent-%COMP%] {\n margin-top: 1.5rem;\n padding: 1.25rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n background: var(--mj-bg-surface-sunken);\n}\n\n.form-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n margin: 0 0 1rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.form-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 1.125rem;\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n resize: vertical;\n min-height: 100px;\n}\n\n\n\n\n\n.confirm-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 420px;\n width: 90%;\n padding: 2rem;\n text-align: center;\n animation: _ngcontent-%COMP%_dialogBounce 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n@media (max-width: 639px) {\n .confirm-dialog[_ngcontent-%COMP%] {\n padding: 1.5rem;\n border-radius: var(--mj-radius-2xl);\n }\n}\n\n.confirm-dialog-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: var(--mj-status-warning-bg);\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 1.5rem;\n}\n\n.confirm-dialog-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n color: var(--mj-status-warning-text);\n}\n\n.confirm-dialog-content[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.confirm-dialog-title[_ngcontent-%COMP%] {\n margin: 0 0 0.75rem 0;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.confirm-dialog-message[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n}\n\n.confirm-dialog-message[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n.confirm-dialog-details[_ngcontent-%COMP%] {\n display: block;\n margin-top: 0.75rem;\n padding: 0.75rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-md);\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n\n.confirm-dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n justify-content: center;\n}\n\n@media (max-width: 639px) {\n .confirm-dialog-actions[_ngcontent-%COMP%] {\n flex-direction: column-reverse;\n }\n\n .confirm-dialog-actions[_ngcontent-%COMP%] .btn-danger[_ngcontent-%COMP%], \n .confirm-dialog-actions[_ngcontent-%COMP%] .btn-secondary[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}\n\n.confirm-dialog-actions[_ngcontent-%COMP%] .btn-danger[_ngcontent-%COMP%] {\n min-width: 140px;\n}\n\n.confirm-dialog-actions[_ngcontent-%COMP%] .btn-secondary[_ngcontent-%COMP%] {\n min-width: 100px;\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_expandIn {\n from {\n transform: scale(0.95);\n opacity: 0;\n }\n to {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_dialogBounce {\n 0% {\n transform: scale(0.9) translateY(10px);\n opacity: 0;\n }\n 70% {\n transform: scale(1.02) translateY(-5px);\n }\n 100% {\n transform: scale(1) translateY(0);\n opacity: 1;\n }\n}\n\n\n\n\n\n.sr-only[_ngcontent-%COMP%] {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}"] });
1275
+ i0.ɵɵconditional(ctx.showStopConfirmDialog ? 9 : -1);
1276
+ } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent, i4.LoadingComponent, i5.MJButtonDirective, i5.MJPageHeaderInteriorComponent, i5.MJPageBodyInteriorComponent, i5.MJRefreshButtonComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n\n.sticky-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n\n\n\n\n.scrollable-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem 2.5rem;\n }\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons[_ngcontent-%COMP%] {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n\n\n\n\n.mj-grid-4[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 1rem 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1rem 1.5rem;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n.mj-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\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\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\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.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\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(--mj-text-primary);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n }\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\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 flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.75rem;\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 1.5rem 1rem 1.5rem;\n padding: 1rem 1.25rem;\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 (min-width: 768px) {\n .filters-row[_ngcontent-%COMP%] {\n gap: 1.5rem;\n }\n}\n\n.mj-filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.mj-filter-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-full);\n padding: 4px;\n gap: 2px;\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 (min-width: 640px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 280px;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 400px;\n max-width: 600px;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 500px;\n max-width: 800px;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n left: 1.25rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n font-size: 1rem;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem 1rem 3.25rem;\n font-size: 1.0625rem;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1.125rem 1.5rem 1.125rem 3.5rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-secondary);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--mj-bg-page);\n}\n\n.mj-search[_ngcontent-%COMP%]:focus-within .mj-search-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\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(--mj-bg-page);\n border-radius: var(--mj-radius-xl);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem;\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n\n\n\n\n.expand-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--mj-radius-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n\n\n\n\n.status-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(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success);\n}\n\n.status-badge.status-inactive[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n}\n\n.status-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n}\n\n\n\n\n\n.mobile-actions-bar[_ngcontent-%COMP%] {\n display: none;\n}\n\n.mobile-action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--mj-border-default);\n margin-bottom: 1.5rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n\n\n\n\n.error-container[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n font-size: 3.5rem;\n color: var(--mj-status-error);\n margin-bottom: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-message[_ngcontent-%COMP%] {\n font-size: 1.0625rem;\n color: var(--mj-text-primary);\n margin: 0 0 1.5rem 0;\n}\n\n\n\n\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUp 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--mj-text-primary);\n margin: 0 0 1rem 0;\n line-height: 1.5;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (max-width: 639px) {\n .modal-dialog[_ngcontent-%COMP%] {\n width: 95%;\n max-height: 85vh;\n }\n\n .modal-header[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n\n .modal-body[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .modal-footer[_ngcontent-%COMP%] {\n padding: 1rem;\n flex-direction: column;\n }\n\n}\n\n\n\n\n\n\n\n\n\n\n\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(--mj-border-default);\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n border-radius: var(--mj-radius-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(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.filter-button[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.filter-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n\n\n\n\n.filter-modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: flex-end;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 0;\n}\n\n.filter-modal[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl) var(--mj-radius-2xl) 0 0;\n box-shadow: var(--mj-shadow-2xl);\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(--mj-border-default);\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(--mj-text-primary);\n margin: 0;\n}\n\n.filter-modal-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-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(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-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(--mj-brand-primary);\n color: var(--mj-brand-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(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\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(--mj-text-primary);\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(--mj-bg-surface-sunken);\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\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(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-option.selected[_ngcontent-%COMP%] {\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-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(--mj-brand-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(--mj-text-primary);\n}\n\n.filter-option.selected[_ngcontent-%COMP%] .filter-option-label[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n\n\n\n\n.text-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.text-warning[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-500);\n}\n\n.text-success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\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 transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\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.mj-search-input[_ngcontent-%COMP%]:focus-visible, \nbutton[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}", "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n@media (max-width: 639px) {\n .stats-toggle-button[_ngcontent-%COMP%] {\n padding: 0.875rem 1rem;\n }\n\n .stats-toggle-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n }\n\n .stats-toggle-title[_ngcontent-%COMP%] {\n font-size: 0.9375rem;\n }\n\n .stats-toggle-subtitle[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n }\n\n .stats-toggle-arrow[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n}\n\n\n\n\n\n.stats-toggle-container[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.stats-toggle-button[_ngcontent-%COMP%] {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.stats-toggle-button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.stats-toggle-button.expanded[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-accent-subtle);\n margin-bottom: 1rem;\n}\n\n.stats-toggle-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.stats-toggle-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n.stats-toggle-button.expanded[_ngcontent-%COMP%] .stats-toggle-icon[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.stats-toggle-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.stats-toggle-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.stats-toggle-button.expanded[_ngcontent-%COMP%] .stats-toggle-title[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.stats-toggle-subtitle[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.stats-toggle-arrow[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n color: var(--mj-text-secondary);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.stats-toggle-button.expanded[_ngcontent-%COMP%] .stats-toggle-arrow[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n color: var(--mj-brand-primary);\n}\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr;\n gap: 0.75rem;\n width: 100%;\n overflow: hidden;\n max-height: 0;\n opacity: 0;\n transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.stats-grid.visible[_ngcontent-%COMP%] {\n max-height: 1000px;\n opacity: 1;\n margin-bottom: 1.5rem;\n}\n\n@media (min-width: 640px) {\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .stats-toggle-button[_ngcontent-%COMP%] {\n display: none;\n }\n\n .stats-grid[_ngcontent-%COMP%] {\n max-height: none;\n opacity: 1;\n margin-bottom: 1.5rem;\n gap: 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(4, 1fr);\n gap: 1.5rem;\n }\n}\n\n@media (min-width: 1440px) {\n .stats-grid[_ngcontent-%COMP%] {\n gap: 2rem;\n }\n}\n\n\n\n.stat-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1.25rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\n cursor: default;\n}\n\n\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n font-size: 1.5rem;\n}\n\n@media (max-width: 639px) {\n .stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 1.25rem;\n }\n}\n\n.stat-icon-status[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n\n.stat-icon-active[_ngcontent-%COMP%] {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-limit[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n\n.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n\n\n\n@media (max-width: 639px) {\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n font-weight: 700;\n }\n}\n\n\n\n\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n box-shadow: none;\n}\n\n@media (min-width: 640px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.25rem;\n }\n}\n\n\n\n\n\n.sessions-layout[_ngcontent-%COMP%] {\n display: flex;\n gap: 1.5rem;\n min-height: 400px;\n overflow: visible;\n}\n\n@media (max-width: 767px) {\n .sessions-layout[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 1rem;\n min-height: auto;\n }\n}\n\n@media (min-width: 768px) and (max-width: 1023px) {\n .sessions-layout[_ngcontent-%COMP%] {\n gap: 1.25rem;\n }\n}\n\n\n\n\n\n.sessions-panel[_ngcontent-%COMP%] {\n flex: 0 0 380px;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n background: var(--mj-bg-surface);\n max-height: 600px;\n}\n\n@media (max-width: 767px) {\n .sessions-panel[_ngcontent-%COMP%] {\n flex: none;\n max-height: 350px;\n }\n}\n\n@media (min-width: 768px) and (max-width: 1023px) {\n .sessions-panel[_ngcontent-%COMP%] {\n flex: 0 0 320px;\n }\n}\n\n@media (min-width: 1440px) {\n .sessions-panel[_ngcontent-%COMP%] {\n flex: 0 0 420px;\n }\n}\n\n.panel-header[_ngcontent-%COMP%] {\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-shrink: 0;\n gap: 0.5rem;\n}\n\n@media (max-width: 639px) {\n .panel-header[_ngcontent-%COMP%] {\n padding: 0.75rem;\n flex-wrap: wrap;\n }\n}\n\n.panel-header[_ngcontent-%COMP%] .panel-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n flex-shrink: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (max-width: 639px) {\n .panel-header[_ngcontent-%COMP%] .panel-title[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n max-width: 50%;\n }\n}\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .panel-actions[_ngcontent-%COMP%] {\n gap: 0.25rem;\n }\n\n .panel-actions[_ngcontent-%COMP%] .checkbox-label[_ngcontent-%COMP%] {\n font-size: 0;\n gap: 0;\n min-height: 36px;\n padding: 0;\n }\n\n .panel-actions[_ngcontent-%COMP%] .checkbox-label[_ngcontent-%COMP%]::after {\n content: \"Auto\";\n font-size: 0.75rem;\n margin-left: 0.25rem;\n }\n}\n\n.sessions-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n min-height: 0;\n position: relative;\n padding: 0.75rem;\n}\n\n\n\n\n\n.session-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 1rem;\n margin-bottom: 0.75rem;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.session-card[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.session-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-sm);\n border-color: var(--mj-brand-primary);\n}\n\n.session-card.selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-brand-accent-subtle);\n}\n\n.session-card[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.session-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.75rem;\n}\n\n.session-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.session-info[_ngcontent-%COMP%] .session-title[_ngcontent-%COMP%] {\n margin: 0 0 0.5rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.session-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n flex-wrap: wrap;\n}\n\n.session-meta[_ngcontent-%COMP%] .meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.session-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n margin-top: 0.5rem;\n}\n\n\n\n\n\n.badge[_ngcontent-%COMP%] {\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n}\n\n.badge-user[_ngcontent-%COMP%] {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.badge-migration[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success);\n}\n\n.badge-type[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning);\n}\n\n\n\n\n\n.action-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n border-radius: var(--mj-radius-full);\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: flex;\n align-items: center;\n justify-content: center;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.action-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.action-btn-danger[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n color: var(--mj-brand-on-primary);\n}\n\n\n\n\n\n.log-viewer-panel[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n background: var(--mj-bg-surface);\n min-height: 400px;\n}\n\n@media (max-width: 767px) {\n .log-viewer-panel[_ngcontent-%COMP%] {\n min-height: 350px;\n }\n}\n\n\n\n.log-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 300px;\n height: 100%;\n position: relative;\n background: var(--mj-text-primary);\n color: var(--mj-border-strong);\n}\n\n.log-content[_ngcontent-%COMP%] .cm-editor {\n height: 100%;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n font-size: 0.875rem;\n}\n\n.log-content[_ngcontent-%COMP%] .cm-scroller {\n font-family: inherit;\n}\n\n.log-content[_ngcontent-%COMP%] .cm-content {\n background: var(--mj-text-primary);\n color: var(--mj-border-strong);\n}\n\n.log-content[_ngcontent-%COMP%] .cm-gutters {\n background: var(--mj-text-primary);\n color: var(--mj-text-disabled);\n border-right: 1px solid var(--mj-text-secondary);\n}\n\n.log-content[_ngcontent-%COMP%] .cm-activeLineGutter {\n background: var(--mj-text-primary);\n}\n\n.log-content[_ngcontent-%COMP%] .cm-activeLine {\n background: rgba(255, 255, 255, 0.04);\n}\n\n\n\n.log-viewer-panel.expanded[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n border-radius: 0;\n margin: 0;\n max-height: none;\n height: 100vh;\n animation: _ngcontent-%COMP%_expandIn 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.log-viewer-panel.expanded[_ngcontent-%COMP%] .panel-header[_ngcontent-%COMP%] {\n border-radius: 0;\n}\n\n.log-viewer-panel.expanded[_ngcontent-%COMP%] .log-content[_ngcontent-%COMP%] {\n max-height: calc(100vh - 60px);\n min-height: calc(100vh - 60px);\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] .empty-icon.warning[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n max-width: 400px;\n}\n\n\n\n\n\n.info-box[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n padding: 1.5rem;\n margin-top: 1.5rem;\n text-align: left;\n max-width: 500px;\n border: 1px solid var(--mj-border-default);\n}\n\n.info-box[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 1rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.info-box[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n margin: 0;\n padding-left: 1.25rem;\n font-size: 1rem;\n color: var(--mj-text-primary);\n}\n\n.info-box[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin-bottom: 0.5rem;\n}\n\n.info-box[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-active);\n padding: 0.125rem 0.5rem;\n border-radius: var(--mj-radius-sm);\n font-size: 0.8125rem;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n color: var(--mj-text-primary);\n}\n\n\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n min-height: 300px;\n}\n\n.loading-text[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin-top: 1rem;\n}\n\n\n\n\n\n.modal-backdrop[_ngcontent-%COMP%] {\n background: var(--mj-bg-overlay);\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n width: 90%;\n display: flex;\n flex-direction: column;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.modal-dialog.modal-large[_ngcontent-%COMP%] {\n max-width: 700px;\n}\n\n\n\n.modal-dialog.fullscreen[_ngcontent-%COMP%] {\n max-width: 100vw;\n width: 100vw;\n max-height: 100vh;\n height: 100vh;\n border-radius: 0;\n margin: 0;\n}\n\n@media (max-width: 639px) {\n .modal-dialog[_ngcontent-%COMP%] {\n width: 95%;\n max-height: 85vh;\n border-radius: var(--mj-radius-2xl);\n }\n\n .modal-dialog.fullscreen[_ngcontent-%COMP%] {\n border-radius: 0;\n max-height: 100vh;\n }\n}\n\n.modal-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-header[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n}\n\n\n\n.modal-header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n flex-shrink: 0;\n}\n\n.modal-action-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.125rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.modal-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-action-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.modal-body[_ngcontent-%COMP%] {\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n flex: 1;\n}\n\n@media (max-width: 639px) {\n .modal-body[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n justify-content: flex-end;\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-footer[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n\n \n\n .modal-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}\n\n\n\n\n\n.form-group[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.form-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n margin-bottom: 0.5rem;\n}\n\n.form-input[_ngcontent-%COMP%], \n.form-select[_ngcontent-%COMP%], \n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n min-height: 44px;\n padding: 0.875rem 1rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n font-size: 1rem;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.form-input[_ngcontent-%COMP%]:hover, \n.form-select[_ngcontent-%COMP%]:hover, \n.form-textarea[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.form-input[_ngcontent-%COMP%]:focus, \n.form-select[_ngcontent-%COMP%]:focus, \n.form-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.form-input[_ngcontent-%COMP%]::placeholder, \n.form-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-secondary);\n opacity: 0.7;\n}\n\n.form-select[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.form-hint[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin-top: 0.375rem;\n}\n\n.form-checkboxes[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n font-size: 1rem;\n color: var(--mj-text-primary);\n cursor: pointer;\n min-height: 44px;\n padding: 0.25rem 0;\n}\n\n.checkbox-label[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n\n\n.form-section[_ngcontent-%COMP%] {\n margin-top: 1.5rem;\n padding: 1.25rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n background: var(--mj-bg-surface-sunken);\n}\n\n.form-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n margin: 0 0 1rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.form-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 1.125rem;\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n resize: vertical;\n min-height: 100px;\n}\n\n\n\n\n\n.confirm-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 420px;\n width: 90%;\n padding: 2rem;\n text-align: center;\n animation: _ngcontent-%COMP%_dialogBounce 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n@media (max-width: 639px) {\n .confirm-dialog[_ngcontent-%COMP%] {\n padding: 1.5rem;\n border-radius: var(--mj-radius-2xl);\n }\n}\n\n.confirm-dialog-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: var(--mj-status-warning-bg);\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 1.5rem;\n}\n\n.confirm-dialog-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n color: var(--mj-status-warning-text);\n}\n\n.confirm-dialog-content[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.confirm-dialog-title[_ngcontent-%COMP%] {\n margin: 0 0 0.75rem 0;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.confirm-dialog-message[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n}\n\n.confirm-dialog-message[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n.confirm-dialog-details[_ngcontent-%COMP%] {\n display: block;\n margin-top: 0.75rem;\n padding: 0.75rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-md);\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n\n.confirm-dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n justify-content: center;\n}\n\n@media (max-width: 639px) {\n .confirm-dialog-actions[_ngcontent-%COMP%] {\n flex-direction: column-reverse;\n }\n\n \n\n .confirm-dialog-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_expandIn {\n from {\n transform: scale(0.95);\n opacity: 0;\n }\n to {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_dialogBounce {\n 0% {\n transform: scale(0.9) translateY(10px);\n opacity: 0;\n }\n 70% {\n transform: scale(1.02) translateY(-5px);\n }\n 100% {\n transform: scale(1) translateY(0);\n opacity: 1;\n }\n}\n\n\n\n\n\n.sr-only[_ngcontent-%COMP%] {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}"] });
1280
1277
  };
1281
1278
  SqlLoggingComponent = __decorate([
1282
1279
  RegisterClass(BaseDashboard, 'SqlLogging')
@@ -1284,7 +1281,7 @@ SqlLoggingComponent = __decorate([
1284
1281
  export { SqlLoggingComponent };
1285
1282
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SqlLoggingComponent, [{
1286
1283
  type: Component,
1287
- args: [{ standalone: false, selector: 'mj-sql-logging', template: "<div class=\"sql-logging-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\" role=\"toolbar\" aria-label=\"SQL logging actions\">\n <button\n class=\"btn-secondary\"\n (click)=\"loadActiveSessions()\"\n [disabled]=\"loading\"\n aria-label=\"Refresh sessions\"\n >\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"loading\" aria-hidden=\"true\"></i>\n Refresh\n </button>\n @if (isOwner && configEnabled) {\n <button\n class=\"btn-primary\"\n [disabled]=\"loading || activeSessions.length >= (sqlLoggingConfig?.maxActiveSessions || 5)\"\n (click)=\"openStartSessionDialog()\"\n [attr.aria-label]=\"'Start new SQL logging session' + (activeSessions.length >= (sqlLoggingConfig?.maxActiveSessions || 5) ? ' (maximum sessions reached)' : '')\"\n >\n <i class=\"fa-solid fa-play\" aria-hidden=\"true\"></i>\n Start New Session\n </button>\n }\n </div>\n\n <!-- Stats Cards with Toggle -->\n @if (isOwner && configEnabled) {\n <div class=\"stats-toggle-container\">\n <!-- Toggle Button -->\n <button\n class=\"stats-toggle-button\"\n [class.expanded]=\"showStats\"\n (click)=\"showStats = !showStats\"\n [attr.aria-expanded]=\"showStats\"\n aria-controls=\"stats-grid-content\"\n >\n <div class=\"stats-toggle-left\">\n <div class=\"stats-toggle-icon\">\n <i class=\"fa-solid fa-chart-line\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"stats-toggle-text\">\n <h3 class=\"stats-toggle-title\">Statistics</h3>\n <p class=\"stats-toggle-subtitle\">View session statistics and metrics</p>\n </div>\n </div>\n <i class=\"fa-solid fa-chevron-down stats-toggle-arrow\" aria-hidden=\"true\"></i>\n </button>\n\n <!-- Stats Grid (Collapsible) -->\n <div\n id=\"stats-grid-content\"\n class=\"stats-grid\"\n [class.visible]=\"showStats\"\n role=\"region\"\n aria-label=\"SQL logging statistics\"\n >\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-status\">\n <i class=\"fa-solid fa-power-off\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" [attr.aria-label]=\"'Status: ' + (configEnabled ? 'Enabled' : 'Disabled')\">\n {{ configEnabled ? \"Enabled\" : \"Disabled\" }}\n </div>\n <div class=\"stat-label\">Status</div>\n </div>\n </div>\n\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-active\">\n <i class=\"fa-solid fa-play-circle\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" [attr.aria-label]=\"activeSessions.length + ' active sessions'\">\n {{ activeSessions.length }}\n </div>\n <div class=\"stat-label\">Active Sessions</div>\n </div>\n </div>\n\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-limit\">\n <i class=\"fa-solid fa-gauge-high\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" [attr.aria-label]=\"(sqlLoggingConfig?.maxActiveSessions || 5) + ' maximum sessions allowed'\">\n {{ sqlLoggingConfig?.maxActiveSessions || 5 }}\n </div>\n <div class=\"stat-label\">Max Sessions</div>\n </div>\n </div>\n\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-total\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" [attr.aria-label]=\"getTotalStatementCount() + ' total SQL statements captured'\">\n {{ getTotalStatementCount() }}\n </div>\n <div class=\"stat-label\">Total Statements</div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- Loading State -->\n @if (loading && !activeSessions.length) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading SQL logging configuration...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Content Area -->\n @if (!loading || activeSessions.length > 0) {\n <div class=\"content-area\">\n @if (!isOwner) {\n <!-- Not authorized -->\n <div class=\"empty-state\" role=\"alert\">\n <i class=\"fa-solid fa-lock empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">Access Denied</p>\n <p class=\"empty-subtext\">SQL logging requires Owner privileges. Please contact your system administrator for access.</p>\n <button class=\"btn-secondary\" (click)=\"refreshUserPermissions()\" style=\"margin-top: 1rem\" aria-label=\"Refresh user permissions\">\n <i class=\"fa-solid fa-sync\" aria-hidden=\"true\"></i>\n Refresh Permissions\n </button>\n </div>\n } @else if (!configEnabled) {\n <!-- Not enabled in config -->\n <div class=\"empty-state\" role=\"alert\">\n <i class=\"fa-solid fa-exclamation-triangle empty-icon warning\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">SQL Logging Disabled</p>\n <p class=\"empty-subtext\">SQL logging is not enabled in the server configuration.</p>\n <div class=\"info-box\">\n <h4>To enable SQL logging:</h4>\n <ol>\n <li>Set <code>sqlLogging.enabled = true</code> in mj.config.cjs</li>\n <li>Restart the MJ API server</li>\n <li>Refresh this page</li>\n </ol>\n </div>\n </div>\n } @else if (activeSessions.length === 0) {\n <!-- No active sessions -->\n <div class=\"empty-state\" role=\"status\">\n <i class=\"fa-solid fa-file-code empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">No Active Sessions</p>\n <p class=\"empty-subtext\">Start a new SQL logging session to begin capturing SQL statements.</p>\n <button class=\"btn-primary\" (click)=\"openStartSessionDialog()\" style=\"margin-top: 1rem\" aria-label=\"Start a new SQL logging session\">\n <i class=\"fa-solid fa-play\" aria-hidden=\"true\"></i>\n Start New Session\n </button>\n </div>\n } @else {\n <!-- Sessions layout -->\n <div class=\"sessions-layout\">\n <!-- Sessions panel -->\n <div class=\"sessions-panel\" role=\"region\" aria-label=\"Active sessions list\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">Active Sessions</h3>\n @if (activeSessions.length > 0) {\n <button\n class=\"btn-danger btn-small\"\n (click)=\"openStopAllSessionsConfirm()\"\n [disabled]=\"loading\"\n aria-label=\"Stop all active sessions\"\n >\n <i class=\"fa-solid fa-stop\" aria-hidden=\"true\"></i>\n Stop All\n </button>\n }\n </div>\n <div class=\"sessions-list\" role=\"list\" aria-label=\"SQL logging sessions\">\n @for (session of activeSessions; track session.id) {\n <div\n class=\"session-card\"\n [class.selected]=\"selectedSession?.id === session.id\"\n (click)=\"selectSession(session)\"\n role=\"listitem\"\n tabindex=\"0\"\n (keydown.enter)=\"selectSession(session)\"\n (keydown.space)=\"selectSession(session); $event.preventDefault()\"\n [attr.aria-label]=\"'Session: ' + session.sessionName + ', ' + session.statementCount + ' statements, duration ' + getSessionDuration(session.startTime)\"\n [attr.aria-selected]=\"selectedSession?.id === session.id\"\n >\n <div class=\"session-header\">\n <div class=\"session-info\">\n <h4 class=\"session-title\">{{ session.sessionName }}</h4>\n <div class=\"session-meta\">\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-clock\" aria-hidden=\"true\"></i>\n {{ getSessionDuration(session.startTime) }}\n </span>\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n {{ session.statementCount }} statements\n </span>\n </div>\n </div>\n <button mjButton\n variant=\"danger\"\n size=\"sm\"\n (click)=\"openStopSessionConfirm(session, $event)\"\n [attr.aria-label]=\"'Stop session ' + session.sessionName\"\n >\n <i class=\"fa-solid fa-stop\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"session-badges\">\n @if (session.filterByUserId) {\n <span class=\"badge badge-user\">\n <i class=\"fa-solid fa-user\" aria-hidden=\"true\"></i>\n User Filtered\n </span>\n }\n @if (session.options?.formatAsMigration) {\n <span class=\"badge badge-migration\">\n <i class=\"fa-solid fa-code-branch\" aria-hidden=\"true\"></i>\n Migration\n </span>\n }\n <span class=\"badge badge-type\">\n {{ session.options?.statementTypes || \"both\" }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Log viewer panel -->\n <div class=\"log-viewer-panel\" [class.expanded]=\"isLogViewerExpanded\" role=\"region\" aria-label=\"SQL log viewer\">\n @if (selectedSession) {\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">{{ selectedSession.sessionName }}</h3>\n <div class=\"panel-actions\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"autoRefresh\"\n aria-label=\"Enable auto-refresh\"\n />\n Auto-refresh\n </label>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"loadSessionLog(selectedSession)\"\n aria-label=\"Refresh log content\"\n >\n <i class=\"fa-solid fa-sync\" [class.fa-spin]=\"loading\" aria-hidden=\"true\"></i>\n </button>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"toggleLogViewerExpand()\"\n [attr.aria-label]=\"isLogViewerExpanded ? 'Collapse log viewer' : 'Expand log viewer to fullscreen'\"\n [attr.aria-expanded]=\"isLogViewerExpanded\"\n >\n <i class=\"fa-solid\" [class.fa-expand]=\"!isLogViewerExpanded\" [class.fa-compress]=\"isLogViewerExpanded\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"log-content\">\n <mj-code-editor\n [value]=\"logContent\"\n [readonly]=\"true\"\n [disabled]=\"true\"\n [language]=\"'sql'\"\n [setup]=\"'basic'\"\n [lineWrapping]=\"true\"\n [highlightWhitespace]=\"false\"\n style=\"height: 100%\"\n aria-label=\"SQL log content\"\n ></mj-code-editor>\n </div>\n } @else {\n <div class=\"empty-state\" role=\"status\">\n <i class=\"fa-solid fa-arrow-left empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">Select a Session</p>\n <p class=\"empty-subtext\">Choose a session from the list to view its SQL log.</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Start Session Dialog -->\n @if (showStartSessionDialog) {\n <div\n class=\"modal-backdrop\"\n (click)=\"showStartSessionDialog = false\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"start-session-dialog-title\"\n >\n <div class=\"modal-dialog modal-large\" [class.fullscreen]=\"isStartDialogFullscreen\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"start-session-dialog-title\">\n <i class=\"fa-solid fa-play\" aria-hidden=\"true\"></i>\n Start SQL Logging Session\n </h3>\n <div class=\"modal-header-actions\">\n <button\n class=\"modal-action-btn\"\n (click)=\"toggleStartDialogFullscreen()\"\n [attr.aria-label]=\"isStartDialogFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'\"\n type=\"button\"\n >\n <i class=\"fa-solid\" [class.fa-compress]=\"isStartDialogFullscreen\" [class.fa-expand]=\"!isStartDialogFullscreen\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"modal-close\" (click)=\"showStartSessionDialog = false\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"modal-body\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"session-name\">Session Name</label>\n <input\n type=\"text\"\n id=\"session-name\"\n class=\"form-input\"\n [(ngModel)]=\"newSessionOptions.sessionName\"\n placeholder=\"Enter a descriptive name for this session\"\n aria-describedby=\"session-name-hint\"\n />\n <div id=\"session-name-hint\" class=\"form-hint\">A descriptive name to identify this logging session</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"file-name\">File Name</label>\n <input\n type=\"text\"\n id=\"file-name\"\n class=\"form-input\"\n [(ngModel)]=\"newSessionOptions.fileName\"\n placeholder=\"sql-log-2024-01-01.sql\"\n aria-describedby=\"file-name-hint\"\n />\n <div id=\"file-name-hint\" class=\"form-hint\">The SQL log will be saved to this file</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"statement-types\">Statement Types</label>\n <select\n id=\"statement-types\"\n class=\"form-select\"\n [(ngModel)]=\"newSessionOptions.statementTypes\"\n aria-describedby=\"statement-types-hint\"\n >\n @for (option of statementTypeOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.text }}</option>\n }\n </select>\n <div id=\"statement-types-hint\" class=\"form-hint\">Filter which types of SQL statements to capture</div>\n </div>\n\n <div class=\"form-checkboxes\" role=\"group\" aria-label=\"Session options\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"newSessionOptions.filterToCurrentUser\" />\n Filter to my SQL statements only\n </label>\n\n\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"newSessionOptions.formatAsMigration\" />\n Format as migration file\n </label>\n\n\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"newSessionOptions.prettyPrint\" />\n Pretty print SQL statements\n </label>\n </div>\n\n <!-- SQL Pattern Filtering Section -->\n <div class=\"form-section\">\n <h4 class=\"form-section-title\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n SQL Pattern Filtering\n </h4>\n\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"filter-type\">Filter Mode</label>\n <select\n id=\"filter-type\"\n class=\"form-select\"\n [(ngModel)]=\"newSessionOptions.filterType\"\n aria-describedby=\"filter-type-hint\"\n >\n @for (option of filterTypeOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.text }}</option>\n }\n </select>\n <div id=\"filter-type-hint\" class=\"form-hint\">Exclude: Skip SQL matching any pattern. Include: Only log SQL matching a pattern.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"filter-patterns\">Filter Patterns (one per line or comma-separated)</label>\n <textarea\n id=\"filter-patterns\"\n class=\"form-textarea\"\n [(ngModel)]=\"newSessionOptions.filterPatterns\"\n rows=\"4\"\n placeholder=\"Examples:&#10;*AIPrompt*&#10;/spCreate.*Run/i&#10;SELECT * FROM vwMetadata\"\n aria-describedby=\"filter-patterns-hint\"\n ></textarea>\n <div id=\"filter-patterns-hint\" class=\"form-hint\">Supports wildcards (*) and regex (/pattern/flags). Example: *spCreate* matches any SP starting with spCreate.</div>\n </div>\n </div>\n\n <!-- Advanced Options Section -->\n <div class=\"form-section\">\n <h4 class=\"form-section-title\">\n <i class=\"fa-solid fa-cog\" aria-hidden=\"true\"></i>\n Advanced Options\n </h4>\n\n @if (newSessionOptions.formatAsMigration) {\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"default-schema\">Default Schema Name</label>\n <input\n type=\"text\"\n id=\"default-schema\"\n class=\"form-input\"\n [(ngModel)]=\"newSessionOptions.defaultSchemaName\"\n placeholder=\"__mj\"\n aria-describedby=\"default-schema-hint\"\n />\n <div id=\"default-schema-hint\" class=\"form-hint\">Schema name to replace with $&#123;flyway:defaultSchema&#125; placeholder.</div>\n </div>\n }\n\n <div class=\"form-checkboxes\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"newSessionOptions.verboseOutput\" />\n Verbose Debug Output\n </label>\n <div class=\"form-hint\" style=\"margin-left: 1.75rem\">Log detailed filter decisions to server console (for debugging).</div>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button class=\"btn-primary\" (click)=\"startNewSession()\" [disabled]=\"loading\" aria-label=\"Start the SQL logging session\">\n @if (loading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Starting...\n } @else {\n <i class=\"fa-solid fa-play\" aria-hidden=\"true\"></i>\n Start Session\n }\n </button>\n <button class=\"btn-secondary\" (click)=\"showStartSessionDialog = false\" aria-label=\"Cancel and close dialog\">Cancel</button>\n </div>\n </div>\n </div>\n }\n\n <!-- Stop Session Confirmation Dialog -->\n @if (showStopConfirmDialog) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelStopConfirm()\"\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby=\"stop-dialog-title\"\n aria-describedby=\"stop-dialog-desc\"\n >\n <div class=\"confirm-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"confirm-dialog-icon\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"confirm-dialog-content\">\n <h3 class=\"confirm-dialog-title\" id=\"stop-dialog-title\">\n @if (isStoppingAll) {\n Stop All Sessions?\n } @else {\n Stop Session?\n }\n </h3>\n <p class=\"confirm-dialog-message\" id=\"stop-dialog-desc\">\n @if (isStoppingAll) {\n Are you sure you want to stop <strong>all {{ activeSessions.length }} active</strong> SQL logging sessions? This action cannot be undone.\n } @else if (sessionToStop) {\n Are you sure you want to stop the session <strong>\"{{ sessionToStop.sessionName }}\"</strong>?\n <span class=\"confirm-dialog-details\"> This session has captured {{ sessionToStop.statementCount }} SQL statements. </span>\n }\n </p>\n </div>\n <div class=\"confirm-dialog-actions\">\n <button class=\"btn-danger\" (click)=\"confirmStopSession()\" [disabled]=\"loading\" [attr.aria-label]=\"isStoppingAll ? 'Confirm stop all sessions' : 'Confirm stop session'\">\n @if (loading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Stopping...\n } @else {\n <i class=\"fa-solid fa-stop\" aria-hidden=\"true\"></i>\n @if (isStoppingAll) {\n Stop All Sessions\n } @else {\n Stop Session\n }\n }\n </button>\n <button class=\"btn-secondary\" (click)=\"cancelStopConfirm()\" [disabled]=\"loading\" aria-label=\"Cancel and keep sessions running\">Cancel</button>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: ["/* =============================================================================\n Shared Admin Patterns - MJ Design System\n Common styles shared across all admin settings components.\n Component-specific CSS files override these values where needed.\n ============================================================================= */\n\n/* -----------------------------------------------------------------------------\n Host & Container\n ----------------------------------------------------------------------------- */\n:host {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Sticky Header\n ----------------------------------------------------------------------------- */\n.sticky-header {\n flex-shrink: 0;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n/* -----------------------------------------------------------------------------\n Scrollable Content\n ----------------------------------------------------------------------------- */\n.scrollable-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .scrollable-content {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .scrollable-content {\n padding: 2rem 2.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons (In Sticky Header)\n ----------------------------------------------------------------------------- */\n.action-buttons {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .action-buttons {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n }\n\n .mj-btn-icon-mobile .btn-text {\n display: none;\n }\n\n .mj-btn-icon-mobile {\n padding: 0.5rem 0.75rem;\n min-height: 40px;\n gap: 0;\n border-radius: var(--mj-radius-full);\n }\n\n .mj-btn-icon-mobile i {\n font-size: 1.125rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Statistics Cards Grid - Static Display (Non-interactive)\n ----------------------------------------------------------------------------- */\n.mj-grid-4 {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 1rem 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4 {\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1rem 1.5rem;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4 {\n gap: 1rem;\n }\n}\n\n/* Static Card - No hover effects */\n.mj-card {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\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/* -----------------------------------------------------------------------------\n Stat Icon Containers\n ----------------------------------------------------------------------------- */\n.stat-icon {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\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.stat-icon-total {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-active {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\n/* -----------------------------------------------------------------------------\n Stat Content Typography\n ----------------------------------------------------------------------------- */\n.stat-content {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content .stat-value {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content .stat-value {\n font-size: 2rem;\n }\n}\n\n.stat-content .stat-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\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 flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.75rem;\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .filters-section {\n margin: 0 1.5rem 1rem 1.5rem;\n padding: 1rem 1.25rem;\n }\n}\n\n.filters-row {\n display: flex;\n gap: 1rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (min-width: 768px) {\n .filters-row {\n gap: 1.5rem;\n }\n}\n\n.mj-filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.mj-filter-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-buttons {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-full);\n padding: 4px;\n gap: 2px;\n}\n\n.mj-filter-buttons .mj-btn {\n border-radius: var(--mj-radius-full);\n}\n\n.mj-filter-buttons .mj-btn-primary {\n background-color: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n/* -----------------------------------------------------------------------------\n Search Input\n ----------------------------------------------------------------------------- */\n.mj-search {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n@media (min-width: 640px) {\n .mj-search {\n min-width: 280px;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-search {\n min-width: 400px;\n max-width: 600px;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search {\n min-width: 500px;\n max-width: 800px;\n }\n}\n\n.mj-search .mj-search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-icon {\n left: 1.25rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search .mj-search-input {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n font-size: 1rem;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-input {\n padding: 1rem 1.25rem 1rem 3.25rem;\n font-size: 1.0625rem;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search .mj-search-input {\n padding: 1.125rem 1.5rem 1.125rem 3.5rem;\n }\n}\n\n.mj-search .mj-search-input::placeholder {\n color: var(--mj-text-secondary);\n}\n\n.mj-search .mj-search-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search .mj-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--mj-bg-page);\n}\n\n.mj-search:focus-within .mj-search-icon {\n color: var(--mj-brand-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Content Area\n ----------------------------------------------------------------------------- */\n.content-area {\n flex: 1 1 auto;\n overflow: visible;\n position: relative;\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-xl);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem;\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .content-area {\n padding: 1.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Expand Button\n ----------------------------------------------------------------------------- */\n.expand-btn {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--mj-radius-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.expand-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.expand-btn i {\n transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* -----------------------------------------------------------------------------\n Status Badge\n ----------------------------------------------------------------------------- */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.status-badge.status-active {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success);\n}\n\n.status-badge.status-inactive {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n}\n\n.status-badge i {\n font-size: 0.625rem;\n}\n\n/* -----------------------------------------------------------------------------\n Mobile Actions Bar\n ----------------------------------------------------------------------------- */\n.mobile-actions-bar {\n display: none;\n}\n\n.mobile-action-buttons {\n display: flex;\n gap: 0.5rem;\n}\n\n/* -----------------------------------------------------------------------------\n Empty State\n ----------------------------------------------------------------------------- */\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state .empty-icon {\n font-size: 4rem;\n color: var(--mj-border-default);\n margin-bottom: 1.5rem;\n}\n\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state .empty-subtext {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Loading State\n ----------------------------------------------------------------------------- */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n/* -----------------------------------------------------------------------------\n Error State\n ----------------------------------------------------------------------------- */\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container .error-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container .error-icon {\n font-size: 3.5rem;\n color: var(--mj-status-error);\n margin-bottom: 1rem;\n}\n\n.error-container .error-message {\n font-size: 1.0625rem;\n color: var(--mj-text-primary);\n margin: 0 0 1.5rem 0;\n}\n\n/* -----------------------------------------------------------------------------\n Modal Dialog\n ----------------------------------------------------------------------------- */\n.modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: fadeIn 0.2s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-dialog {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.modal-header .modal-close {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.modal-header .modal-close:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n\n.modal-body p {\n font-size: 1rem;\n color: var(--mj-text-primary);\n margin: 0 0 1rem 0;\n line-height: 1.5;\n}\n\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (max-width: 639px) {\n .modal-dialog {\n width: 95%;\n max-height: 85vh;\n }\n\n .modal-header {\n padding: 1rem;\n }\n\n .modal-header .modal-title {\n font-size: 1.125rem;\n }\n\n .modal-body {\n padding: 1rem;\n }\n\n .modal-footer {\n padding: 1rem;\n flex-direction: column;\n }\n\n .modal-footer .mj-btn {\n width: 100%;\n justify-content: center;\n }\n}\n\n/* -----------------------------------------------------------------------------\n MJ Button System\n ----------------------------------------------------------------------------- */\n.mj-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n font-weight: 600;\n border: none;\n border-radius: var(--mj-radius-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.mj-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n/* Primary Button */\n.mj-btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.mj-btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-light);\n box-shadow: var(--mj-shadow-md);\n}\n\n.mj-btn-primary:active:not(:disabled) {\n background: var(--mj-color-brand-400);\n transform: scale(0.98);\n}\n\n/* Secondary Button */\n.mj-btn-secondary {\n background: var(--mj-bg-page);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-color-neutral-400);\n}\n\n.mj-btn-secondary:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.mj-btn-secondary:active:not(:disabled) {\n background: var(--mj-color-brand-700);\n border-color: var(--mj-color-brand-700);\n}\n\n/* Ghost Button */\n.mj-btn-ghost {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.mj-btn-ghost:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.mj-btn-ghost:active:not(:disabled) {\n background: var(--mj-color-brand-700);\n}\n\n/* Danger Button */\n.mj-btn-danger {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.mj-btn-danger:hover:not(:disabled) {\n background: var(--mj-color-error-300);\n box-shadow: var(--mj-shadow-md);\n}\n\n.mj-btn-danger:active:not(:disabled) {\n background: var(--mj-color-error-200);\n transform: scale(0.98);\n}\n\n/* Small Button */\n.mj-btn-sm {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n/* Icon-only Button */\n.mj-btn-icon-only {\n padding: 0.625rem;\n min-width: 44px;\n min-height: 44px;\n}\n\n/* Icon-mobile Button (text hidden on small screens) */\n.mj-btn-icon-mobile {\n gap: 0.5rem;\n}\n\n.mj-btn-icon-mobile .btn-text {\n display: inline;\n}\n\n/* Ghost Danger Button */\n.mj-btn-ghost.mj-btn-danger {\n background: transparent;\n color: var(--mj-status-error);\n box-shadow: none;\n}\n\n.mj-btn-ghost.mj-btn-danger:hover:not(:disabled) {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\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(--mj-border-default);\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n border-radius: var(--mj-radius-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(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.filter-button:active {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.filter-button i {\n font-size: 1rem;\n}\n\n/* -----------------------------------------------------------------------------\n Filter Modal (Mobile Bottom Sheet)\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(--mj-bg-page);\n border-radius: var(--mj-radius-2xl) var(--mj-radius-2xl) 0 0;\n box-shadow: var(--mj-shadow-2xl);\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(--mj-border-default);\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(--mj-text-primary);\n margin: 0;\n}\n\n.filter-modal-title i {\n color: var(--mj-brand-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(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-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(--mj-brand-primary);\n color: var(--mj-brand-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(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\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(--mj-text-primary);\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(--mj-bg-surface-sunken);\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\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(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-option.selected {\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-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(--mj-brand-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(--mj-text-primary);\n}\n\n.filter-option.selected .filter-option-label {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* -----------------------------------------------------------------------------\n Utility Classes\n ----------------------------------------------------------------------------- */\n.text-danger {\n color: var(--mj-status-error);\n}\n\n.text-warning {\n color: var(--mj-color-warning-500);\n}\n\n.text-success {\n color: var(--mj-status-success);\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 transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\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 Accessibility: Focus Indicators\n ----------------------------------------------------------------------------- */\n.mj-search-input:focus-visible,\nbutton:focus-visible,\n.mj-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Reduced Motion\n ----------------------------------------------------------------------------- */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n", "/* =============================================================================\n SQL Logging Component - Component-Specific Styles\n Shared patterns are in ../shared/styles/_admin-patterns.css\n ============================================================================= */\n\n/* -----------------------------------------------------------------------------\n Host Override - SQL Logging uses block/scroll layout instead of flex\n ----------------------------------------------------------------------------- */\n:host {\n display: block;\n height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Container & Layout\n ----------------------------------------------------------------------------- */\n.sql-logging-container {\n display: flex;\n flex-direction: column;\n min-height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n position: relative;\n background: var(--mj-bg-page);\n padding: 1rem;\n}\n\n@media (min-width: 640px) {\n .sql-logging-container {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .sql-logging-container {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .sql-logging-container {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .sql-logging-container {\n padding: 2rem 2.5rem;\n max-width: 1920px;\n margin: 0 auto;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons Override - Different layout (margin-bottom, no padding/bg)\n ----------------------------------------------------------------------------- */\n.action-buttons {\n margin-bottom: 1.5rem;\n padding: 0;\n background: transparent;\n}\n\n@media (max-width: 639px) {\n .action-buttons {\n justify-content: center;\n }\n\n /* Icon-only buttons on mobile */\n .action-buttons .btn-primary,\n .action-buttons .btn-secondary {\n font-size: 0;\n padding: 0.75rem;\n min-width: 48px;\n min-height: 48px;\n gap: 0;\n }\n\n .action-buttons .btn-primary i,\n .action-buttons .btn-secondary i {\n font-size: 1.125rem;\n }\n\n .stats-toggle-button {\n padding: 0.875rem 1rem;\n }\n\n .stats-toggle-icon {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n }\n\n .stats-toggle-title {\n font-size: 0.9375rem;\n }\n\n .stats-toggle-subtitle {\n font-size: 0.75rem;\n }\n\n .stats-toggle-arrow {\n font-size: 1.125rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Button System - SQL Logging uses .btn-* instead of .mj-btn-*\n ----------------------------------------------------------------------------- */\n.btn-primary,\n.btn-secondary,\n.btn-danger {\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(--mj-radius-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n min-width: 44px;\n}\n\n/* Primary Button */\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-light);\n box-shadow: var(--mj-shadow-md);\n}\n\n.btn-primary:active:not(:disabled) {\n background: var(--mj-color-brand-300);\n transform: scale(0.98);\n}\n\n.btn-primary:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.btn-primary i {\n font-size: 0.875rem;\n}\n\n/* Secondary Button */\n.btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.btn-secondary:active:not(:disabled) {\n background: var(--mj-brand-primary-active);\n border-color: var(--mj-brand-primary-active);\n}\n\n.btn-secondary:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.btn-secondary i {\n font-size: 0.875rem;\n}\n\n/* Danger Button */\n.btn-danger {\n background: var(--mj-status-error);\n color: var(--mj-brand-on-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.btn-danger:hover:not(:disabled) {\n background: var(--mj-color-error-300);\n box-shadow: var(--mj-shadow-md);\n}\n\n.btn-danger:active:not(:disabled) {\n background: var(--mj-color-error-200);\n transform: scale(0.98);\n}\n\n.btn-danger:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.btn-danger i {\n font-size: 0.875rem;\n}\n\n.btn-danger.btn-small {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n/* -----------------------------------------------------------------------------\n Statistics Grid - Collapsible Cards\n ----------------------------------------------------------------------------- */\n.stats-toggle-container {\n margin-bottom: 1.5rem;\n}\n\n.stats-toggle-button {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.stats-toggle-button:hover {\n background: var(--mj-bg-surface-active);\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.stats-toggle-button.expanded {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-accent-subtle);\n margin-bottom: 1rem;\n}\n\n.stats-toggle-left {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.stats-toggle-icon {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n.stats-toggle-button.expanded .stats-toggle-icon {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.stats-toggle-text {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.stats-toggle-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.stats-toggle-button.expanded .stats-toggle-title {\n color: var(--mj-brand-primary);\n}\n\n.stats-toggle-subtitle {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.stats-toggle-arrow {\n font-size: 1.25rem;\n color: var(--mj-text-secondary);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.stats-toggle-button.expanded .stats-toggle-arrow {\n transform: rotate(180deg);\n color: var(--mj-brand-primary);\n}\n\n.stats-grid {\n display: grid;\n grid-template-columns: 1fr;\n gap: 0.75rem;\n width: 100%;\n overflow: hidden;\n max-height: 0;\n opacity: 0;\n transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.stats-grid.visible {\n max-height: 1000px;\n opacity: 1;\n margin-bottom: 1.5rem;\n}\n\n@media (min-width: 640px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .stats-toggle-button {\n display: none;\n }\n\n .stats-grid {\n max-height: none;\n opacity: 1;\n margin-bottom: 1.5rem;\n gap: 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .stats-grid {\n grid-template-columns: repeat(4, 1fr);\n gap: 1.5rem;\n }\n}\n\n@media (min-width: 1440px) {\n .stats-grid {\n gap: 2rem;\n }\n}\n\n/* Static Display Card */\n.stat-card {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1.25rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\n cursor: default;\n}\n\n/* Stat Icon Override - Different sizes */\n.stat-icon {\n width: 56px;\n height: 56px;\n font-size: 1.5rem;\n}\n\n@media (max-width: 639px) {\n .stat-icon {\n width: 48px;\n height: 48px;\n font-size: 1.25rem;\n }\n}\n\n.stat-icon-status {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n\n.stat-icon-active {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-limit {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n\n.stat-icon-total {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n\n/* Stat Value Override for mobile */\n@media (max-width: 639px) {\n .stat-content .stat-value {\n font-size: 1.5rem;\n font-weight: 700;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Content Area Override - Different styling\n ----------------------------------------------------------------------------- */\n.content-area {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n box-shadow: none;\n}\n\n@media (min-width: 640px) {\n .content-area {\n padding: 1.25rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Sessions Layout - Two-panel design\n ----------------------------------------------------------------------------- */\n.sessions-layout {\n display: flex;\n gap: 1.5rem;\n min-height: 400px;\n overflow: visible;\n}\n\n@media (max-width: 767px) {\n .sessions-layout {\n flex-direction: column;\n gap: 1rem;\n min-height: auto;\n }\n}\n\n@media (min-width: 768px) and (max-width: 1023px) {\n .sessions-layout {\n gap: 1.25rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Sessions Panel\n ----------------------------------------------------------------------------- */\n.sessions-panel {\n flex: 0 0 380px;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n background: var(--mj-bg-surface);\n max-height: 600px;\n}\n\n@media (max-width: 767px) {\n .sessions-panel {\n flex: none;\n max-height: 350px;\n }\n}\n\n@media (min-width: 768px) and (max-width: 1023px) {\n .sessions-panel {\n flex: 0 0 320px;\n }\n}\n\n@media (min-width: 1440px) {\n .sessions-panel {\n flex: 0 0 420px;\n }\n}\n\n.panel-header {\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-shrink: 0;\n gap: 0.5rem;\n}\n\n@media (max-width: 639px) {\n .panel-header {\n padding: 0.75rem;\n flex-wrap: wrap;\n }\n}\n\n.panel-header .panel-title {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n flex-shrink: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (max-width: 639px) {\n .panel-header .panel-title {\n font-size: 0.875rem;\n max-width: 50%;\n }\n}\n\n.panel-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .panel-actions {\n gap: 0.25rem;\n }\n\n .panel-actions .checkbox-label {\n font-size: 0;\n gap: 0;\n min-height: 36px;\n padding: 0;\n }\n\n .panel-actions .checkbox-label::after {\n content: \"Auto\";\n font-size: 0.75rem;\n margin-left: 0.25rem;\n }\n}\n\n.sessions-list {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n min-height: 0;\n position: relative;\n padding: 0.75rem;\n}\n\n/* -----------------------------------------------------------------------------\n Session Cards\n ----------------------------------------------------------------------------- */\n.session-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 1rem;\n margin-bottom: 0.75rem;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.session-card:last-child {\n margin-bottom: 0;\n}\n\n.session-card:hover {\n box-shadow: var(--mj-shadow-sm);\n border-color: var(--mj-brand-primary);\n}\n\n.session-card.selected {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-brand-accent-subtle);\n}\n\n.session-card:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.session-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.75rem;\n}\n\n.session-info {\n flex: 1;\n min-width: 0;\n}\n\n.session-info .session-title {\n margin: 0 0 0.5rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.session-meta {\n display: flex;\n gap: 1rem;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n flex-wrap: wrap;\n}\n\n.session-meta .meta-item {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.session-badges {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n margin-top: 0.5rem;\n}\n\n/* -----------------------------------------------------------------------------\n Badges - Chips\n ----------------------------------------------------------------------------- */\n.badge {\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n}\n\n.badge-user {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.badge-migration {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success);\n}\n\n.badge-type {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning);\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons (Icon buttons)\n ----------------------------------------------------------------------------- */\n.action-btn {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n border-radius: var(--mj-radius-full);\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: flex;\n align-items: center;\n justify-content: center;\n}\n\n.action-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.action-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.action-btn-danger:hover {\n background: var(--mj-status-error);\n color: var(--mj-brand-on-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Log Viewer Panel\n ----------------------------------------------------------------------------- */\n.log-viewer-panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n background: var(--mj-bg-surface);\n min-height: 400px;\n}\n\n@media (max-width: 767px) {\n .log-viewer-panel {\n min-height: 350px;\n }\n}\n\n/* Code editor keeps its dark theme for readability (intentionally hardcoded for code syntax) */\n.log-content {\n flex: 1;\n overflow: hidden;\n min-height: 300px;\n height: 100%;\n position: relative;\n background: var(--mj-text-primary);\n color: var(--mj-border-strong);\n}\n\n.log-content ::ng-deep .cm-editor {\n height: 100%;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n font-size: 0.875rem;\n}\n\n.log-content ::ng-deep .cm-scroller {\n font-family: inherit;\n}\n\n.log-content ::ng-deep .cm-content {\n background: var(--mj-text-primary);\n color: var(--mj-border-strong);\n}\n\n.log-content ::ng-deep .cm-gutters {\n background: var(--mj-text-primary);\n color: var(--mj-text-disabled);\n border-right: 1px solid var(--mj-text-secondary);\n}\n\n.log-content ::ng-deep .cm-activeLineGutter {\n background: var(--mj-text-primary);\n}\n\n.log-content ::ng-deep .cm-activeLine {\n background: rgba(255, 255, 255, 0.04);\n}\n\n/* Expanded Log Viewer */\n.log-viewer-panel.expanded {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n border-radius: 0;\n margin: 0;\n max-height: none;\n height: 100vh;\n animation: expandIn 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.log-viewer-panel.expanded .panel-header {\n border-radius: 0;\n}\n\n.log-viewer-panel.expanded .log-content {\n max-height: calc(100vh - 60px);\n min-height: calc(100vh - 60px);\n}\n\n/* -----------------------------------------------------------------------------\n Empty State Override - Different icon.warning styling\n ----------------------------------------------------------------------------- */\n.empty-state .empty-icon.warning {\n color: var(--mj-status-warning);\n}\n\n.empty-state .empty-subtext {\n max-width: 400px;\n}\n\n/* -----------------------------------------------------------------------------\n Info Box\n ----------------------------------------------------------------------------- */\n.info-box {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n padding: 1.5rem;\n margin-top: 1.5rem;\n text-align: left;\n max-width: 500px;\n border: 1px solid var(--mj-border-default);\n}\n\n.info-box h4 {\n margin: 0 0 1rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.info-box ol {\n margin: 0;\n padding-left: 1.25rem;\n font-size: 1rem;\n color: var(--mj-text-primary);\n}\n\n.info-box ol li {\n margin-bottom: 0.5rem;\n}\n\n.info-box code {\n background: var(--mj-bg-surface-active);\n padding: 0.125rem 0.5rem;\n border-radius: var(--mj-radius-sm);\n font-size: 0.8125rem;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n color: var(--mj-text-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Loading Container Override\n ----------------------------------------------------------------------------- */\n.loading-container {\n min-height: 300px;\n}\n\n.loading-text {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin-top: 1rem;\n}\n\n/* -----------------------------------------------------------------------------\n Modal Dialog Overrides - SQL Logging has its own modal patterns\n ----------------------------------------------------------------------------- */\n.modal-backdrop {\n background: var(--mj-bg-overlay);\n}\n\n.modal-dialog {\n width: 90%;\n display: flex;\n flex-direction: column;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.modal-dialog.modal-large {\n max-width: 700px;\n}\n\n/* Fullscreen mode */\n.modal-dialog.fullscreen {\n max-width: 100vw;\n width: 100vw;\n max-height: 100vh;\n height: 100vh;\n border-radius: 0;\n margin: 0;\n}\n\n@media (max-width: 639px) {\n .modal-dialog {\n width: 95%;\n max-height: 85vh;\n border-radius: var(--mj-radius-2xl);\n }\n\n .modal-dialog.fullscreen {\n border-radius: 0;\n max-height: 100vh;\n }\n}\n\n.modal-header {\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-header {\n padding: 1rem 1.25rem;\n }\n}\n\n/* Modal Header Actions */\n.modal-header-actions {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n flex-shrink: 0;\n}\n\n.modal-action-btn {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.125rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.modal-action-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-action-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.modal-body {\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n flex: 1;\n}\n\n@media (max-width: 639px) {\n .modal-body {\n padding: 1rem 1.25rem;\n }\n}\n\n.modal-footer {\n justify-content: flex-end;\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-footer {\n padding: 1rem 1.25rem;\n }\n\n .modal-footer .btn-primary,\n .modal-footer .btn-secondary {\n width: 100%;\n justify-content: center;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Form Elements\n ----------------------------------------------------------------------------- */\n.form-group {\n margin-bottom: 1.5rem;\n}\n\n.form-label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n margin-bottom: 0.5rem;\n}\n\n.form-input,\n.form-select,\n.form-textarea {\n width: 100%;\n min-height: 44px;\n padding: 0.875rem 1rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n font-size: 1rem;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.form-input:hover,\n.form-select:hover,\n.form-textarea:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.form-input:focus,\n.form-select:focus,\n.form-textarea:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.form-input::placeholder,\n.form-textarea::placeholder {\n color: var(--mj-text-secondary);\n opacity: 0.7;\n}\n\n.form-select {\n cursor: pointer;\n}\n\n.form-hint {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin-top: 0.375rem;\n}\n\n.form-checkboxes {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.checkbox-label {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n font-size: 1rem;\n color: var(--mj-text-primary);\n cursor: pointer;\n min-height: 44px;\n padding: 0.25rem 0;\n}\n\n.checkbox-label input[type=\"checkbox\"] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n/* Form Section */\n.form-section {\n margin-top: 1.5rem;\n padding: 1.25rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n background: var(--mj-bg-surface-sunken);\n}\n\n.form-section-title {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n margin: 0 0 1rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.form-section-title i {\n color: var(--mj-brand-primary);\n font-size: 1.125rem;\n}\n\n.form-textarea {\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n resize: vertical;\n min-height: 100px;\n}\n\n/* -----------------------------------------------------------------------------\n Confirmation Dialog\n ----------------------------------------------------------------------------- */\n.confirm-dialog {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 420px;\n width: 90%;\n padding: 2rem;\n text-align: center;\n animation: dialogBounce 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n@media (max-width: 639px) {\n .confirm-dialog {\n padding: 1.5rem;\n border-radius: var(--mj-radius-2xl);\n }\n}\n\n.confirm-dialog-icon {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: var(--mj-status-warning-bg);\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 1.5rem;\n}\n\n.confirm-dialog-icon i {\n font-size: 1.75rem;\n color: var(--mj-status-warning-text);\n}\n\n.confirm-dialog-content {\n margin-bottom: 1.5rem;\n}\n\n.confirm-dialog-title {\n margin: 0 0 0.75rem 0;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.confirm-dialog-message {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n}\n\n.confirm-dialog-message strong {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n.confirm-dialog-details {\n display: block;\n margin-top: 0.75rem;\n padding: 0.75rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-md);\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n\n.confirm-dialog-actions {\n display: flex;\n gap: 0.75rem;\n justify-content: center;\n}\n\n@media (max-width: 639px) {\n .confirm-dialog-actions {\n flex-direction: column-reverse;\n }\n\n .confirm-dialog-actions .btn-danger,\n .confirm-dialog-actions .btn-secondary {\n width: 100%;\n justify-content: center;\n }\n}\n\n.confirm-dialog-actions .btn-danger {\n min-width: 140px;\n}\n\n.confirm-dialog-actions .btn-secondary {\n min-width: 100px;\n}\n\n/* -----------------------------------------------------------------------------\n SQL-Logging-specific Animations\n ----------------------------------------------------------------------------- */\n@keyframes expandIn {\n from {\n transform: scale(0.95);\n opacity: 0;\n }\n to {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@keyframes dialogBounce {\n 0% {\n transform: scale(0.9) translateY(10px);\n opacity: 0;\n }\n 70% {\n transform: scale(1.02) translateY(-5px);\n }\n 100% {\n transform: scale(1) translateY(0);\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Screen Reader Only\n ----------------------------------------------------------------------------- */\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n"] }]
1284
+ args: [{ standalone: false, selector: 'mj-sql-logging', template: "<!--\n Interior chrome \u2014 sub-page of Admin's Monitoring left-nav shell. Single section\n (no L2 tab nav) so [toolbar] is empty; actions land in [actions]. See Section 10\n of plans/explorer-chrome-conventions.md.\n-->\n<mj-page-header-interior\n Role=\"region\"\n AriaLabel=\"SQL logging actions\"\n Title=\"SQL Logging\"\n Subtitle=\"Capture and download SQL statements executed by the API\">\n <div actions>\n <mj-refresh-button\n [Loading]=\"loading\"\n (Clicked)=\"loadActiveSessions()\">\n </mj-refresh-button>\n @if (isOwner && configEnabled) {\n <button mjButton\n variant=\"primary\"\n size=\"sm\"\n [disabled]=\"loading || activeSessions.length >= (sqlLoggingConfig?.maxActiveSessions || 5)\"\n (click)=\"openStartSessionDialog()\"\n [attr.aria-label]=\"'Start new SQL logging session' + (activeSessions.length >= (sqlLoggingConfig?.maxActiveSessions || 5) ? ' (maximum sessions reached)' : '')\">\n <i class=\"fa-solid fa-play\" aria-hidden=\"true\"></i>\n Start New Session\n </button>\n }\n </div>\n</mj-page-header-interior>\n\n<mj-page-body-interior>\n\n <!-- Stats Cards with Toggle -->\n @if (isOwner && configEnabled) {\n <div class=\"stats-toggle-container\">\n <!-- Toggle Button -->\n <button\n class=\"stats-toggle-button\"\n [class.expanded]=\"showStats\"\n (click)=\"showStats = !showStats\"\n [attr.aria-expanded]=\"showStats\"\n aria-controls=\"stats-grid-content\"\n >\n <div class=\"stats-toggle-left\">\n <div class=\"stats-toggle-icon\">\n <i class=\"fa-solid fa-chart-line\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"stats-toggle-text\">\n <h3 class=\"stats-toggle-title\">Statistics</h3>\n <p class=\"stats-toggle-subtitle\">View session statistics and metrics</p>\n </div>\n </div>\n <i class=\"fa-solid fa-chevron-down stats-toggle-arrow\" aria-hidden=\"true\"></i>\n </button>\n\n <!-- Stats Grid (Collapsible) -->\n <div\n id=\"stats-grid-content\"\n class=\"stats-grid\"\n [class.visible]=\"showStats\"\n role=\"region\"\n aria-label=\"SQL logging statistics\"\n >\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-status\">\n <i class=\"fa-solid fa-power-off\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" [attr.aria-label]=\"'Status: ' + (configEnabled ? 'Enabled' : 'Disabled')\">\n {{ configEnabled ? \"Enabled\" : \"Disabled\" }}\n </div>\n <div class=\"stat-label\">Status</div>\n </div>\n </div>\n\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-active\">\n <i class=\"fa-solid fa-play-circle\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" [attr.aria-label]=\"activeSessions.length + ' active sessions'\">\n {{ activeSessions.length }}\n </div>\n <div class=\"stat-label\">Active Sessions</div>\n </div>\n </div>\n\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-limit\">\n <i class=\"fa-solid fa-gauge-high\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" [attr.aria-label]=\"(sqlLoggingConfig?.maxActiveSessions || 5) + ' maximum sessions allowed'\">\n {{ sqlLoggingConfig?.maxActiveSessions || 5 }}\n </div>\n <div class=\"stat-label\">Max Sessions</div>\n </div>\n </div>\n\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-total\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" [attr.aria-label]=\"getTotalStatementCount() + ' total SQL statements captured'\">\n {{ getTotalStatementCount() }}\n </div>\n <div class=\"stat-label\">Total Statements</div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- Loading State -->\n @if (loading && !activeSessions.length) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading SQL logging configuration...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Content Area -->\n @if (!loading || activeSessions.length > 0) {\n <div class=\"content-area\">\n @if (!isOwner) {\n <!-- Not authorized -->\n <div class=\"empty-state\" role=\"alert\">\n <i class=\"fa-solid fa-lock empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">Access Denied</p>\n <p class=\"empty-subtext\">SQL logging requires Owner privileges. Please contact your system administrator for access.</p>\n <button mjButton variant=\"secondary\" size=\"md\" (click)=\"refreshUserPermissions()\" style=\"margin-top: 1rem\" aria-label=\"Refresh user permissions\">\n <i class=\"fa-solid fa-sync\" aria-hidden=\"true\"></i>\n Refresh Permissions\n </button>\n </div>\n } @else if (!configEnabled) {\n <!-- Not enabled in config -->\n <div class=\"empty-state\" role=\"alert\">\n <i class=\"fa-solid fa-exclamation-triangle empty-icon warning\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">SQL Logging Disabled</p>\n <p class=\"empty-subtext\">SQL logging is not enabled in the server configuration.</p>\n <div class=\"info-box\">\n <h4>To enable SQL logging:</h4>\n <ol>\n <li>Set <code>sqlLogging.enabled = true</code> in mj.config.cjs</li>\n <li>Restart the MJ API server</li>\n <li>Refresh this page</li>\n </ol>\n </div>\n </div>\n } @else if (activeSessions.length === 0) {\n <!-- No active sessions -->\n <div class=\"empty-state\" role=\"status\">\n <i class=\"fa-solid fa-file-code empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">No Active Sessions</p>\n <p class=\"empty-subtext\">Start a new SQL logging session to begin capturing SQL statements.</p>\n <button mjButton variant=\"primary\" size=\"md\" (click)=\"openStartSessionDialog()\" style=\"margin-top: 1rem\" aria-label=\"Start a new SQL logging session\">\n <i class=\"fa-solid fa-play\" aria-hidden=\"true\"></i>\n Start New Session\n </button>\n </div>\n } @else {\n <!-- Sessions layout -->\n <div class=\"sessions-layout\">\n <!-- Sessions panel -->\n <div class=\"sessions-panel\" role=\"region\" aria-label=\"Active sessions list\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">Active Sessions</h3>\n @if (activeSessions.length > 0) {\n <button mjButton\n variant=\"danger\"\n size=\"sm\"\n (click)=\"openStopAllSessionsConfirm()\"\n [disabled]=\"loading\"\n aria-label=\"Stop all active sessions\"\n >\n <i class=\"fa-solid fa-stop\" aria-hidden=\"true\"></i>\n Stop All\n </button>\n }\n </div>\n <div class=\"sessions-list\" role=\"list\" aria-label=\"SQL logging sessions\">\n @for (session of activeSessions; track session.id) {\n <div\n class=\"session-card\"\n [class.selected]=\"selectedSession?.id === session.id\"\n (click)=\"selectSession(session)\"\n role=\"listitem\"\n tabindex=\"0\"\n (keydown.enter)=\"selectSession(session)\"\n (keydown.space)=\"selectSession(session); $event.preventDefault()\"\n [attr.aria-label]=\"'Session: ' + session.sessionName + ', ' + session.statementCount + ' statements, duration ' + getSessionDuration(session.startTime)\"\n [attr.aria-selected]=\"selectedSession?.id === session.id\"\n >\n <div class=\"session-header\">\n <div class=\"session-info\">\n <h4 class=\"session-title\">{{ session.sessionName }}</h4>\n <div class=\"session-meta\">\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-clock\" aria-hidden=\"true\"></i>\n {{ getSessionDuration(session.startTime) }}\n </span>\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n {{ session.statementCount }} statements\n </span>\n </div>\n </div>\n <button mjButton\n variant=\"danger\"\n size=\"sm\"\n (click)=\"openStopSessionConfirm(session, $event)\"\n [attr.aria-label]=\"'Stop session ' + session.sessionName\"\n >\n <i class=\"fa-solid fa-stop\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"session-badges\">\n @if (session.filterByUserId) {\n <span class=\"badge badge-user\">\n <i class=\"fa-solid fa-user\" aria-hidden=\"true\"></i>\n User Filtered\n </span>\n }\n @if (session.options?.formatAsMigration) {\n <span class=\"badge badge-migration\">\n <i class=\"fa-solid fa-code-branch\" aria-hidden=\"true\"></i>\n Migration\n </span>\n }\n <span class=\"badge badge-type\">\n {{ session.options?.statementTypes || \"both\" }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Log viewer panel -->\n <div class=\"log-viewer-panel\" [class.expanded]=\"isLogViewerExpanded\" role=\"region\" aria-label=\"SQL log viewer\">\n @if (selectedSession) {\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">{{ selectedSession.sessionName }}</h3>\n <div class=\"panel-actions\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"autoRefresh\"\n aria-label=\"Enable auto-refresh\"\n />\n Auto-refresh\n </label>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"loadSessionLog(selectedSession)\"\n aria-label=\"Refresh log content\"\n >\n <i class=\"fa-solid fa-sync\" [class.fa-spin]=\"loading\" aria-hidden=\"true\"></i>\n </button>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"toggleLogViewerExpand()\"\n [attr.aria-label]=\"isLogViewerExpanded ? 'Collapse log viewer' : 'Expand log viewer to fullscreen'\"\n [attr.aria-expanded]=\"isLogViewerExpanded\"\n >\n <i class=\"fa-solid\" [class.fa-expand]=\"!isLogViewerExpanded\" [class.fa-compress]=\"isLogViewerExpanded\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"log-content\">\n <mj-code-editor\n [value]=\"logContent\"\n [readonly]=\"true\"\n [disabled]=\"true\"\n [language]=\"'sql'\"\n [setup]=\"'basic'\"\n [lineWrapping]=\"true\"\n [highlightWhitespace]=\"false\"\n style=\"height: 100%\"\n aria-label=\"SQL log content\"\n ></mj-code-editor>\n </div>\n } @else {\n <div class=\"empty-state\" role=\"status\">\n <i class=\"fa-solid fa-arrow-left empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">Select a Session</p>\n <p class=\"empty-subtext\">Choose a session from the list to view its SQL log.</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Start Session Dialog -->\n @if (showStartSessionDialog) {\n <div\n class=\"modal-backdrop\"\n (click)=\"showStartSessionDialog = false\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"start-session-dialog-title\"\n >\n <div class=\"modal-dialog modal-large\" [class.fullscreen]=\"isStartDialogFullscreen\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"start-session-dialog-title\">\n <i class=\"fa-solid fa-play\" aria-hidden=\"true\"></i>\n Start SQL Logging Session\n </h3>\n <div class=\"modal-header-actions\">\n <button\n class=\"modal-action-btn\"\n (click)=\"toggleStartDialogFullscreen()\"\n [attr.aria-label]=\"isStartDialogFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'\"\n type=\"button\"\n >\n <i class=\"fa-solid\" [class.fa-compress]=\"isStartDialogFullscreen\" [class.fa-expand]=\"!isStartDialogFullscreen\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"modal-close\" (click)=\"showStartSessionDialog = false\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"modal-body\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"session-name\">Session Name</label>\n <input\n type=\"text\"\n id=\"session-name\"\n class=\"form-input\"\n [(ngModel)]=\"newSessionOptions.sessionName\"\n placeholder=\"Enter a descriptive name for this session\"\n aria-describedby=\"session-name-hint\"\n />\n <div id=\"session-name-hint\" class=\"form-hint\">A descriptive name to identify this logging session</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"file-name\">File Name</label>\n <input\n type=\"text\"\n id=\"file-name\"\n class=\"form-input\"\n [(ngModel)]=\"newSessionOptions.fileName\"\n placeholder=\"sql-log-2024-01-01.sql\"\n aria-describedby=\"file-name-hint\"\n />\n <div id=\"file-name-hint\" class=\"form-hint\">The SQL log will be saved to this file</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"statement-types\">Statement Types</label>\n <select\n id=\"statement-types\"\n class=\"form-select\"\n [(ngModel)]=\"newSessionOptions.statementTypes\"\n aria-describedby=\"statement-types-hint\"\n >\n @for (option of statementTypeOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.text }}</option>\n }\n </select>\n <div id=\"statement-types-hint\" class=\"form-hint\">Filter which types of SQL statements to capture</div>\n </div>\n\n <div class=\"form-checkboxes\" role=\"group\" aria-label=\"Session options\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"newSessionOptions.filterToCurrentUser\" />\n Filter to my SQL statements only\n </label>\n\n\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"newSessionOptions.formatAsMigration\" />\n Format as migration file\n </label>\n\n\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"newSessionOptions.prettyPrint\" />\n Pretty print SQL statements\n </label>\n </div>\n\n <!-- SQL Pattern Filtering Section -->\n <div class=\"form-section\">\n <h4 class=\"form-section-title\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n SQL Pattern Filtering\n </h4>\n\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"filter-type\">Filter Mode</label>\n <select\n id=\"filter-type\"\n class=\"form-select\"\n [(ngModel)]=\"newSessionOptions.filterType\"\n aria-describedby=\"filter-type-hint\"\n >\n @for (option of filterTypeOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.text }}</option>\n }\n </select>\n <div id=\"filter-type-hint\" class=\"form-hint\">Exclude: Skip SQL matching any pattern. Include: Only log SQL matching a pattern.</div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"filter-patterns\">Filter Patterns (one per line or comma-separated)</label>\n <textarea\n id=\"filter-patterns\"\n class=\"form-textarea\"\n [(ngModel)]=\"newSessionOptions.filterPatterns\"\n rows=\"4\"\n placeholder=\"Examples:&#10;*AIPrompt*&#10;/spCreate.*Run/i&#10;SELECT * FROM vwMetadata\"\n aria-describedby=\"filter-patterns-hint\"\n ></textarea>\n <div id=\"filter-patterns-hint\" class=\"form-hint\">Supports wildcards (*) and regex (/pattern/flags). Example: *spCreate* matches any SP starting with spCreate.</div>\n </div>\n </div>\n\n <!-- Advanced Options Section -->\n <div class=\"form-section\">\n <h4 class=\"form-section-title\">\n <i class=\"fa-solid fa-cog\" aria-hidden=\"true\"></i>\n Advanced Options\n </h4>\n\n @if (newSessionOptions.formatAsMigration) {\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"default-schema\">Default Schema Name</label>\n <input\n type=\"text\"\n id=\"default-schema\"\n class=\"form-input\"\n [(ngModel)]=\"newSessionOptions.defaultSchemaName\"\n placeholder=\"__mj\"\n aria-describedby=\"default-schema-hint\"\n />\n <div id=\"default-schema-hint\" class=\"form-hint\">Schema name to replace with $&#123;flyway:defaultSchema&#125; placeholder.</div>\n </div>\n }\n\n <div class=\"form-checkboxes\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" [(ngModel)]=\"newSessionOptions.verboseOutput\" />\n Verbose Debug Output\n </label>\n <div class=\"form-hint\" style=\"margin-left: 1.75rem\">Log detailed filter decisions to server console (for debugging).</div>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button mjButton variant=\"primary\" size=\"md\" (click)=\"startNewSession()\" [disabled]=\"loading\" aria-label=\"Start the SQL logging session\">\n @if (loading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Starting...\n } @else {\n <i class=\"fa-solid fa-play\" aria-hidden=\"true\"></i>\n Start Session\n }\n </button>\n <button mjButton variant=\"secondary\" size=\"md\" (click)=\"showStartSessionDialog = false\" aria-label=\"Cancel and close dialog\">Cancel</button>\n </div>\n </div>\n </div>\n }\n\n <!-- Stop Session Confirmation Dialog -->\n @if (showStopConfirmDialog) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelStopConfirm()\"\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby=\"stop-dialog-title\"\n aria-describedby=\"stop-dialog-desc\"\n >\n <div class=\"confirm-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"confirm-dialog-icon\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"confirm-dialog-content\">\n <h3 class=\"confirm-dialog-title\" id=\"stop-dialog-title\">\n @if (isStoppingAll) {\n Stop All Sessions?\n } @else {\n Stop Session?\n }\n </h3>\n <p class=\"confirm-dialog-message\" id=\"stop-dialog-desc\">\n @if (isStoppingAll) {\n Are you sure you want to stop <strong>all {{ activeSessions.length }} active</strong> SQL logging sessions? This action cannot be undone.\n } @else if (sessionToStop) {\n Are you sure you want to stop the session <strong>\"{{ sessionToStop.sessionName }}\"</strong>?\n <span class=\"confirm-dialog-details\"> This session has captured {{ sessionToStop.statementCount }} SQL statements. </span>\n }\n </p>\n </div>\n <div class=\"confirm-dialog-actions\">\n <button mjButton variant=\"danger\" size=\"md\" (click)=\"confirmStopSession()\" [disabled]=\"loading\" [attr.aria-label]=\"isStoppingAll ? 'Confirm stop all sessions' : 'Confirm stop session'\">\n @if (loading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Stopping...\n } @else {\n <i class=\"fa-solid fa-stop\" aria-hidden=\"true\"></i>\n @if (isStoppingAll) {\n Stop All Sessions\n } @else {\n Stop Session\n }\n }\n </button>\n <button mjButton variant=\"secondary\" size=\"md\" (click)=\"cancelStopConfirm()\" [disabled]=\"loading\" aria-label=\"Cancel and keep sessions running\">Cancel</button>\n </div>\n </div>\n </div>\n }\n</mj-page-body-interior>\n", styles: ["/* =============================================================================\n Shared Admin Patterns - MJ Design System\n Common styles shared across all admin settings components.\n Component-specific CSS files override these values where needed.\n ============================================================================= */\n\n/* -----------------------------------------------------------------------------\n Host & Container\n ----------------------------------------------------------------------------- */\n:host {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Sticky Header\n ----------------------------------------------------------------------------- */\n.sticky-header {\n flex-shrink: 0;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n/* -----------------------------------------------------------------------------\n Scrollable Content\n ----------------------------------------------------------------------------- */\n.scrollable-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .scrollable-content {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .scrollable-content {\n padding: 2rem 2.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons (In Sticky Header)\n ----------------------------------------------------------------------------- */\n.action-buttons {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .action-buttons {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Statistics Cards Grid - Static Display (Non-interactive)\n ----------------------------------------------------------------------------- */\n.mj-grid-4 {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 1rem 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4 {\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1rem 1.5rem;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4 {\n gap: 1rem;\n }\n}\n\n/* Static Card - No hover effects */\n.mj-card {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\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/* -----------------------------------------------------------------------------\n Stat Icon Containers\n ----------------------------------------------------------------------------- */\n.stat-icon {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\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.stat-icon-total {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-active {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\n/* -----------------------------------------------------------------------------\n Stat Content Typography\n ----------------------------------------------------------------------------- */\n.stat-content {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content .stat-value {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content .stat-value {\n font-size: 2rem;\n }\n}\n\n.stat-content .stat-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\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 flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.75rem;\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .filters-section {\n margin: 0 1.5rem 1rem 1.5rem;\n padding: 1rem 1.25rem;\n }\n}\n\n.filters-row {\n display: flex;\n gap: 1rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (min-width: 768px) {\n .filters-row {\n gap: 1.5rem;\n }\n}\n\n.mj-filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.mj-filter-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-buttons {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-full);\n padding: 4px;\n gap: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Search Input\n ----------------------------------------------------------------------------- */\n.mj-search {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n@media (min-width: 640px) {\n .mj-search {\n min-width: 280px;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-search {\n min-width: 400px;\n max-width: 600px;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search {\n min-width: 500px;\n max-width: 800px;\n }\n}\n\n.mj-search .mj-search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-icon {\n left: 1.25rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search .mj-search-input {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n font-size: 1rem;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-input {\n padding: 1rem 1.25rem 1rem 3.25rem;\n font-size: 1.0625rem;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search .mj-search-input {\n padding: 1.125rem 1.5rem 1.125rem 3.5rem;\n }\n}\n\n.mj-search .mj-search-input::placeholder {\n color: var(--mj-text-secondary);\n}\n\n.mj-search .mj-search-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search .mj-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--mj-bg-page);\n}\n\n.mj-search:focus-within .mj-search-icon {\n color: var(--mj-brand-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Content Area\n ----------------------------------------------------------------------------- */\n.content-area {\n flex: 1 1 auto;\n overflow: visible;\n position: relative;\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-xl);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem;\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .content-area {\n padding: 1.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Expand Button\n ----------------------------------------------------------------------------- */\n.expand-btn {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--mj-radius-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.expand-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.expand-btn i {\n transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* -----------------------------------------------------------------------------\n Status Badge\n ----------------------------------------------------------------------------- */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.status-badge.status-active {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success);\n}\n\n.status-badge.status-inactive {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n}\n\n.status-badge i {\n font-size: 0.625rem;\n}\n\n/* -----------------------------------------------------------------------------\n Mobile Actions Bar\n ----------------------------------------------------------------------------- */\n.mobile-actions-bar {\n display: none;\n}\n\n.mobile-action-buttons {\n display: flex;\n gap: 0.5rem;\n}\n\n/* -----------------------------------------------------------------------------\n Empty State\n ----------------------------------------------------------------------------- */\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state .empty-icon {\n font-size: 4rem;\n color: var(--mj-border-default);\n margin-bottom: 1.5rem;\n}\n\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state .empty-subtext {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Loading State\n ----------------------------------------------------------------------------- */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n/* -----------------------------------------------------------------------------\n Error State\n ----------------------------------------------------------------------------- */\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container .error-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container .error-icon {\n font-size: 3.5rem;\n color: var(--mj-status-error);\n margin-bottom: 1rem;\n}\n\n.error-container .error-message {\n font-size: 1.0625rem;\n color: var(--mj-text-primary);\n margin: 0 0 1.5rem 0;\n}\n\n/* -----------------------------------------------------------------------------\n Modal Dialog\n ----------------------------------------------------------------------------- */\n.modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: fadeIn 0.2s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-dialog {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.modal-header .modal-close {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.modal-header .modal-close:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n\n.modal-body p {\n font-size: 1rem;\n color: var(--mj-text-primary);\n margin: 0 0 1rem 0;\n line-height: 1.5;\n}\n\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (max-width: 639px) {\n .modal-dialog {\n width: 95%;\n max-height: 85vh;\n }\n\n .modal-header {\n padding: 1rem;\n }\n\n .modal-header .modal-title {\n font-size: 1.125rem;\n }\n\n .modal-body {\n padding: 1rem;\n }\n\n .modal-footer {\n padding: 1rem;\n flex-direction: column;\n }\n\n}\n\n/* The legacy \"MJ Button System\" rule block (.mj-btn / .mj-btn-primary /\n .mj-btn-secondary / .mj-btn-ghost / .mj-btn-danger / .mj-btn-sm /\n .mj-btn-icon-only / .mj-btn-icon-mobile) was removed 2026-05-19. These\n rules pre-dated the mjButton directive standardization (the directive\n uses BEM modifiers like .mj-btn--primary, single-dash names like\n .mj-btn-primary don't match it anyway). The base .mj-btn rule WAS active\n though \u2014 its component-scoped specificity outranked button.scss's global\n directive styles, so admin sub-page buttons rendered pill-shaped + 44px\n regardless of the variant/size requested via mjButton inputs. Removing the\n rule lets every sub-page fall back to the directive's intended look. */\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(--mj-border-default);\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n border-radius: var(--mj-radius-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(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.filter-button:active {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.filter-button i {\n font-size: 1rem;\n}\n\n/* -----------------------------------------------------------------------------\n Filter Modal (Mobile Bottom Sheet)\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(--mj-bg-page);\n border-radius: var(--mj-radius-2xl) var(--mj-radius-2xl) 0 0;\n box-shadow: var(--mj-shadow-2xl);\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(--mj-border-default);\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(--mj-text-primary);\n margin: 0;\n}\n\n.filter-modal-title i {\n color: var(--mj-brand-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(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-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(--mj-brand-primary);\n color: var(--mj-brand-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(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\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(--mj-text-primary);\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(--mj-bg-surface-sunken);\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\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(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-option.selected {\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-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(--mj-brand-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(--mj-text-primary);\n}\n\n.filter-option.selected .filter-option-label {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* -----------------------------------------------------------------------------\n Utility Classes\n ----------------------------------------------------------------------------- */\n.text-danger {\n color: var(--mj-status-error);\n}\n\n.text-warning {\n color: var(--mj-color-warning-500);\n}\n\n.text-success {\n color: var(--mj-status-success);\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 transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\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 Accessibility: Focus Indicators\n ----------------------------------------------------------------------------- */\n.mj-search-input:focus-visible,\nbutton:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Reduced Motion\n ----------------------------------------------------------------------------- */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n", "/* =============================================================================\n SQL Logging Component - Component-Specific Styles\n Shared patterns are in ../shared/styles/_admin-patterns.css\n ============================================================================= */\n\n/*\n Layout \u2014 host is flex column (from _admin-patterns.css :host).\n <mj-page-header-interior> sits pinned at the top; .scrollable-content\n (also from _admin-patterns) fills the rest with responsive padding.\n Buttons in this component use the mjButton directive \u2014 see Section 10\n of plans/explorer-chrome-conventions.md.\n*/\n\n/* Small-viewport adjustments for the collapsible stats toggle. */\n@media (max-width: 639px) {\n .stats-toggle-button {\n padding: 0.875rem 1rem;\n }\n\n .stats-toggle-icon {\n width: 40px;\n height: 40px;\n font-size: 1rem;\n }\n\n .stats-toggle-title {\n font-size: 0.9375rem;\n }\n\n .stats-toggle-subtitle {\n font-size: 0.75rem;\n }\n\n .stats-toggle-arrow {\n font-size: 1.125rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Statistics Grid - Collapsible Cards\n ----------------------------------------------------------------------------- */\n.stats-toggle-container {\n margin-bottom: 1.5rem;\n}\n\n.stats-toggle-button {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.stats-toggle-button:hover {\n background: var(--mj-bg-surface-active);\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.stats-toggle-button.expanded {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-accent-subtle);\n margin-bottom: 1rem;\n}\n\n.stats-toggle-left {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.stats-toggle-icon {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n.stats-toggle-button.expanded .stats-toggle-icon {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.stats-toggle-text {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.stats-toggle-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.stats-toggle-button.expanded .stats-toggle-title {\n color: var(--mj-brand-primary);\n}\n\n.stats-toggle-subtitle {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.stats-toggle-arrow {\n font-size: 1.25rem;\n color: var(--mj-text-secondary);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.stats-toggle-button.expanded .stats-toggle-arrow {\n transform: rotate(180deg);\n color: var(--mj-brand-primary);\n}\n\n.stats-grid {\n display: grid;\n grid-template-columns: 1fr;\n gap: 0.75rem;\n width: 100%;\n overflow: hidden;\n max-height: 0;\n opacity: 0;\n transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.stats-grid.visible {\n max-height: 1000px;\n opacity: 1;\n margin-bottom: 1.5rem;\n}\n\n@media (min-width: 640px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .stats-toggle-button {\n display: none;\n }\n\n .stats-grid {\n max-height: none;\n opacity: 1;\n margin-bottom: 1.5rem;\n gap: 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .stats-grid {\n grid-template-columns: repeat(4, 1fr);\n gap: 1.5rem;\n }\n}\n\n@media (min-width: 1440px) {\n .stats-grid {\n gap: 2rem;\n }\n}\n\n/* Static Display Card */\n.stat-card {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1.25rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\n cursor: default;\n}\n\n/* Stat Icon Override - Different sizes */\n.stat-icon {\n width: 56px;\n height: 56px;\n font-size: 1.5rem;\n}\n\n@media (max-width: 639px) {\n .stat-icon {\n width: 48px;\n height: 48px;\n font-size: 1.25rem;\n }\n}\n\n.stat-icon-status {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n\n.stat-icon-active {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-limit {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n\n.stat-icon-total {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success);\n}\n\n/* Stat Value Override for mobile */\n@media (max-width: 639px) {\n .stat-content .stat-value {\n font-size: 1.5rem;\n font-weight: 700;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Content Area Override - Different styling\n ----------------------------------------------------------------------------- */\n.content-area {\n flex: 1;\n min-height: 0;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n box-shadow: none;\n}\n\n@media (min-width: 640px) {\n .content-area {\n padding: 1.25rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Sessions Layout - Two-panel design\n ----------------------------------------------------------------------------- */\n.sessions-layout {\n display: flex;\n gap: 1.5rem;\n min-height: 400px;\n overflow: visible;\n}\n\n@media (max-width: 767px) {\n .sessions-layout {\n flex-direction: column;\n gap: 1rem;\n min-height: auto;\n }\n}\n\n@media (min-width: 768px) and (max-width: 1023px) {\n .sessions-layout {\n gap: 1.25rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Sessions Panel\n ----------------------------------------------------------------------------- */\n.sessions-panel {\n flex: 0 0 380px;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n background: var(--mj-bg-surface);\n max-height: 600px;\n}\n\n@media (max-width: 767px) {\n .sessions-panel {\n flex: none;\n max-height: 350px;\n }\n}\n\n@media (min-width: 768px) and (max-width: 1023px) {\n .sessions-panel {\n flex: 0 0 320px;\n }\n}\n\n@media (min-width: 1440px) {\n .sessions-panel {\n flex: 0 0 420px;\n }\n}\n\n.panel-header {\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-shrink: 0;\n gap: 0.5rem;\n}\n\n@media (max-width: 639px) {\n .panel-header {\n padding: 0.75rem;\n flex-wrap: wrap;\n }\n}\n\n.panel-header .panel-title {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n flex-shrink: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (max-width: 639px) {\n .panel-header .panel-title {\n font-size: 0.875rem;\n max-width: 50%;\n }\n}\n\n.panel-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .panel-actions {\n gap: 0.25rem;\n }\n\n .panel-actions .checkbox-label {\n font-size: 0;\n gap: 0;\n min-height: 36px;\n padding: 0;\n }\n\n .panel-actions .checkbox-label::after {\n content: \"Auto\";\n font-size: 0.75rem;\n margin-left: 0.25rem;\n }\n}\n\n.sessions-list {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n min-height: 0;\n position: relative;\n padding: 0.75rem;\n}\n\n/* -----------------------------------------------------------------------------\n Session Cards\n ----------------------------------------------------------------------------- */\n.session-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 1rem;\n margin-bottom: 0.75rem;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.session-card:last-child {\n margin-bottom: 0;\n}\n\n.session-card:hover {\n box-shadow: var(--mj-shadow-sm);\n border-color: var(--mj-brand-primary);\n}\n\n.session-card.selected {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-brand-accent-subtle);\n}\n\n.session-card:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.session-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.75rem;\n}\n\n.session-info {\n flex: 1;\n min-width: 0;\n}\n\n.session-info .session-title {\n margin: 0 0 0.5rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.session-meta {\n display: flex;\n gap: 1rem;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n flex-wrap: wrap;\n}\n\n.session-meta .meta-item {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.session-badges {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n margin-top: 0.5rem;\n}\n\n/* -----------------------------------------------------------------------------\n Badges - Chips\n ----------------------------------------------------------------------------- */\n.badge {\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n}\n\n.badge-user {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.badge-migration {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success);\n}\n\n.badge-type {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning);\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons (Icon buttons)\n ----------------------------------------------------------------------------- */\n.action-btn {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n border-radius: var(--mj-radius-full);\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: flex;\n align-items: center;\n justify-content: center;\n}\n\n.action-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.action-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.action-btn-danger:hover {\n background: var(--mj-status-error);\n color: var(--mj-brand-on-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Log Viewer Panel\n ----------------------------------------------------------------------------- */\n.log-viewer-panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n background: var(--mj-bg-surface);\n min-height: 400px;\n}\n\n@media (max-width: 767px) {\n .log-viewer-panel {\n min-height: 350px;\n }\n}\n\n/* Code editor keeps its dark theme for readability (intentionally hardcoded for code syntax) */\n.log-content {\n flex: 1;\n overflow: hidden;\n min-height: 300px;\n height: 100%;\n position: relative;\n background: var(--mj-text-primary);\n color: var(--mj-border-strong);\n}\n\n.log-content ::ng-deep .cm-editor {\n height: 100%;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n font-size: 0.875rem;\n}\n\n.log-content ::ng-deep .cm-scroller {\n font-family: inherit;\n}\n\n.log-content ::ng-deep .cm-content {\n background: var(--mj-text-primary);\n color: var(--mj-border-strong);\n}\n\n.log-content ::ng-deep .cm-gutters {\n background: var(--mj-text-primary);\n color: var(--mj-text-disabled);\n border-right: 1px solid var(--mj-text-secondary);\n}\n\n.log-content ::ng-deep .cm-activeLineGutter {\n background: var(--mj-text-primary);\n}\n\n.log-content ::ng-deep .cm-activeLine {\n background: rgba(255, 255, 255, 0.04);\n}\n\n/* Expanded Log Viewer */\n.log-viewer-panel.expanded {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n border-radius: 0;\n margin: 0;\n max-height: none;\n height: 100vh;\n animation: expandIn 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.log-viewer-panel.expanded .panel-header {\n border-radius: 0;\n}\n\n.log-viewer-panel.expanded .log-content {\n max-height: calc(100vh - 60px);\n min-height: calc(100vh - 60px);\n}\n\n/* -----------------------------------------------------------------------------\n Empty State Override - Different icon.warning styling\n ----------------------------------------------------------------------------- */\n.empty-state .empty-icon.warning {\n color: var(--mj-status-warning);\n}\n\n.empty-state .empty-subtext {\n max-width: 400px;\n}\n\n/* -----------------------------------------------------------------------------\n Info Box\n ----------------------------------------------------------------------------- */\n.info-box {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n padding: 1.5rem;\n margin-top: 1.5rem;\n text-align: left;\n max-width: 500px;\n border: 1px solid var(--mj-border-default);\n}\n\n.info-box h4 {\n margin: 0 0 1rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.info-box ol {\n margin: 0;\n padding-left: 1.25rem;\n font-size: 1rem;\n color: var(--mj-text-primary);\n}\n\n.info-box ol li {\n margin-bottom: 0.5rem;\n}\n\n.info-box code {\n background: var(--mj-bg-surface-active);\n padding: 0.125rem 0.5rem;\n border-radius: var(--mj-radius-sm);\n font-size: 0.8125rem;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n color: var(--mj-text-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Loading Container Override\n ----------------------------------------------------------------------------- */\n.loading-container {\n min-height: 300px;\n}\n\n.loading-text {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin-top: 1rem;\n}\n\n/* -----------------------------------------------------------------------------\n Modal Dialog Overrides - SQL Logging has its own modal patterns\n ----------------------------------------------------------------------------- */\n.modal-backdrop {\n background: var(--mj-bg-overlay);\n}\n\n.modal-dialog {\n width: 90%;\n display: flex;\n flex-direction: column;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.modal-dialog.modal-large {\n max-width: 700px;\n}\n\n/* Fullscreen mode */\n.modal-dialog.fullscreen {\n max-width: 100vw;\n width: 100vw;\n max-height: 100vh;\n height: 100vh;\n border-radius: 0;\n margin: 0;\n}\n\n@media (max-width: 639px) {\n .modal-dialog {\n width: 95%;\n max-height: 85vh;\n border-radius: var(--mj-radius-2xl);\n }\n\n .modal-dialog.fullscreen {\n border-radius: 0;\n max-height: 100vh;\n }\n}\n\n.modal-header {\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-header {\n padding: 1rem 1.25rem;\n }\n}\n\n/* Modal Header Actions */\n.modal-header-actions {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n flex-shrink: 0;\n}\n\n.modal-action-btn {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.125rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.modal-action-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-action-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.modal-body {\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n flex: 1;\n}\n\n@media (max-width: 639px) {\n .modal-body {\n padding: 1rem 1.25rem;\n }\n}\n\n.modal-footer {\n justify-content: flex-end;\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-footer {\n padding: 1rem 1.25rem;\n }\n\n /* Stretch the action buttons to full width on small viewports. */\n .modal-footer button {\n width: 100%;\n justify-content: center;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Form Elements\n ----------------------------------------------------------------------------- */\n.form-group {\n margin-bottom: 1.5rem;\n}\n\n.form-label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n margin-bottom: 0.5rem;\n}\n\n.form-input,\n.form-select,\n.form-textarea {\n width: 100%;\n min-height: 44px;\n padding: 0.875rem 1rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n font-size: 1rem;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.form-input:hover,\n.form-select:hover,\n.form-textarea:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.form-input:focus,\n.form-select:focus,\n.form-textarea:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.form-input::placeholder,\n.form-textarea::placeholder {\n color: var(--mj-text-secondary);\n opacity: 0.7;\n}\n\n.form-select {\n cursor: pointer;\n}\n\n.form-hint {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin-top: 0.375rem;\n}\n\n.form-checkboxes {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.checkbox-label {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n font-size: 1rem;\n color: var(--mj-text-primary);\n cursor: pointer;\n min-height: 44px;\n padding: 0.25rem 0;\n}\n\n.checkbox-label input[type=\"checkbox\"] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n/* Form Section */\n.form-section {\n margin-top: 1.5rem;\n padding: 1.25rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n background: var(--mj-bg-surface-sunken);\n}\n\n.form-section-title {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n margin: 0 0 1rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.form-section-title i {\n color: var(--mj-brand-primary);\n font-size: 1.125rem;\n}\n\n.form-textarea {\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n resize: vertical;\n min-height: 100px;\n}\n\n/* -----------------------------------------------------------------------------\n Confirmation Dialog\n ----------------------------------------------------------------------------- */\n.confirm-dialog {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 420px;\n width: 90%;\n padding: 2rem;\n text-align: center;\n animation: dialogBounce 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n@media (max-width: 639px) {\n .confirm-dialog {\n padding: 1.5rem;\n border-radius: var(--mj-radius-2xl);\n }\n}\n\n.confirm-dialog-icon {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: var(--mj-status-warning-bg);\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 1.5rem;\n}\n\n.confirm-dialog-icon i {\n font-size: 1.75rem;\n color: var(--mj-status-warning-text);\n}\n\n.confirm-dialog-content {\n margin-bottom: 1.5rem;\n}\n\n.confirm-dialog-title {\n margin: 0 0 0.75rem 0;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.confirm-dialog-message {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n}\n\n.confirm-dialog-message strong {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n.confirm-dialog-details {\n display: block;\n margin-top: 0.75rem;\n padding: 0.75rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-md);\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n\n.confirm-dialog-actions {\n display: flex;\n gap: 0.75rem;\n justify-content: center;\n}\n\n@media (max-width: 639px) {\n .confirm-dialog-actions {\n flex-direction: column-reverse;\n }\n\n /* Stretch the action buttons to full width on small viewports. */\n .confirm-dialog-actions button {\n width: 100%;\n justify-content: center;\n }\n}\n\n/* -----------------------------------------------------------------------------\n SQL-Logging-specific Animations\n ----------------------------------------------------------------------------- */\n@keyframes expandIn {\n from {\n transform: scale(0.95);\n opacity: 0;\n }\n to {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@keyframes dialogBounce {\n 0% {\n transform: scale(0.9) translateY(10px);\n opacity: 0;\n }\n 70% {\n transform: scale(1.02) translateY(-5px);\n }\n 100% {\n transform: scale(1) translateY(0);\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Screen Reader Only\n ----------------------------------------------------------------------------- */\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n"] }]
1288
1285
  }], () => [{ type: i1.SharedService }, { type: i0.ChangeDetectorRef }], { onEscapeKey: [{
1289
1286
  type: HostListener,
1290
1287
  args: ['document:keydown.escape']