@memberjunction/ng-explorer-settings 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts +15 -1
  2. package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts.map +1 -1
  3. package/dist/lib/application-management/application-dialog/application-dialog.component.js +329 -190
  4. package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
  5. package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
  6. package/dist/lib/application-management/application-management.component.js +265 -184
  7. package/dist/lib/application-management/application-management.component.js.map +1 -1
  8. package/dist/lib/entity-permissions/entity-permissions.component.d.ts +1 -0
  9. package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
  10. package/dist/lib/entity-permissions/entity-permissions.component.js +369 -192
  11. package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
  12. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts.map +1 -1
  13. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +160 -143
  14. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
  15. package/dist/lib/module.d.ts +20 -25
  16. package/dist/lib/module.d.ts.map +1 -1
  17. package/dist/lib/module.js +20 -44
  18. package/dist/lib/module.js.map +1 -1
  19. package/dist/lib/notification-preferences/notification-preferences.component.d.ts +77 -0
  20. package/dist/lib/notification-preferences/notification-preferences.component.d.ts.map +1 -1
  21. package/dist/lib/notification-preferences/notification-preferences.component.js +153 -77
  22. package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
  23. package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts.map +1 -1
  24. package/dist/lib/role-management/role-dialog/role-dialog.component.js +93 -89
  25. package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
  26. package/dist/lib/role-management/role-management.component.d.ts +1 -0
  27. package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
  28. package/dist/lib/role-management/role-management.component.js +275 -158
  29. package/dist/lib/role-management/role-management.component.js.map +1 -1
  30. package/dist/lib/settings/settings.component.d.ts +54 -1
  31. package/dist/lib/settings/settings.component.d.ts.map +1 -1
  32. package/dist/lib/settings/settings.component.js +528 -182
  33. package/dist/lib/settings/settings.component.js.map +1 -1
  34. package/dist/lib/shared/settings-card.component.d.ts.map +1 -1
  35. package/dist/lib/shared/settings-card.component.js +21 -18
  36. package/dist/lib/shared/settings-card.component.js.map +1 -1
  37. package/dist/lib/sql-logging/sql-logging.component.d.ts +12 -3
  38. package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -1
  39. package/dist/lib/sql-logging/sql-logging.component.js +318 -245
  40. package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
  41. package/dist/lib/user-app-config/user-app-config.component.d.ts +21 -3
  42. package/dist/lib/user-app-config/user-app-config.component.d.ts.map +1 -1
  43. package/dist/lib/user-app-config/user-app-config.component.js +202 -147
  44. package/dist/lib/user-app-config/user-app-config.component.js.map +1 -1
  45. package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
  46. package/dist/lib/user-management/user-dialog/user-dialog.component.js +120 -116
  47. package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
  48. package/dist/lib/user-management/user-management.component.d.ts +32 -2
  49. package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
  50. package/dist/lib/user-management/user-management.component.js +822 -297
  51. package/dist/lib/user-management/user-management.component.js.map +1 -1
  52. package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts +31 -2
  53. package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts.map +1 -1
  54. package/dist/lib/user-profile-settings/user-profile-settings.component.js +213 -80
  55. package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
  56. package/package.json +21 -20
@@ -15,101 +15,127 @@ import * as i0 from "@angular/core";
15
15
  import * as i1 from "@memberjunction/ng-shared";
16
16
  import * as i2 from "@angular/forms";
17
17
  import * as i3 from "@memberjunction/ng-code-editor";
18
+ import * as i4 from "@memberjunction/ng-shared-generic";
18
19
  const _forTrack0 = ($index, $item) => $item.id;
19
20
  const _forTrack1 = ($index, $item) => $item.value;
20
21
  function SqlLoggingComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
21
22
  const _r1 = i0.ɵɵgetCurrentView();
22
- i0.ɵɵelementStart(0, "button", 9);
23
+ i0.ɵɵelementStart(0, "button", 10);
23
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()); });
24
- i0.ɵɵelement(1, "i", 10);
25
+ i0.ɵɵelement(1, "i", 11);
25
26
  i0.ɵɵtext(2, " Start New Session ");
26
27
  i0.ɵɵelementEnd();
27
28
  } if (rf & 2) {
28
29
  const ctx_r1 = i0.ɵɵnextContext();
29
30
  i0.ɵɵproperty("disabled", ctx_r1.loading || ctx_r1.activeSessions.length >= ((ctx_r1.sqlLoggingConfig == null ? null : ctx_r1.sqlLoggingConfig.maxActiveSessions) || 5));
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)" : ""));
30
32
  } }
31
33
  function SqlLoggingComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
32
- i0.ɵɵelementStart(0, "div", 5)(1, "div", 11)(2, "div", 12);
33
- i0.ɵɵelement(3, "i", 13);
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);
34
39
  i0.ɵɵelementEnd();
35
- i0.ɵɵelementStart(4, "div", 14)(5, "div", 15);
36
- i0.ɵɵtext(6);
40
+ i0.ɵɵelementStart(5, "div", 16)(6, "h3", 17);
41
+ i0.ɵɵtext(7, "Statistics");
37
42
  i0.ɵɵelementEnd();
38
- i0.ɵɵelementStart(7, "div", 16);
39
- i0.ɵɵtext(8, "Status");
43
+ i0.ɵɵelementStart(8, "p", 18);
44
+ i0.ɵɵtext(9, "View session statistics and metrics");
40
45
  i0.ɵɵelementEnd()()();
41
- i0.ɵɵelementStart(9, "div", 11)(10, "div", 17);
42
- i0.ɵɵelement(11, "i", 18);
46
+ i0.ɵɵelement(10, "i", 19);
47
+ i0.ɵɵelementEnd();
48
+ i0.ɵɵelementStart(11, "div", 20)(12, "div", 21)(13, "div", 22);
49
+ i0.ɵɵelement(14, "i", 23);
43
50
  i0.ɵɵelementEnd();
44
- i0.ɵɵelementStart(12, "div", 14)(13, "div", 15);
45
- i0.ɵɵtext(14);
51
+ i0.ɵɵelementStart(15, "div", 24)(16, "div", 25);
52
+ i0.ɵɵtext(17);
46
53
  i0.ɵɵelementEnd();
47
- i0.ɵɵelementStart(15, "div", 16);
48
- i0.ɵɵtext(16, "Active Sessions");
54
+ i0.ɵɵelementStart(18, "div", 26);
55
+ i0.ɵɵtext(19, "Status");
49
56
  i0.ɵɵelementEnd()()();
50
- i0.ɵɵelementStart(17, "div", 11)(18, "div", 19);
51
- i0.ɵɵelement(19, "i", 20);
57
+ i0.ɵɵelementStart(20, "div", 21)(21, "div", 27);
58
+ i0.ɵɵelement(22, "i", 28);
52
59
  i0.ɵɵelementEnd();
53
- i0.ɵɵelementStart(20, "div", 14)(21, "div", 15);
54
- i0.ɵɵtext(22);
60
+ i0.ɵɵelementStart(23, "div", 24)(24, "div", 25);
61
+ i0.ɵɵtext(25);
55
62
  i0.ɵɵelementEnd();
56
- i0.ɵɵelementStart(23, "div", 16);
57
- i0.ɵɵtext(24, "Max Sessions");
63
+ i0.ɵɵelementStart(26, "div", 26);
64
+ i0.ɵɵtext(27, "Active Sessions");
58
65
  i0.ɵɵelementEnd()()();
59
- i0.ɵɵelementStart(25, "div", 11)(26, "div", 21);
60
- i0.ɵɵelement(27, "i", 22);
66
+ i0.ɵɵelementStart(28, "div", 21)(29, "div", 29);
67
+ i0.ɵɵelement(30, "i", 30);
61
68
  i0.ɵɵelementEnd();
62
- i0.ɵɵelementStart(28, "div", 14)(29, "div", 15);
63
- i0.ɵɵtext(30);
69
+ i0.ɵɵelementStart(31, "div", 24)(32, "div", 25);
70
+ i0.ɵɵtext(33);
64
71
  i0.ɵɵelementEnd();
65
- i0.ɵɵelementStart(31, "div", 16);
66
- i0.ɵɵtext(32, "Total Statements");
67
- i0.ɵɵelementEnd()()()();
72
+ i0.ɵɵelementStart(34, "div", 26);
73
+ i0.ɵɵtext(35, "Max Sessions");
74
+ i0.ɵɵelementEnd()()();
75
+ i0.ɵɵelementStart(36, "div", 21)(37, "div", 31);
76
+ i0.ɵɵelement(38, "i", 32);
77
+ i0.ɵɵelementEnd();
78
+ i0.ɵɵelementStart(39, "div", 24)(40, "div", 25);
79
+ i0.ɵɵtext(41);
80
+ i0.ɵɵelementEnd();
81
+ i0.ɵɵelementStart(42, "div", 26);
82
+ i0.ɵɵtext(43, "Total Statements");
83
+ i0.ɵɵelementEnd()()()()();
68
84
  } if (rf & 2) {
69
85
  const ctx_r1 = i0.ɵɵnextContext();
70
- i0.ɵɵadvance(6);
71
- i0.ɵɵtextInterpolate(ctx_r1.configEnabled ? "Enabled" : "Disabled");
72
- i0.ɵɵadvance(8);
73
- i0.ɵɵtextInterpolate(ctx_r1.activeSessions.length);
74
- i0.ɵɵadvance(8);
75
- i0.ɵɵtextInterpolate((ctx_r1.sqlLoggingConfig == null ? null : ctx_r1.sqlLoggingConfig.maxActiveSessions) || 5);
76
- i0.ɵɵadvance(8);
77
- i0.ɵɵtextInterpolate(ctx_r1.getTotalStatementCount());
86
+ i0.ɵɵadvance();
87
+ i0.ɵɵclassProp("expanded", ctx_r1.showStats);
88
+ i0.ɵɵattribute("aria-expanded", ctx_r1.showStats);
89
+ i0.ɵɵadvance(10);
90
+ i0.ɵɵclassProp("visible", ctx_r1.showStats);
91
+ i0.ɵɵadvance(5);
92
+ i0.ɵɵattribute("aria-label", "Status: " + (ctx_r1.configEnabled ? "Enabled" : "Disabled"));
93
+ i0.ɵɵadvance();
94
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.configEnabled ? "Enabled" : "Disabled", " ");
95
+ i0.ɵɵadvance(7);
96
+ i0.ɵɵattribute("aria-label", ctx_r1.activeSessions.length + " active sessions");
97
+ i0.ɵɵadvance();
98
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.activeSessions.length, " ");
99
+ i0.ɵɵadvance(7);
100
+ i0.ɵɵattribute("aria-label", ((ctx_r1.sqlLoggingConfig == null ? null : ctx_r1.sqlLoggingConfig.maxActiveSessions) || 5) + " maximum sessions allowed");
101
+ i0.ɵɵadvance();
102
+ i0.ɵɵtextInterpolate1(" ", (ctx_r1.sqlLoggingConfig == null ? null : ctx_r1.sqlLoggingConfig.maxActiveSessions) || 5, " ");
103
+ i0.ɵɵadvance(7);
104
+ i0.ɵɵattribute("aria-label", ctx_r1.getTotalStatementCount() + " total SQL statements captured");
105
+ i0.ɵɵadvance();
106
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.getTotalStatementCount(), " ");
78
107
  } }
79
108
  function SqlLoggingComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
80
- i0.ɵɵelementStart(0, "div", 6)(1, "div", 23);
81
- i0.ɵɵelement(2, "div", 24)(3, "div", 24)(4, "div", 24);
109
+ i0.ɵɵelementStart(0, "div", 6);
110
+ i0.ɵɵelement(1, "mj-loading", 33);
82
111
  i0.ɵɵelementEnd();
83
- i0.ɵɵelementStart(5, "div", 25);
84
- i0.ɵɵtext(6, "Loading SQL logging configuration...");
85
- i0.ɵɵelementEnd()();
86
112
  } }
87
113
  function SqlLoggingComponent_Conditional_8_Conditional_1_Template(rf, ctx) { if (rf & 1) {
88
- const _r3 = i0.ɵɵgetCurrentView();
89
- i0.ɵɵelementStart(0, "div", 26);
90
- i0.ɵɵelement(1, "i", 28);
91
- i0.ɵɵelementStart(2, "p", 29);
114
+ const _r4 = i0.ɵɵgetCurrentView();
115
+ i0.ɵɵelementStart(0, "div", 34);
116
+ i0.ɵɵelement(1, "i", 37);
117
+ i0.ɵɵelementStart(2, "p", 38);
92
118
  i0.ɵɵtext(3, "Access Denied");
93
119
  i0.ɵɵelementEnd();
94
- i0.ɵɵelementStart(4, "p", 30);
120
+ i0.ɵɵelementStart(4, "p", 39);
95
121
  i0.ɵɵtext(5, "SQL logging requires Owner privileges. Please contact your system administrator for access.");
96
122
  i0.ɵɵelementEnd();
97
- i0.ɵɵelementStart(6, "button", 31);
98
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_1_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.refreshUserPermissions()); });
99
- i0.ɵɵelement(7, "i", 32);
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);
100
126
  i0.ɵɵtext(8, " Refresh Permissions ");
101
127
  i0.ɵɵelementEnd()();
102
128
  } }
103
129
  function SqlLoggingComponent_Conditional_8_Conditional_2_Template(rf, ctx) { if (rf & 1) {
104
- i0.ɵɵelementStart(0, "div", 26);
105
- i0.ɵɵelement(1, "i", 33);
106
- i0.ɵɵelementStart(2, "p", 29);
130
+ i0.ɵɵelementStart(0, "div", 34);
131
+ i0.ɵɵelement(1, "i", 42);
132
+ i0.ɵɵelementStart(2, "p", 38);
107
133
  i0.ɵɵtext(3, "SQL Logging Disabled");
108
134
  i0.ɵɵelementEnd();
109
- i0.ɵɵelementStart(4, "p", 30);
135
+ i0.ɵɵelementStart(4, "p", 39);
110
136
  i0.ɵɵtext(5, "SQL logging is not enabled in the server configuration.");
111
137
  i0.ɵɵelementEnd();
112
- i0.ɵɵelementStart(6, "div", 34)(7, "h4");
138
+ i0.ɵɵelementStart(6, "div", 43)(7, "h4");
113
139
  i0.ɵɵtext(8, "To enable SQL logging:");
114
140
  i0.ɵɵelementEnd();
115
141
  i0.ɵɵelementStart(9, "ol")(10, "li");
@@ -127,26 +153,26 @@ function SqlLoggingComponent_Conditional_8_Conditional_2_Template(rf, ctx) { if
127
153
  i0.ɵɵelementEnd()()()();
128
154
  } }
129
155
  function SqlLoggingComponent_Conditional_8_Conditional_3_Template(rf, ctx) { if (rf & 1) {
130
- const _r4 = i0.ɵɵgetCurrentView();
131
- i0.ɵɵelementStart(0, "div", 26);
132
- i0.ɵɵelement(1, "i", 35);
133
- i0.ɵɵelementStart(2, "p", 29);
156
+ const _r5 = i0.ɵɵgetCurrentView();
157
+ i0.ɵɵelementStart(0, "div", 35);
158
+ i0.ɵɵelement(1, "i", 44);
159
+ i0.ɵɵelementStart(2, "p", 38);
134
160
  i0.ɵɵtext(3, "No Active Sessions");
135
161
  i0.ɵɵelementEnd();
136
- i0.ɵɵelementStart(4, "p", 30);
162
+ i0.ɵɵelementStart(4, "p", 39);
137
163
  i0.ɵɵtext(5, "Start a new SQL logging session to begin capturing SQL statements.");
138
164
  i0.ɵɵelementEnd();
139
- i0.ɵɵelementStart(6, "button", 36);
140
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_3_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openStartSessionDialog()); });
141
- i0.ɵɵelement(7, "i", 10);
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);
142
168
  i0.ɵɵtext(8, " Start New Session ");
143
169
  i0.ɵɵelementEnd()();
144
170
  } }
145
171
  function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_5_Template(rf, ctx) { if (rf & 1) {
146
- const _r5 = i0.ɵɵgetCurrentView();
147
- i0.ɵɵelementStart(0, "button", 44);
148
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openStopAllSessionsConfirm()); });
149
- i0.ɵɵelement(1, "i", 45);
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);
150
176
  i0.ɵɵtext(2, " Stop All ");
151
177
  i0.ɵɵelementEnd();
152
178
  } if (rf & 2) {
@@ -154,78 +180,81 @@ function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_5_Template(
154
180
  i0.ɵɵproperty("disabled", ctx_r1.loading);
155
181
  } }
156
182
  function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Conditional_15_Template(rf, ctx) { if (rf & 1) {
157
- i0.ɵɵelementStart(0, "span", 55);
158
- i0.ɵɵelement(1, "i", 58);
183
+ i0.ɵɵelementStart(0, "span", 64);
184
+ i0.ɵɵelement(1, "i", 67);
159
185
  i0.ɵɵtext(2, " User Filtered ");
160
186
  i0.ɵɵelementEnd();
161
187
  } }
162
188
  function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Conditional_16_Template(rf, ctx) { if (rf & 1) {
163
- i0.ɵɵelementStart(0, "span", 56);
164
- i0.ɵɵelement(1, "i", 59);
189
+ i0.ɵɵelementStart(0, "span", 65);
190
+ i0.ɵɵelement(1, "i", 68);
165
191
  i0.ɵɵtext(2, " Migration ");
166
192
  i0.ɵɵelementEnd();
167
193
  } }
168
194
  function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template(rf, ctx) { if (rf & 1) {
169
- const _r6 = i0.ɵɵgetCurrentView();
170
- i0.ɵɵelementStart(0, "div", 46);
171
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template_div_click_0_listener() { const session_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectSession(session_r7)); });
172
- i0.ɵɵelementStart(1, "div", 47)(2, "div", 48)(3, "h4", 49);
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);
173
199
  i0.ɵɵtext(4);
174
200
  i0.ɵɵelementEnd();
175
- i0.ɵɵelementStart(5, "div", 50)(6, "span", 51);
176
- i0.ɵɵelement(7, "i", 52);
201
+ i0.ɵɵelementStart(5, "div", 59)(6, "span", 60);
202
+ i0.ɵɵelement(7, "i", 61);
177
203
  i0.ɵɵtext(8);
178
204
  i0.ɵɵelementEnd();
179
- i0.ɵɵelementStart(9, "span", 51);
180
- i0.ɵɵelement(10, "i", 22);
205
+ i0.ɵɵelementStart(9, "span", 60);
206
+ i0.ɵɵelement(10, "i", 32);
181
207
  i0.ɵɵtext(11);
182
208
  i0.ɵɵelementEnd()()();
183
- i0.ɵɵelementStart(12, "button", 53);
184
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template_button_click_12_listener($event) { const session_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openStopSessionConfirm(session_r7, $event)); });
185
- i0.ɵɵelement(13, "i", 45);
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);
186
212
  i0.ɵɵelementEnd()();
187
- i0.ɵɵelementStart(14, "div", 54);
188
- i0.ɵɵtemplate(15, SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Conditional_15_Template, 3, 0, "span", 55)(16, SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Conditional_16_Template, 3, 0, "span", 56);
189
- i0.ɵɵelementStart(17, "span", 57);
213
+ i0.ɵɵelementStart(14, "div", 63);
214
+ i0.ɵɵtemplate(15, SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Conditional_15_Template, 3, 0, "span", 64)(16, SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Conditional_16_Template, 3, 0, "span", 65);
215
+ i0.ɵɵelementStart(17, "span", 66);
190
216
  i0.ɵɵtext(18);
191
217
  i0.ɵɵelementEnd()()();
192
218
  } if (rf & 2) {
193
- const session_r7 = ctx.$implicit;
219
+ const session_r8 = ctx.$implicit;
194
220
  const ctx_r1 = i0.ɵɵnextContext(3);
195
- i0.ɵɵclassProp("selected", (ctx_r1.selectedSession == null ? null : ctx_r1.selectedSession.id) === session_r7.id);
221
+ i0.ɵɵclassProp("selected", (ctx_r1.selectedSession == null ? null : ctx_r1.selectedSession.id) === session_r8.id);
222
+ i0.ɵɵattribute("aria-label", "Session: " + session_r8.sessionName + ", " + session_r8.statementCount + " statements, duration " + ctx_r1.getSessionDuration(session_r8.startTime))("aria-selected", (ctx_r1.selectedSession == null ? null : ctx_r1.selectedSession.id) === session_r8.id);
196
223
  i0.ɵɵadvance(4);
197
- i0.ɵɵtextInterpolate(session_r7.sessionName);
224
+ i0.ɵɵtextInterpolate(session_r8.sessionName);
198
225
  i0.ɵɵadvance(4);
199
- i0.ɵɵtextInterpolate1(" ", ctx_r1.getSessionDuration(session_r7.startTime), " ");
226
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.getSessionDuration(session_r8.startTime), " ");
200
227
  i0.ɵɵadvance(3);
201
- i0.ɵɵtextInterpolate1(" ", session_r7.statementCount, " statements ");
202
- i0.ɵɵadvance(4);
203
- i0.ɵɵconditional(session_r7.filterByUserId ? 15 : -1);
228
+ i0.ɵɵtextInterpolate1(" ", session_r8.statementCount, " statements ");
229
+ i0.ɵɵadvance();
230
+ i0.ɵɵattribute("aria-label", "Stop session " + session_r8.sessionName);
231
+ i0.ɵɵadvance(3);
232
+ i0.ɵɵconditional(session_r8.filterByUserId ? 15 : -1);
204
233
  i0.ɵɵadvance();
205
- i0.ɵɵconditional((session_r7.options == null ? null : session_r7.options.formatAsMigration) ? 16 : -1);
234
+ i0.ɵɵconditional((session_r8.options == null ? null : session_r8.options.formatAsMigration) ? 16 : -1);
206
235
  i0.ɵɵadvance(2);
207
- i0.ɵɵtextInterpolate1(" ", (session_r7.options == null ? null : session_r7.options.statementTypes) || "both", " ");
236
+ i0.ɵɵtextInterpolate1(" ", (session_r8.options == null ? null : session_r8.options.statementTypes) || "both", " ");
208
237
  } }
209
238
  function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template(rf, ctx) { if (rf & 1) {
210
- const _r8 = i0.ɵɵgetCurrentView();
211
- i0.ɵɵelementStart(0, "div", 38)(1, "h3", 39);
239
+ const _r9 = i0.ɵɵgetCurrentView();
240
+ i0.ɵɵelementStart(0, "div", 47)(1, "h3", 48);
212
241
  i0.ɵɵtext(2);
213
242
  i0.ɵɵelementEnd();
214
- i0.ɵɵelementStart(3, "div", 60)(4, "label", 61)(5, "input", 62);
215
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template_input_ngModelChange_5_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.autoRefresh, $event) || (ctx_r1.autoRefresh = $event); return i0.ɵɵresetView($event); });
243
+ i0.ɵɵelementStart(3, "div", 69)(4, "label", 70)(5, "input", 71);
244
+ 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); });
216
245
  i0.ɵɵelementEnd();
217
246
  i0.ɵɵtext(6, " Auto-refresh ");
218
247
  i0.ɵɵelementEnd();
219
- i0.ɵɵelementStart(7, "button", 63);
220
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.loadSessionLog(ctx_r1.selectedSession)); });
221
- i0.ɵɵelement(8, "i", 32);
248
+ i0.ɵɵelementStart(7, "button", 72);
249
+ 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)); });
250
+ i0.ɵɵelement(8, "i", 41);
222
251
  i0.ɵɵelementEnd();
223
- i0.ɵɵelementStart(9, "button", 64);
224
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleLogViewerExpand()); });
225
- i0.ɵɵelement(10, "i", 65);
252
+ i0.ɵɵelementStart(9, "button", 73);
253
+ 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()); });
254
+ i0.ɵɵelement(10, "i", 74);
226
255
  i0.ɵɵelementEnd()()();
227
- i0.ɵɵelementStart(11, "div", 66);
228
- i0.ɵɵelement(12, "mj-code-editor", 67);
256
+ i0.ɵɵelementStart(11, "div", 75);
257
+ i0.ɵɵelement(12, "mj-code-editor", 76);
229
258
  i0.ɵɵelementEnd();
230
259
  } if (rf & 2) {
231
260
  const ctx_r1 = i0.ɵɵnextContext(3);
@@ -236,33 +265,33 @@ function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template
236
265
  i0.ɵɵadvance(3);
237
266
  i0.ɵɵclassProp("fa-spin", ctx_r1.loading);
238
267
  i0.ɵɵadvance();
239
- i0.ɵɵproperty("title", ctx_r1.isLogViewerExpanded ? "Collapse" : "Expand");
268
+ i0.ɵɵattribute("aria-label", ctx_r1.isLogViewerExpanded ? "Collapse log viewer" : "Expand log viewer to fullscreen")("aria-expanded", ctx_r1.isLogViewerExpanded);
240
269
  i0.ɵɵadvance();
241
270
  i0.ɵɵclassProp("fa-expand", !ctx_r1.isLogViewerExpanded)("fa-compress", ctx_r1.isLogViewerExpanded);
242
271
  i0.ɵɵadvance(2);
243
272
  i0.ɵɵproperty("value", ctx_r1.logContent)("readonly", true)("disabled", true)("language", "sql")("setup", "basic")("lineWrapping", true)("highlightWhitespace", false);
244
273
  } }
245
274
  function SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_11_Template(rf, ctx) { if (rf & 1) {
246
- i0.ɵɵelementStart(0, "div", 26);
247
- i0.ɵɵelement(1, "i", 68);
248
- i0.ɵɵelementStart(2, "p", 29);
275
+ i0.ɵɵelementStart(0, "div", 35);
276
+ i0.ɵɵelement(1, "i", 77);
277
+ i0.ɵɵelementStart(2, "p", 38);
249
278
  i0.ɵɵtext(3, "Select a Session");
250
279
  i0.ɵɵelementEnd();
251
- i0.ɵɵelementStart(4, "p", 30);
280
+ i0.ɵɵelementStart(4, "p", 39);
252
281
  i0.ɵɵtext(5, "Choose a session from the list to view its SQL log.");
253
282
  i0.ɵɵelementEnd()();
254
283
  } }
255
284
  function SqlLoggingComponent_Conditional_8_Conditional_4_Template(rf, ctx) { if (rf & 1) {
256
- i0.ɵɵelementStart(0, "div", 27)(1, "div", 37)(2, "div", 38)(3, "h3", 39);
285
+ i0.ɵɵelementStart(0, "div", 36)(1, "div", 46)(2, "div", 47)(3, "h3", 48);
257
286
  i0.ɵɵtext(4, "Active Sessions");
258
287
  i0.ɵɵelementEnd();
259
- i0.ɵɵtemplate(5, SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_5_Template, 3, 1, "button", 40);
288
+ i0.ɵɵtemplate(5, SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_5_Template, 3, 1, "button", 49);
260
289
  i0.ɵɵelementEnd();
261
- i0.ɵɵelementStart(6, "div", 41);
262
- i0.ɵɵrepeaterCreate(7, SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template, 19, 8, "div", 42, _forTrack0);
290
+ i0.ɵɵelementStart(6, "div", 50);
291
+ i0.ɵɵrepeaterCreate(7, SqlLoggingComponent_Conditional_8_Conditional_4_For_8_Template, 19, 11, "div", 51, _forTrack0);
263
292
  i0.ɵɵelementEnd()();
264
- i0.ɵɵelementStart(9, "div", 43);
265
- i0.ɵɵtemplate(10, SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template, 13, 16)(11, SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_11_Template, 6, 0, "div", 26);
293
+ i0.ɵɵelementStart(9, "div", 52);
294
+ i0.ɵɵtemplate(10, SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_10_Template, 13, 17)(11, SqlLoggingComponent_Conditional_8_Conditional_4_Conditional_11_Template, 6, 0, "div", 35);
266
295
  i0.ɵɵelementEnd()();
267
296
  } if (rf & 2) {
268
297
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -277,156 +306,179 @@ function SqlLoggingComponent_Conditional_8_Conditional_4_Template(rf, ctx) { if
277
306
  } }
278
307
  function SqlLoggingComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
279
308
  i0.ɵɵelementStart(0, "div", 7);
280
- i0.ɵɵtemplate(1, SqlLoggingComponent_Conditional_8_Conditional_1_Template, 9, 0, "div", 26)(2, SqlLoggingComponent_Conditional_8_Conditional_2_Template, 19, 0, "div", 26)(3, SqlLoggingComponent_Conditional_8_Conditional_3_Template, 9, 0, "div", 26)(4, SqlLoggingComponent_Conditional_8_Conditional_4_Template, 12, 4, "div", 27);
309
+ i0.ɵɵtemplate(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);
281
310
  i0.ɵɵelementEnd();
282
311
  } if (rf & 2) {
283
312
  const ctx_r1 = i0.ɵɵnextContext();
284
313
  i0.ɵɵadvance();
285
314
  i0.ɵɵconditional(!ctx_r1.isOwner ? 1 : !ctx_r1.configEnabled ? 2 : ctx_r1.activeSessions.length === 0 ? 3 : 4);
286
315
  } }
287
- function SqlLoggingComponent_Conditional_9_For_24_Template(rf, ctx) { if (rf & 1) {
288
- i0.ɵɵelementStart(0, "option", 82);
316
+ function SqlLoggingComponent_Conditional_9_For_29_Template(rf, ctx) { if (rf & 1) {
317
+ i0.ɵɵelementStart(0, "option", 96);
289
318
  i0.ɵɵtext(1);
290
319
  i0.ɵɵelementEnd();
291
320
  } if (rf & 2) {
292
- const option_r10 = ctx.$implicit;
293
- i0.ɵɵproperty("value", option_r10.value);
321
+ const option_r11 = ctx.$implicit;
322
+ i0.ɵɵproperty("value", option_r11.value);
294
323
  i0.ɵɵadvance();
295
- i0.ɵɵtextInterpolate(option_r10.text);
324
+ i0.ɵɵtextInterpolate(option_r11.text);
296
325
  } }
297
- function SqlLoggingComponent_Conditional_9_For_44_Template(rf, ctx) { if (rf & 1) {
298
- i0.ɵɵelementStart(0, "option", 82);
326
+ function SqlLoggingComponent_Conditional_9_For_51_Template(rf, ctx) { if (rf & 1) {
327
+ i0.ɵɵelementStart(0, "option", 96);
299
328
  i0.ɵɵtext(1);
300
329
  i0.ɵɵelementEnd();
301
330
  } if (rf & 2) {
302
- const option_r11 = ctx.$implicit;
303
- i0.ɵɵproperty("value", option_r11.value);
331
+ const option_r12 = ctx.$implicit;
332
+ i0.ɵɵproperty("value", option_r12.value);
304
333
  i0.ɵɵadvance();
305
- i0.ɵɵtextInterpolate(option_r11.text);
334
+ i0.ɵɵtextInterpolate(option_r12.text);
306
335
  } }
307
- function SqlLoggingComponent_Conditional_9_Conditional_57_Template(rf, ctx) { if (rf & 1) {
308
- const _r12 = i0.ɵɵgetCurrentView();
309
- i0.ɵɵelementStart(0, "div", 76)(1, "label", 77);
336
+ function SqlLoggingComponent_Conditional_9_Conditional_64_Template(rf, ctx) { if (rf & 1) {
337
+ const _r13 = i0.ɵɵgetCurrentView();
338
+ i0.ɵɵelementStart(0, "div", 87)(1, "label", 115);
310
339
  i0.ɵɵtext(2, "Default Schema Name");
311
340
  i0.ɵɵelementEnd();
312
- i0.ɵɵelementStart(3, "input", 93);
313
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Conditional_57_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.defaultSchemaName, $event) || (ctx_r1.newSessionOptions.defaultSchemaName = $event); return i0.ɵɵresetView($event); });
341
+ i0.ɵɵelementStart(3, "input", 116);
342
+ 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); });
314
343
  i0.ɵɵelementEnd();
315
- i0.ɵɵelementStart(4, "div", 80);
316
- i0.ɵɵtext(5, " Schema name to replace with ${flyway:defaultSchema} placeholder. ");
344
+ i0.ɵɵelementStart(4, "div", 117);
345
+ i0.ɵɵtext(5, "Schema name to replace with ${flyway:defaultSchema} placeholder.");
317
346
  i0.ɵɵelementEnd()();
318
347
  } if (rf & 2) {
319
348
  const ctx_r1 = i0.ɵɵnextContext(2);
320
349
  i0.ɵɵadvance(3);
321
350
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newSessionOptions.defaultSchemaName);
322
351
  } }
352
+ function SqlLoggingComponent_Conditional_9_Conditional_73_Template(rf, ctx) { if (rf & 1) {
353
+ i0.ɵɵelement(0, "i", 118);
354
+ i0.ɵɵtext(1, " Starting... ");
355
+ } }
356
+ function SqlLoggingComponent_Conditional_9_Conditional_74_Template(rf, ctx) { if (rf & 1) {
357
+ i0.ɵɵelement(0, "i", 11);
358
+ i0.ɵɵtext(1, " Start Session ");
359
+ } }
323
360
  function SqlLoggingComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
324
- const _r9 = i0.ɵɵgetCurrentView();
325
- i0.ɵɵelementStart(0, "div", 69);
326
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStartSessionDialog = false); });
327
- i0.ɵɵelementStart(1, "div", 70);
328
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r9); return i0.ɵɵresetView($event.stopPropagation()); });
329
- i0.ɵɵelementStart(2, "div", 71)(3, "h3", 72);
330
- i0.ɵɵelement(4, "i", 10);
361
+ const _r10 = i0.ɵɵgetCurrentView();
362
+ i0.ɵɵelementStart(0, "div", 78);
363
+ 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); });
364
+ i0.ɵɵelementStart(1, "div", 79);
365
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r10); return i0.ɵɵresetView($event.stopPropagation()); });
366
+ i0.ɵɵelementStart(2, "div", 80)(3, "h3", 81);
367
+ i0.ɵɵelement(4, "i", 11);
331
368
  i0.ɵɵtext(5, " Start SQL Logging Session ");
332
369
  i0.ɵɵelementEnd();
333
- i0.ɵɵelementStart(6, "button", 73);
334
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStartSessionDialog = false); });
335
- i0.ɵɵelement(7, "i", 74);
336
- i0.ɵɵelementEnd()();
337
- i0.ɵɵelementStart(8, "div", 75)(9, "div", 76)(10, "label", 77);
338
- i0.ɵɵtext(11, "Session Name");
370
+ i0.ɵɵelementStart(6, "div", 82)(7, "button", 83);
371
+ 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()); });
372
+ i0.ɵɵelement(8, "i", 74);
373
+ i0.ɵɵelementEnd();
374
+ i0.ɵɵelementStart(9, "button", 84);
375
+ 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); });
376
+ i0.ɵɵelement(10, "i", 85);
377
+ i0.ɵɵelementEnd()()();
378
+ i0.ɵɵelementStart(11, "div", 86)(12, "div", 87)(13, "label", 88);
379
+ i0.ɵɵtext(14, "Session Name");
380
+ i0.ɵɵelementEnd();
381
+ i0.ɵɵelementStart(15, "input", 89);
382
+ 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); });
339
383
  i0.ɵɵelementEnd();
340
- i0.ɵɵelementStart(12, "input", 78);
341
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.sessionName, $event) || (ctx_r1.newSessionOptions.sessionName = $event); return i0.ɵɵresetView($event); });
384
+ i0.ɵɵelementStart(16, "div", 90);
385
+ i0.ɵɵtext(17, "A descriptive name to identify this logging session");
342
386
  i0.ɵɵelementEnd()();
343
- i0.ɵɵelementStart(13, "div", 76)(14, "label", 77);
344
- i0.ɵɵtext(15, "File Name");
387
+ i0.ɵɵelementStart(18, "div", 87)(19, "label", 91);
388
+ i0.ɵɵtext(20, "File Name");
345
389
  i0.ɵɵelementEnd();
346
- i0.ɵɵelementStart(16, "input", 79);
347
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_16_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.fileName, $event) || (ctx_r1.newSessionOptions.fileName = $event); return i0.ɵɵresetView($event); });
390
+ i0.ɵɵelementStart(21, "input", 92);
391
+ 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); });
348
392
  i0.ɵɵelementEnd();
349
- i0.ɵɵelementStart(17, "div", 80);
350
- i0.ɵɵtext(18, "The SQL log will be saved to this file");
393
+ i0.ɵɵelementStart(22, "div", 93);
394
+ i0.ɵɵtext(23, "The SQL log will be saved to this file");
351
395
  i0.ɵɵelementEnd()();
352
- i0.ɵɵelementStart(19, "div", 76)(20, "label", 77);
353
- i0.ɵɵtext(21, "Statement Types");
396
+ i0.ɵɵelementStart(24, "div", 87)(25, "label", 94);
397
+ i0.ɵɵtext(26, "Statement Types");
354
398
  i0.ɵɵelementEnd();
355
- i0.ɵɵelementStart(22, "select", 81);
356
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_select_ngModelChange_22_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.statementTypes, $event) || (ctx_r1.newSessionOptions.statementTypes = $event); return i0.ɵɵresetView($event); });
357
- i0.ɵɵrepeaterCreate(23, SqlLoggingComponent_Conditional_9_For_24_Template, 2, 2, "option", 82, _forTrack1);
399
+ i0.ɵɵelementStart(27, "select", 95);
400
+ 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); });
401
+ i0.ɵɵrepeaterCreate(28, SqlLoggingComponent_Conditional_9_For_29_Template, 2, 2, "option", 96, _forTrack1);
402
+ i0.ɵɵelementEnd();
403
+ i0.ɵɵelementStart(30, "div", 97);
404
+ i0.ɵɵtext(31, "Filter which types of SQL statements to capture");
358
405
  i0.ɵɵelementEnd()();
359
- i0.ɵɵelementStart(25, "div", 83)(26, "label", 61)(27, "input", 62);
360
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_27_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.filterToCurrentUser, $event) || (ctx_r1.newSessionOptions.filterToCurrentUser = $event); return i0.ɵɵresetView($event); });
406
+ i0.ɵɵelementStart(32, "div", 98)(33, "label", 70)(34, "input", 99);
407
+ 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); });
361
408
  i0.ɵɵelementEnd();
362
- i0.ɵɵtext(28, " Filter to my SQL statements only ");
409
+ i0.ɵɵtext(35, " Filter to my SQL statements only ");
363
410
  i0.ɵɵelementEnd();
364
- i0.ɵɵelementStart(29, "label", 61)(30, "input", 62);
365
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_30_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.formatAsMigration, $event) || (ctx_r1.newSessionOptions.formatAsMigration = $event); return i0.ɵɵresetView($event); });
411
+ i0.ɵɵelementStart(36, "label", 70)(37, "input", 99);
412
+ 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); });
366
413
  i0.ɵɵelementEnd();
367
- i0.ɵɵtext(31, " Format as migration file ");
414
+ i0.ɵɵtext(38, " Format as migration file ");
368
415
  i0.ɵɵelementEnd();
369
- i0.ɵɵelementStart(32, "label", 61)(33, "input", 62);
370
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_33_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.prettyPrint, $event) || (ctx_r1.newSessionOptions.prettyPrint = $event); return i0.ɵɵresetView($event); });
416
+ i0.ɵɵelementStart(39, "label", 70)(40, "input", 99);
417
+ 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); });
371
418
  i0.ɵɵelementEnd();
372
- i0.ɵɵtext(34, " Pretty print SQL statements ");
419
+ i0.ɵɵtext(41, " Pretty print SQL statements ");
373
420
  i0.ɵɵelementEnd()();
374
- i0.ɵɵelementStart(35, "div", 84)(36, "h4", 85);
375
- i0.ɵɵelement(37, "i", 86);
376
- i0.ɵɵtext(38, " SQL Pattern Filtering ");
421
+ i0.ɵɵelementStart(42, "div", 100)(43, "h4", 101);
422
+ i0.ɵɵelement(44, "i", 102);
423
+ i0.ɵɵtext(45, " SQL Pattern Filtering ");
377
424
  i0.ɵɵelementEnd();
378
- i0.ɵɵelementStart(39, "div", 76)(40, "label", 77);
379
- i0.ɵɵtext(41, "Filter Mode");
425
+ i0.ɵɵelementStart(46, "div", 87)(47, "label", 103);
426
+ i0.ɵɵtext(48, "Filter Mode");
380
427
  i0.ɵɵelementEnd();
381
- i0.ɵɵelementStart(42, "select", 81);
382
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_select_ngModelChange_42_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.filterType, $event) || (ctx_r1.newSessionOptions.filterType = $event); return i0.ɵɵresetView($event); });
383
- i0.ɵɵrepeaterCreate(43, SqlLoggingComponent_Conditional_9_For_44_Template, 2, 2, "option", 82, _forTrack1);
428
+ i0.ɵɵelementStart(49, "select", 104);
429
+ 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); });
430
+ i0.ɵɵrepeaterCreate(50, SqlLoggingComponent_Conditional_9_For_51_Template, 2, 2, "option", 96, _forTrack1);
384
431
  i0.ɵɵelementEnd();
385
- i0.ɵɵelementStart(45, "div", 80);
386
- i0.ɵɵtext(46, " Exclude: Skip SQL matching any pattern. Include: Only log SQL matching a pattern. ");
432
+ i0.ɵɵelementStart(52, "div", 105);
433
+ i0.ɵɵtext(53, "Exclude: Skip SQL matching any pattern. Include: Only log SQL matching a pattern.");
387
434
  i0.ɵɵelementEnd()();
388
- i0.ɵɵelementStart(47, "div", 76)(48, "label", 77);
389
- i0.ɵɵtext(49, "Filter Patterns (one per line or comma-separated)");
435
+ i0.ɵɵelementStart(54, "div", 87)(55, "label", 106);
436
+ i0.ɵɵtext(56, "Filter Patterns (one per line or comma-separated)");
390
437
  i0.ɵɵelementEnd();
391
- i0.ɵɵelementStart(50, "textarea", 87);
392
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_textarea_ngModelChange_50_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.filterPatterns, $event) || (ctx_r1.newSessionOptions.filterPatterns = $event); return i0.ɵɵresetView($event); });
438
+ i0.ɵɵelementStart(57, "textarea", 107);
439
+ 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); });
393
440
  i0.ɵɵelementEnd();
394
- i0.ɵɵelementStart(51, "div", 80);
395
- i0.ɵɵtext(52, " Supports wildcards (*) and regex (/pattern/flags). Example: *spCreate* matches any SP starting with spCreate. ");
441
+ i0.ɵɵelementStart(58, "div", 108);
442
+ i0.ɵɵtext(59, "Supports wildcards (*) and regex (/pattern/flags). Example: *spCreate* matches any SP starting with spCreate.");
396
443
  i0.ɵɵelementEnd()()();
397
- i0.ɵɵelementStart(53, "div", 84)(54, "h4", 85);
398
- i0.ɵɵelement(55, "i", 88);
399
- i0.ɵɵtext(56, " Advanced Options ");
444
+ i0.ɵɵelementStart(60, "div", 100)(61, "h4", 101);
445
+ i0.ɵɵelement(62, "i", 109);
446
+ i0.ɵɵtext(63, " Advanced Options ");
400
447
  i0.ɵɵelementEnd();
401
- i0.ɵɵtemplate(57, SqlLoggingComponent_Conditional_9_Conditional_57_Template, 6, 1, "div", 76);
402
- i0.ɵɵelementStart(58, "div", 83)(59, "label", 61)(60, "input", 62);
403
- i0.ɵɵtwoWayListener("ngModelChange", function SqlLoggingComponent_Conditional_9_Template_input_ngModelChange_60_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newSessionOptions.verboseOutput, $event) || (ctx_r1.newSessionOptions.verboseOutput = $event); return i0.ɵɵresetView($event); });
448
+ i0.ɵɵtemplate(64, SqlLoggingComponent_Conditional_9_Conditional_64_Template, 6, 1, "div", 87);
449
+ i0.ɵɵelementStart(65, "div", 110)(66, "label", 70)(67, "input", 99);
450
+ 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); });
404
451
  i0.ɵɵelementEnd();
405
- i0.ɵɵtext(61, " Verbose Debug Output ");
452
+ i0.ɵɵtext(68, " Verbose Debug Output ");
406
453
  i0.ɵɵelementEnd();
407
- i0.ɵɵelementStart(62, "div", 89);
408
- i0.ɵɵtext(63, " Log detailed filter decisions to server console (for debugging). ");
454
+ i0.ɵɵelementStart(69, "div", 111);
455
+ i0.ɵɵtext(70, "Log detailed filter decisions to server console (for debugging).");
409
456
  i0.ɵɵelementEnd()()()();
410
- i0.ɵɵelementStart(64, "div", 90)(65, "button", 91);
411
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_button_click_65_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.startNewSession()); });
412
- i0.ɵɵelement(66, "i", 10);
413
- i0.ɵɵtext(67, " Start Session ");
414
- i0.ɵɵelementEnd();
415
- i0.ɵɵelementStart(68, "button", 92);
416
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_9_Template_button_click_68_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showStartSessionDialog = false); });
417
- i0.ɵɵtext(69, " Cancel ");
457
+ i0.ɵɵelementStart(71, "div", 112)(72, "button", 113);
458
+ 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()); });
459
+ i0.ɵɵtemplate(73, SqlLoggingComponent_Conditional_9_Conditional_73_Template, 2, 0)(74, SqlLoggingComponent_Conditional_9_Conditional_74_Template, 2, 0);
460
+ i0.ɵɵelementEnd();
461
+ i0.ɵɵelementStart(75, "button", 114);
462
+ 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); });
463
+ i0.ɵɵtext(76, "Cancel");
418
464
  i0.ɵɵelementEnd()()()();
419
465
  } if (rf & 2) {
420
466
  const ctx_r1 = i0.ɵɵnextContext();
421
- i0.ɵɵadvance(12);
467
+ i0.ɵɵadvance();
468
+ i0.ɵɵclassProp("fullscreen", ctx_r1.isStartDialogFullscreen);
469
+ i0.ɵɵadvance(6);
470
+ i0.ɵɵattribute("aria-label", ctx_r1.isStartDialogFullscreen ? "Exit fullscreen" : "Enter fullscreen");
471
+ i0.ɵɵadvance();
472
+ i0.ɵɵclassProp("fa-compress", ctx_r1.isStartDialogFullscreen)("fa-expand", !ctx_r1.isStartDialogFullscreen);
473
+ i0.ɵɵadvance(7);
422
474
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newSessionOptions.sessionName);
423
- i0.ɵɵadvance(4);
475
+ i0.ɵɵadvance(6);
424
476
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newSessionOptions.fileName);
425
477
  i0.ɵɵadvance(6);
426
478
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newSessionOptions.statementTypes);
427
479
  i0.ɵɵadvance();
428
480
  i0.ɵɵrepeater(ctx_r1.statementTypeOptions);
429
- i0.ɵɵadvance(4);
481
+ i0.ɵɵadvance(6);
430
482
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newSessionOptions.filterToCurrentUser);
431
483
  i0.ɵɵadvance(3);
432
484
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newSessionOptions.formatAsMigration);
@@ -439,11 +491,13 @@ function SqlLoggingComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
439
491
  i0.ɵɵadvance(7);
440
492
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newSessionOptions.filterPatterns);
441
493
  i0.ɵɵadvance(7);
442
- i0.ɵɵconditional(ctx_r1.newSessionOptions.formatAsMigration ? 57 : -1);
494
+ i0.ɵɵconditional(ctx_r1.newSessionOptions.formatAsMigration ? 64 : -1);
443
495
  i0.ɵɵadvance(3);
444
496
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newSessionOptions.verboseOutput);
445
497
  i0.ɵɵadvance(5);
446
498
  i0.ɵɵproperty("disabled", ctx_r1.loading);
499
+ i0.ɵɵadvance();
500
+ i0.ɵɵconditional(ctx_r1.loading ? 73 : 74);
447
501
  } }
448
502
  function SqlLoggingComponent_Conditional_10_Conditional_6_Template(rf, ctx) { if (rf & 1) {
449
503
  i0.ɵɵtext(0, " Stop All Sessions? ");
@@ -468,7 +522,7 @@ function SqlLoggingComponent_Conditional_10_Conditional_10_Template(rf, ctx) { i
468
522
  i0.ɵɵtext(2);
469
523
  i0.ɵɵelementEnd();
470
524
  i0.ɵɵtext(3, "? ");
471
- i0.ɵɵelementStart(4, "span", 102);
525
+ i0.ɵɵelementStart(4, "span", 129);
472
526
  i0.ɵɵtext(5);
473
527
  i0.ɵɵelementEnd();
474
528
  } if (rf & 2) {
@@ -479,7 +533,7 @@ function SqlLoggingComponent_Conditional_10_Conditional_10_Template(rf, ctx) { i
479
533
  i0.ɵɵtextInterpolate1(" This session has captured ", ctx_r1.sessionToStop.statementCount, " SQL statements. ");
480
534
  } }
481
535
  function SqlLoggingComponent_Conditional_10_Conditional_13_Template(rf, ctx) { if (rf & 1) {
482
- i0.ɵɵelement(0, "i", 103);
536
+ i0.ɵɵelement(0, "i", 118);
483
537
  i0.ɵɵtext(1, " Stopping... ");
484
538
  } }
485
539
  function SqlLoggingComponent_Conditional_10_Conditional_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
@@ -489,7 +543,7 @@ function SqlLoggingComponent_Conditional_10_Conditional_14_Conditional_2_Templat
489
543
  i0.ɵɵtext(0, " Stop Session ");
490
544
  } }
491
545
  function SqlLoggingComponent_Conditional_10_Conditional_14_Template(rf, ctx) { if (rf & 1) {
492
- i0.ɵɵelement(0, "i", 45);
546
+ i0.ɵɵelement(0, "i", 54);
493
547
  i0.ɵɵtemplate(1, SqlLoggingComponent_Conditional_10_Conditional_14_Conditional_1_Template, 1, 0)(2, SqlLoggingComponent_Conditional_10_Conditional_14_Conditional_2_Template, 1, 0);
494
548
  } if (rf & 2) {
495
549
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -497,27 +551,27 @@ function SqlLoggingComponent_Conditional_10_Conditional_14_Template(rf, ctx) { i
497
551
  i0.ɵɵconditional(ctx_r1.isStoppingAll ? 1 : 2);
498
552
  } }
499
553
  function SqlLoggingComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
500
- const _r13 = i0.ɵɵgetCurrentView();
501
- i0.ɵɵelementStart(0, "div", 69);
502
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_10_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelStopConfirm()); });
503
- i0.ɵɵelementStart(1, "div", 94);
504
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_10_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r13); return i0.ɵɵresetView($event.stopPropagation()); });
505
- i0.ɵɵelementStart(2, "div", 95);
506
- i0.ɵɵelement(3, "i", 96);
507
- i0.ɵɵelementEnd();
508
- i0.ɵɵelementStart(4, "div", 97)(5, "h3", 98);
554
+ const _r14 = i0.ɵɵgetCurrentView();
555
+ i0.ɵɵelementStart(0, "div", 119);
556
+ 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()); });
557
+ i0.ɵɵelementStart(1, "div", 120);
558
+ i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_10_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r14); return i0.ɵɵresetView($event.stopPropagation()); });
559
+ i0.ɵɵelementStart(2, "div", 121);
560
+ i0.ɵɵelement(3, "i", 122);
561
+ i0.ɵɵelementEnd();
562
+ i0.ɵɵelementStart(4, "div", 123)(5, "h3", 124);
509
563
  i0.ɵɵtemplate(6, SqlLoggingComponent_Conditional_10_Conditional_6_Template, 1, 0)(7, SqlLoggingComponent_Conditional_10_Conditional_7_Template, 1, 0);
510
564
  i0.ɵɵelementEnd();
511
- i0.ɵɵelementStart(8, "p", 99);
565
+ i0.ɵɵelementStart(8, "p", 125);
512
566
  i0.ɵɵtemplate(9, SqlLoggingComponent_Conditional_10_Conditional_9_Template, 4, 1)(10, SqlLoggingComponent_Conditional_10_Conditional_10_Template, 6, 2);
513
567
  i0.ɵɵelementEnd()();
514
- i0.ɵɵelementStart(11, "div", 100)(12, "button", 101);
515
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_10_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmStopSession()); });
568
+ i0.ɵɵelementStart(11, "div", 126)(12, "button", 127);
569
+ 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()); });
516
570
  i0.ɵɵtemplate(13, SqlLoggingComponent_Conditional_10_Conditional_13_Template, 2, 0)(14, SqlLoggingComponent_Conditional_10_Conditional_14_Template, 3, 1);
517
571
  i0.ɵɵelementEnd();
518
- i0.ɵɵelementStart(15, "button", 2);
519
- i0.ɵɵlistener("click", function SqlLoggingComponent_Conditional_10_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelStopConfirm()); });
520
- i0.ɵɵtext(16, " Cancel ");
572
+ i0.ɵɵelementStart(15, "button", 128);
573
+ 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()); });
574
+ i0.ɵɵtext(16, "Cancel");
521
575
  i0.ɵɵelementEnd()()()();
522
576
  } if (rf & 2) {
523
577
  const ctx_r1 = i0.ɵɵnextContext();
@@ -527,6 +581,7 @@ function SqlLoggingComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
527
581
  i0.ɵɵconditional(ctx_r1.isStoppingAll ? 9 : ctx_r1.sessionToStop ? 10 : -1);
528
582
  i0.ɵɵadvance(3);
529
583
  i0.ɵɵproperty("disabled", ctx_r1.loading);
584
+ i0.ɵɵattribute("aria-label", ctx_r1.isStoppingAll ? "Confirm stop all sessions" : "Confirm stop session");
530
585
  i0.ɵɵadvance();
531
586
  i0.ɵɵconditional(ctx_r1.loading ? 13 : 14);
532
587
  i0.ɵɵadvance(2);
@@ -553,6 +608,7 @@ function SqlLoggingComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
553
608
  */
554
609
  let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
555
610
  sharedService;
611
+ cdr;
556
612
  destroy$ = new Subject();
557
613
  /** Whether the component is currently performing an async operation */
558
614
  loading = false;
@@ -576,8 +632,12 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
576
632
  refreshInterval = 5000; // 5 seconds
577
633
  /** Whether the start session dialog is currently visible */
578
634
  showStartSessionDialog = false;
635
+ /** Whether to show the statistics cards section */
636
+ showStats = false;
579
637
  /** Whether the log viewer is in expanded (fullscreen) mode */
580
638
  isLogViewerExpanded = false;
639
+ /** Whether the start session dialog is in fullscreen mode */
640
+ isStartDialogFullscreen = false;
581
641
  /** Whether the stop session confirmation dialog is visible */
582
642
  showStopConfirmDialog = false;
583
643
  /** Session pending stop confirmation (single session or null for all) */
@@ -608,19 +668,20 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
608
668
  statementTypeOptions = [
609
669
  { text: 'Both Queries and Mutations', value: 'both' },
610
670
  { text: 'Queries Only', value: 'queries' },
611
- { text: 'Mutations Only', value: 'mutations' }
671
+ { text: 'Mutations Only', value: 'mutations' },
612
672
  ];
613
673
  /** Options for Regex filter */
614
674
  filterTypeOptions = [
615
675
  { text: 'Exclude Matching (default)', value: 'exclude' },
616
- { text: 'Include Matching Only', value: 'include' }
676
+ { text: 'Include Matching Only', value: 'include' },
617
677
  ];
618
- constructor(sharedService) {
678
+ constructor(sharedService, cdr) {
619
679
  super();
620
680
  this.sharedService = sharedService;
681
+ this.cdr = cdr;
621
682
  }
622
683
  async GetResourceDisplayName(data) {
623
- return "SQL Logging";
684
+ return 'SQL Logging';
624
685
  }
625
686
  initDashboard() {
626
687
  this.startAutoRefresh();
@@ -670,7 +731,7 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
670
731
  email: currentUser?.Email,
671
732
  type: currentUser?.Type,
672
733
  name: currentUser?.Name,
673
- id: currentUser?.ID
734
+ id: currentUser?.ID,
674
735
  });
675
736
  // Use the current user from Metadata
676
737
  const userToCheck = currentUser;
@@ -746,8 +807,8 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
746
807
  filterType: this.newSessionOptions.filterType,
747
808
  verboseOutput: this.newSessionOptions.verboseOutput,
748
809
  defaultSchemaName: this.newSessionOptions.defaultSchemaName,
749
- }
750
- }
810
+ },
811
+ },
751
812
  };
752
813
  const result = await dataProvider.ExecuteGQL(mutation, variables);
753
814
  if (result.errors) {
@@ -861,7 +922,7 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
861
922
  `;
862
923
  const variables = {
863
924
  sessionId: session.id,
864
- maxLines: 1000 // Limit to last 1000 lines for performance
925
+ maxLines: 1000, // Limit to last 1000 lines for performance
865
926
  };
866
927
  const result = await dataProvider.ExecuteGQL(query, variables);
867
928
  if (result.errors) {
@@ -884,11 +945,12 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
884
945
  }
885
946
  catch (error) {
886
947
  console.error('Error loading session log:', error);
887
- this.logContent = `-- Error loading log file --\n-- ${error.message || 'Unknown error occurred'} --\n\n` +
888
- `-- Session Info --\n` +
889
- `-- File: ${session.filePath}\n` +
890
- `-- Session: ${session.sessionName}\n` +
891
- `-- Started: ${new Date(session.startTime).toLocaleString()}\n`;
948
+ this.logContent =
949
+ `-- Error loading log file --\n-- ${error.message || 'Unknown error occurred'} --\n\n` +
950
+ `-- Session Info --\n` +
951
+ `-- File: ${session.filePath}\n` +
952
+ `-- Session: ${session.sessionName}\n` +
953
+ `-- Started: ${new Date(session.startTime).toLocaleString()}\n`;
892
954
  }
893
955
  }
894
956
  /**
@@ -933,6 +995,7 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
933
995
  console.log('Extracted config data:', configData);
934
996
  this.sqlLoggingConfig = configData || null;
935
997
  this.configEnabled = this.sqlLoggingConfig?.enabled || false;
998
+ this.cdr.detectChanges();
936
999
  console.log('Component state after update:');
937
1000
  console.log(' this.sqlLoggingConfig:', this.sqlLoggingConfig);
938
1001
  console.log(' this.configEnabled:', this.configEnabled);
@@ -980,10 +1043,11 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
980
1043
  const sessionsData = result?.activeSqlLoggingSessions;
981
1044
  console.log('Extracted sessions data:', sessionsData);
982
1045
  this.activeSessions = sessionsData || [];
1046
+ this.cdr.detectChanges();
983
1047
  // Update selected session if it still exists
984
1048
  if (this.selectedSession) {
985
1049
  const selectedId = this.selectedSession.id;
986
- const stillExists = this.activeSessions.find(s => s.id === selectedId);
1050
+ const stillExists = this.activeSessions.find((s) => s.id === selectedId);
987
1051
  if (stillExists) {
988
1052
  this.selectedSession = stillExists;
989
1053
  }
@@ -1031,7 +1095,7 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
1031
1095
  // Try to refresh SharedService data
1032
1096
  await SharedService.RefreshData(false);
1033
1097
  // Wait a moment for data to propagate
1034
- await new Promise(resolve => setTimeout(resolve, 1000));
1098
+ await new Promise((resolve) => setTimeout(resolve, 1000));
1035
1099
  // Re-check permissions
1036
1100
  await this.checkUserPermissions();
1037
1101
  console.log('Permissions refreshed');
@@ -1083,6 +1147,12 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
1083
1147
  toggleLogViewerExpand() {
1084
1148
  this.isLogViewerExpanded = !this.isLogViewerExpanded;
1085
1149
  }
1150
+ /**
1151
+ * Toggles the start session dialog between normal and fullscreen mode.
1152
+ */
1153
+ toggleStartDialogFullscreen() {
1154
+ this.isStartDialogFullscreen = !this.isStartDialogFullscreen;
1155
+ }
1086
1156
  /**
1087
1157
  * Handles keyboard events for the component.
1088
1158
  * Closes expanded log viewer or confirmation dialog when Escape is pressed.
@@ -1094,6 +1164,9 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
1094
1164
  else if (this.isLogViewerExpanded) {
1095
1165
  this.isLogViewerExpanded = false;
1096
1166
  }
1167
+ else if (this.isStartDialogFullscreen) {
1168
+ this.isStartDialogFullscreen = false;
1169
+ }
1097
1170
  else if (this.showStartSessionDialog) {
1098
1171
  this.showStartSessionDialog = false;
1099
1172
  }
@@ -1168,18 +1241,18 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
1168
1241
  this.loading = false;
1169
1242
  }
1170
1243
  }
1171
- static ɵfac = function SqlLoggingComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SqlLoggingComponent)(i0.ɵɵdirectiveInject(i1.SharedService)); };
1244
+ static ɵfac = function SqlLoggingComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SqlLoggingComponent)(i0.ɵɵdirectiveInject(i1.SharedService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
1172
1245
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SqlLoggingComponent, selectors: [["mj-sql-logging"]], hostBindings: function SqlLoggingComponent_HostBindings(rf, ctx) { if (rf & 1) {
1173
1246
  i0.ɵɵlistener("keydown.escape", function SqlLoggingComponent_keydown_escape_HostBindingHandler() { return ctx.onEscapeKey(); }, false, i0.ɵɵresolveDocument);
1174
- } }, features: [i0.ɵɵInheritDefinitionFeature], decls: 11, vars: 9, consts: [[1, "sql-logging-container"], [1, "action-buttons"], [1, "btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-refresh"], ["title", "Start SQL logging session", 1, "btn-primary", 3, "disabled"], [1, "stats-grid", 2, "display", "flex"], [1, "loading-container"], [1, "content-area"], [1, "modal-backdrop"], ["title", "Start SQL logging session", 1, "btn-primary", 3, "click", "disabled"], [1, "fa-solid", "fa-play"], [1, "stat-card"], [1, "stat-icon", "stat-icon-status"], [1, "fa-solid", "fa-power-off"], [1, "stat-content"], [1, "stat-value"], [1, "stat-label"], [1, "stat-icon", "stat-icon-active"], [1, "fa-solid", "fa-play-circle"], [1, "stat-icon", "stat-icon-limit"], [1, "fa-solid", "fa-gauge-high"], [1, "stat-icon", "stat-icon-total"], [1, "fa-solid", "fa-database"], [1, "loading-spinner"], [1, "spinner-ring"], [1, "loading-text"], [1, "empty-state"], [1, "sessions-layout"], [1, "fa-solid", "fa-lock", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], [1, "btn-secondary", 2, "margin-top", "1rem", 3, "click"], [1, "fa-solid", "fa-sync"], [1, "fa-solid", "fa-exclamation-triangle", "empty-icon", "warning"], [1, "info-box"], [1, "fa-solid", "fa-file-code", "empty-icon"], [1, "btn-primary", 2, "margin-top", "1rem", 3, "click"], [1, "sessions-panel"], [1, "panel-header"], [1, "panel-title"], ["title", "Stop all sessions", 1, "btn-danger", "btn-small", 3, "disabled"], [1, "sessions-list"], [1, "session-card", 3, "selected"], [1, "log-viewer-panel"], ["title", "Stop all sessions", 1, "btn-danger", "btn-small", 3, "click", "disabled"], [1, "fa-solid", "fa-stop"], [1, "session-card", 3, "click"], [1, "session-header"], [1, "session-info"], [1, "session-title"], [1, "session-meta"], [1, "meta-item"], [1, "fa-solid", "fa-clock"], ["title", "Stop session", 1, "action-btn", "action-btn-danger", 3, "click"], [1, "session-badges"], [1, "badge", "badge-user"], [1, "badge", "badge-migration"], [1, "badge", "badge-type"], [1, "fa-solid", "fa-user"], [1, "fa-solid", "fa-code-branch"], [1, "panel-actions"], [1, "checkbox-label"], ["type", "checkbox", 3, "ngModelChange", "ngModel"], ["title", "Refresh log", 1, "action-btn", 3, "click"], [1, "action-btn", 3, "click", "title"], [1, "fa-solid"], [1, "log-content"], [2, "height", "100%", 3, "value", "readonly", "disabled", "language", "setup", "lineWrapping", "highlightWhitespace"], [1, "fa-solid", "fa-arrow-left", "empty-icon"], [1, "modal-backdrop", 3, "click"], [1, "modal-dialog", "modal-large", 3, "click"], [1, "modal-header"], [1, "modal-title"], [1, "modal-close", 3, "click"], [1, "fa-solid", "fa-times"], [1, "modal-body"], [1, "form-group"], [1, "form-label"], ["type", "text", "placeholder", "Enter a descriptive name for this session", 1, "form-input", 3, "ngModelChange", "ngModel"], ["type", "text", "placeholder", "sql-log-2024-01-01.sql", 1, "form-input", 3, "ngModelChange", "ngModel"], [1, "form-hint"], [1, "form-select", 3, "ngModelChange", "ngModel"], [3, "value"], [1, "form-checkboxes"], [1, "form-section"], [1, "form-section-title"], [1, "fa-solid", "fa-filter"], ["rows", "4", "placeholder", "Examples:\n*AIPrompt*\n/spCreate.*Run/i\nSELECT * FROM vwMetadata", 1, "form-textarea", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-cog"], [1, "form-hint", 2, "margin-left", "1.5rem"], [1, "modal-footer"], [1, "btn-primary", 3, "click", "disabled"], [1, "btn-secondary", 3, "click"], ["type", "text", "placeholder", "__mj", 1, "form-input", 3, "ngModelChange", "ngModel"], [1, "confirm-dialog", 3, "click"], [1, "confirm-dialog-icon"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "confirm-dialog-content"], [1, "confirm-dialog-title"], [1, "confirm-dialog-message"], [1, "confirm-dialog-actions"], [1, "btn-danger", 3, "click", "disabled"], [1, "confirm-dialog-details"], [1, "fa-solid", "fa-spinner", "fa-spin"]], template: function SqlLoggingComponent_Template(rf, ctx) { if (rf & 1) {
1247
+ } }, 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"], [1, "action-btn", "action-btn-danger", 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"], ["aria-label", "Refresh log content", 1, "action-btn", 3, "click"], [1, "action-btn", 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) {
1175
1248
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "button", 2);
1176
1249
  i0.ɵɵlistener("click", function SqlLoggingComponent_Template_button_click_2_listener() { return ctx.loadActiveSessions(); });
1177
1250
  i0.ɵɵelement(3, "i", 3);
1178
1251
  i0.ɵɵtext(4, " Refresh ");
1179
1252
  i0.ɵɵelementEnd();
1180
- i0.ɵɵtemplate(5, SqlLoggingComponent_Conditional_5_Template, 3, 1, "button", 4);
1253
+ i0.ɵɵtemplate(5, SqlLoggingComponent_Conditional_5_Template, 3, 2, "button", 4);
1181
1254
  i0.ɵɵelementEnd();
1182
- i0.ɵɵtemplate(6, SqlLoggingComponent_Conditional_6_Template, 33, 4, "div", 5)(7, SqlLoggingComponent_Conditional_7_Template, 7, 0, "div", 6)(8, SqlLoggingComponent_Conditional_8_Template, 5, 1, "div", 7)(9, SqlLoggingComponent_Conditional_9_Template, 70, 11, "div", 8)(10, SqlLoggingComponent_Conditional_10_Template, 17, 5, "div", 8);
1255
+ i0.ɵɵtemplate(6, SqlLoggingComponent_Conditional_6_Template, 44, 13, "div", 5)(7, SqlLoggingComponent_Conditional_7_Template, 2, 0, "div", 6)(8, SqlLoggingComponent_Conditional_8_Template, 5, 1, "div", 7)(9, SqlLoggingComponent_Conditional_9_Template, 77, 19, "div", 8)(10, SqlLoggingComponent_Conditional_10_Template, 17, 6, "div", 9);
1183
1256
  i0.ɵɵelementEnd();
1184
1257
  } if (rf & 2) {
1185
1258
  i0.ɵɵadvance(2);
@@ -1198,7 +1271,7 @@ let SqlLoggingComponent = class SqlLoggingComponent extends BaseDashboard {
1198
1271
  i0.ɵɵconditional(ctx.showStartSessionDialog ? 9 : -1);
1199
1272
  i0.ɵɵadvance();
1200
1273
  i0.ɵɵconditional(ctx.showStopConfirmDialog ? 10 : -1);
1201
- } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent], styles: ["@keyframes _ngcontent-%COMP%_shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.sql-logging-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n max-width: 1400px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n.action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-bottom: 1.5rem;\n}\n@media (max-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n.btn-primary[_ngcontent-%COMP%]:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n.btn-secondary[_ngcontent-%COMP%]:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.btn-danger[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #f44336;\n color: white;\n}\n.btn-danger[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n.btn-danger[_ngcontent-%COMP%]:hover {\n background-color: #d32f2f;\n}\n.btn-danger.btn-small[_ngcontent-%COMP%] {\n padding: 0.375rem 0.75rem;\n font-size: 0.875rem;\n}\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n margin-bottom: 2rem;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0;\n}\n.stat-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n}\n.stat-icon-status[_ngcontent-%COMP%] {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n.stat-icon-active[_ngcontent-%COMP%] {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-limit[_ngcontent-%COMP%] {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n}\n.stat-icon-total[_ngcontent-%COMP%] {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n\n.stat-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n.stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n padding: 1.5rem;\n min-height: 400px;\n}\n\n.sessions-layout[_ngcontent-%COMP%] {\n display: flex;\n gap: 1.5rem;\n height: calc(100vh - 450px);\n min-height: 400px;\n max-height: 600px;\n}\n@media (max-width: 1024px) {\n .sessions-layout[_ngcontent-%COMP%] {\n flex-direction: column;\n height: auto;\n max-height: none;\n }\n}\n\n.sessions-panel[_ngcontent-%COMP%] {\n flex: 0 0 400px;\n display: flex;\n flex-direction: column;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n overflow: hidden;\n}\n@media (max-width: 1024px) {\n .sessions-panel[_ngcontent-%COMP%] {\n flex: 1;\n max-height: 400px;\n }\n}\n\n.panel-header[_ngcontent-%COMP%] {\n padding: 1rem;\n background: #f9fafb;\n border-bottom: 1px solid #e5e7eb;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n.panel-header[_ngcontent-%COMP%] .panel-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n}\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.sessions-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n padding: 0.75rem;\n}\n\n.session-card[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n padding: 1rem;\n margin-bottom: 0.75rem;\n cursor: pointer;\n transition: all 0.2s;\n}\n.session-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n.session-card.selected[_ngcontent-%COMP%] {\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\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}\n.session-info[_ngcontent-%COMP%] .session-title[_ngcontent-%COMP%] {\n margin: 0 0 0.5rem 0;\n font-size: 0.95rem;\n font-weight: 600;\n color: #1f2937;\n}\n\n.session-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n font-size: 0.75rem;\n color: #6b7280;\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}\n\n.badge[_ngcontent-%COMP%] {\n padding: 0.25rem 0.5rem;\n border-radius: 12px;\n font-size: 0.625rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n.badge-user[_ngcontent-%COMP%] {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.badge-migration[_ngcontent-%COMP%] {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n.badge-type[_ngcontent-%COMP%] {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n padding: 0.375rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n color: #374151;\n}\n.action-btn-danger[_ngcontent-%COMP%]:hover {\n color: #f44336;\n}\n\n.log-viewer-panel[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.log-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n background: #1e1e1e;\n color: #d4d4d4;\n padding: 0;\n min-height: 300px;\n height: 100%;\n position: relative;\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.log-content[_ngcontent-%COMP%] .cm-scroller {\n font-family: inherit;\n}\n.log-content[_ngcontent-%COMP%] .cm-content {\n background: #1e1e1e;\n color: #d4d4d4;\n}\n.log-content[_ngcontent-%COMP%] .cm-gutters {\n background: #252526;\n color: #858585;\n border-right: 1px solid #464647;\n}\n.log-content[_ngcontent-%COMP%] .cm-activeLineGutter {\n background: #2a2a2a;\n}\n.log-content[_ngcontent-%COMP%] .cm-activeLine {\n background: rgba(255, 255, 255, 0.04);\n}\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state[_ngcontent-%COMP%] .empty-icon.warning[_ngcontent-%COMP%] {\n color: #ffc107;\n}\n.empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n color: #6b7280;\n margin: 0;\n}\n\n.info-box[_ngcontent-%COMP%] {\n background: #f3f4f6;\n border-radius: 8px;\n padding: 1.5rem;\n margin-top: 2rem;\n text-align: left;\n max-width: 500px;\n margin-left: auto;\n margin-right: auto;\n}\n.info-box[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 1rem 0;\n color: #1f2937;\n}\n.info-box[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n margin: 0;\n padding-left: 1.25rem;\n color: #374151;\n}\n.info-box[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin-bottom: 0.5rem;\n}\n.info-box[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: #e5e7eb;\n padding: 0.125rem 0.375rem;\n border-radius: 4px;\n font-size: 0.875rem;\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 min-height: 400px;\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%] {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(2) {\n border-color: transparent #9c27b0 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(3) {\n border-color: transparent transparent #4caf50 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUp 0.3s ease;\n}\n.modal-dialog.modal-large[_ngcontent-%COMP%] {\n max-width: 700px;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n}\n.modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n}\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%] {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n max-height: 60vh;\n overflow-y: auto;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n.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: #374151;\n margin-bottom: 0.5rem;\n}\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n}\n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.form-select[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n background: white;\n cursor: pointer;\n transition: all 0.2s;\n}\n.form-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.form-hint[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: #6b7280;\n margin-top: 0.25rem;\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.5rem;\n color: #374151;\n font-size: 0.95rem;\n cursor: pointer;\n}\n.checkbox-label[_ngcontent-%COMP%] input[type=checkbox][_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n\n\n.form-section[_ngcontent-%COMP%] {\n margin-top: 1.5rem;\n padding: 1.25rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: #f9fafb;\n}\n\n.form-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin: 0 0 1rem 0;\n font-size: 1rem;\n font-weight: 600;\n color: #374151;\n}\n\n.form-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6b7280;\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n resize: vertical;\n transition: all 0.2s;\n}\n\n.form-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.form-textarea[_ngcontent-%COMP%]::placeholder {\n color: #9ca3af;\n font-style: italic;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes _ngcontent-%COMP%_slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\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 ease;\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@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\n\n.confirm-dialog[_ngcontent-%COMP%] {\n background: white;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\n max-width: 420px;\n width: 90%;\n padding: 2rem;\n text-align: center;\n animation: _ngcontent-%COMP%_dialogBounce 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_dialogBounce {\n 0% {\n transform: scale(0.9) translateY(10px);\n opacity: 0;\n }\n 50% {\n transform: scale(1.02) translateY(-5px);\n }\n 100% {\n transform: scale(1) translateY(0);\n opacity: 1;\n }\n}\n\n.confirm-dialog-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 1.5rem;\n box-shadow: 0 4px 12px rgba(255, 152, 0, 0.2);\n}\n\n.confirm-dialog-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n color: #f57c00;\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: 700;\n color: #1f2937;\n}\n\n.confirm-dialog-message[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.95rem;\n color: #4b5563;\n line-height: 1.6;\n}\n\n.confirm-dialog-message[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: #1f2937;\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: #f3f4f6;\n border-radius: 8px;\n font-size: 0.875rem;\n color: #6b7280;\n}\n\n.confirm-dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n justify-content: center;\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}"] });
1274
+ } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent, i4.LoadingComponent], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n \n\n --md-primary: #0076B6;\n --md-on-primary: #FFFFFF;\n --md-primary-container: #AAE7FD;\n --md-on-primary-container: #001F2A;\n\n \n\n --md-secondary: #F5A623;\n --md-on-secondary: #FFFFFF;\n --md-secondary-container: #FFECD6;\n --md-on-secondary-container: #2D1600;\n\n \n\n --md-tertiary: #4CAF50;\n --md-on-tertiary: #FFFFFF;\n --md-tertiary-container: #C8E6C9;\n --md-on-tertiary-container: #002204;\n\n \n\n --md-error: #D32F2F;\n --md-on-error: #FFFFFF;\n --md-error-container: #FFCDD2;\n --md-on-error-container: #410002;\n\n \n\n --md-surface: #FAFCFF;\n --md-surface-container-lowest: #FFFFFF;\n --md-surface-container-low: #F3F5F9;\n --md-surface-container: #EDF0F4;\n --md-surface-container-high: #E7EAEE;\n --md-surface-container-highest: #E1E3E8;\n --md-on-surface: #191C20;\n --md-on-surface-variant: #43474E;\n --md-outline: #74777F;\n --md-outline-variant: #C4C6D0;\n\n \n\n --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n --md-elevation-2: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n --md-elevation-3: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08);\n --md-elevation-4: 0 6px 12px rgba(0, 0, 0, 0.1), 0 12px 24px rgba(0, 0, 0, 0.08);\n --md-elevation-5: 0 8px 16px rgba(0, 0, 0, 0.12), 0 16px 32px rgba(0, 0, 0, 0.1);\n\n \n\n --md-corner-extra-small: 4px;\n --md-corner-small: 8px;\n --md-corner-medium: 12px;\n --md-corner-large: 16px;\n --md-corner-extra-large: 28px;\n --md-corner-full: 9999px;\n\n \n\n display: 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(--md-surface);\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 display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\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(--md-corner-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n min-width: 44px;\n}\n\n\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.btn-primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #4BA5D4;\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(--md-surface);\n color: var(--md-primary);\n border: 1px solid var(--md-outline);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #005A8C;\n border-color: #005A8C;\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(--md-error);\n color: var(--md-on-error);\n box-shadow: var(--md-elevation-1);\n}\n\n.btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #E57373;\n box-shadow: var(--md-elevation-2);\n}\n\n.btn-danger[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #EF9A9A;\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(--md-surface-container-low);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.stats-toggle-button[_ngcontent-%COMP%]:hover {\n background: var(--md-surface-container);\n border-color: var(--md-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.stats-toggle-button.expanded[_ngcontent-%COMP%] {\n border-color: var(--md-primary);\n background: var(--md-primary-container);\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(--md-corner-medium);\n background: var(--md-primary-container);\n color: var(--md-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(--md-primary);\n color: var(--md-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(--md-on-surface);\n margin: 0;\n}\n\n.stats-toggle-button.expanded[_ngcontent-%COMP%] .stats-toggle-title[_ngcontent-%COMP%] {\n color: var(--md-primary);\n}\n\n.stats-toggle-subtitle[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n.stats-toggle-arrow[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n color: var(--md-on-surface-variant);\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(--md-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 \n\n .stats-toggle-button[_ngcontent-%COMP%] {\n display: none;\n }\n\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(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n padding: 1.25rem;\n box-shadow: var(--md-elevation-1);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--md-outline-variant);\n cursor: default;\n}\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--md-corner-medium);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n flex-shrink: 0;\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(--md-tertiary-container);\n color: var(--md-tertiary);\n}\n\n.stat-icon-active[_ngcontent-%COMP%] {\n background: var(--md-primary-container);\n color: var(--md-primary);\n}\n\n.stat-icon-limit[_ngcontent-%COMP%] {\n background: var(--md-secondary-container);\n color: #B5751A;\n}\n\n.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--md-tertiary-container);\n color: var(--md-tertiary);\n}\n\n.stat-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--md-on-surface);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (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.stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface-variant);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 0.25rem;\n}\n\n\n\n\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1;\n overflow: visible;\n min-height: 0;\n position: relative;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n padding: 1rem;\n}\n\n@media (min-width: 640px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.5rem;\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(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n overflow: hidden;\n background: var(--md-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(--md-surface-container-low);\n border-bottom: 1px solid var(--md-outline-variant);\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(--md-on-surface);\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 \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(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\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(--md-elevation-1);\n border-color: var(--md-primary);\n}\n\n.session-card.selected[_ngcontent-%COMP%] {\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--md-primary-container);\n}\n\n.session-card[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-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(--md-on-surface);\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(--md-on-surface-variant);\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(--md-corner-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(--md-primary-container);\n color: var(--md-primary);\n border: 1px solid var(--md-primary);\n}\n\n.badge-migration[_ngcontent-%COMP%] {\n background: var(--md-tertiary-container);\n color: #1B5E20;\n border: 1px solid var(--md-tertiary);\n}\n\n.badge-type[_ngcontent-%COMP%] {\n background: var(--md-secondary-container);\n color: #7A4D0C;\n border: 1px solid var(--md-secondary);\n}\n\n\n\n\n\n.action-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n border-radius: var(--md-corner-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(--md-primary);\n color: var(--md-on-primary);\n}\n\n.action-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.action-btn-danger[_ngcontent-%COMP%]:hover {\n background: var(--md-error);\n color: var(--md-on-error);\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(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n overflow: hidden;\n background: var(--md-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: #1e1e1e;\n color: #d4d4d4;\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: #1e1e1e;\n color: #d4d4d4;\n}\n\n.log-content[_ngcontent-%COMP%] .cm-gutters {\n background: #252526;\n color: #858585;\n border-right: 1px solid #464647;\n}\n\n.log-content[_ngcontent-%COMP%] .cm-activeLineGutter {\n background: #2a2a2a;\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%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 4rem 2rem;\n gap: 1rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--md-outline-variant);\n margin-bottom: 0.5rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-icon.warning[_ngcontent-%COMP%] {\n color: var(--md-secondary);\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n max-width: 400px;\n}\n\n\n\n\n\n.info-box[_ngcontent-%COMP%] {\n background: var(--md-surface-container);\n border-radius: var(--md-corner-medium);\n padding: 1.5rem;\n margin-top: 1.5rem;\n text-align: left;\n max-width: 500px;\n border: 1px solid var(--md-outline-variant);\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(--md-on-surface);\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(--md-on-surface);\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(--md-surface-container-high);\n padding: 0.125rem 0.5rem;\n border-radius: var(--md-corner-extra-small);\n font-size: 0.8125rem;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n color: var(--md-on-surface);\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 min-height: 300px;\n}\n\n.loading-text[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n margin-top: 1rem;\n}\n\n\n\n\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n 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(--md-surface);\n border-radius: var(--md-corner-extra-large);\n box-shadow: var(--md-elevation-5);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideUp 0.3s cubic-bezier(0, 0, 0.2, 1);\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: 20px;\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 display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--md-outline-variant);\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-header[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n}\n\n\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(--md-on-surface-variant);\n font-size: 1.125rem;\n cursor: pointer;\n border-radius: var(--md-corner-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(--md-primary);\n color: var(--md-on-primary);\n}\n\n.modal-action-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--md-corner-full);\n transition: all 0.2s 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.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\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 display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--md-outline-variant);\n background: var(--md-surface-container-low);\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-footer[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n flex-direction: column;\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(--md-on-surface);\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(--md-outline-variant);\n border-radius: var(--md-corner-small);\n font-size: 1rem;\n background: var(--md-surface);\n color: var(--md-on-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.form-input[_ngcontent-%COMP%]:hover, \n.form-select[_ngcontent-%COMP%]:hover, \n.form-textarea[_ngcontent-%COMP%]:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\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(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--md-surface);\n}\n\n.form-input[_ngcontent-%COMP%]::placeholder, \n.form-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--md-on-surface-variant);\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(--md-on-surface-variant);\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(--md-on-surface);\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(--md-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(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n background: var(--md-surface-container-low);\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(--md-on-surface);\n}\n\n.form-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-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(--md-surface);\n border-radius: var(--md-corner-extra-large);\n box-shadow: var(--md-elevation-5);\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: 20px;\n }\n}\n\n.confirm-dialog-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: var(--md-secondary-container);\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: #B5751A;\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(--md-on-surface);\n}\n\n.confirm-dialog-message[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n line-height: 1.6;\n}\n\n.confirm-dialog-message[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--md-on-surface);\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(--md-surface-container);\n border-radius: var(--md-corner-small);\n font-size: 0.8125rem;\n color: var(--md-on-surface-variant);\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%_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%_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@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\nbutton[_ngcontent-%COMP%]:focus-visible, \ninput[_ngcontent-%COMP%]:focus-visible, \nselect[_ngcontent-%COMP%]:focus-visible, \ntextarea[_ngcontent-%COMP%]:focus-visible, \na[_ngcontent-%COMP%]:focus-visible, \n[tabindex][_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\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}"] });
1202
1275
  };
1203
1276
  SqlLoggingComponent = __decorate([
1204
1277
  RegisterClass(BaseDashboard, 'SqlLogging')
@@ -1206,8 +1279,8 @@ SqlLoggingComponent = __decorate([
1206
1279
  export { SqlLoggingComponent };
1207
1280
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SqlLoggingComponent, [{
1208
1281
  type: Component,
1209
- args: [{ selector: 'mj-sql-logging', template: "<div class=\"sql-logging-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button class=\"btn-secondary\" (click)=\"loadActiveSessions()\" [disabled]=\"loading\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"loading\"></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 title=\"Start SQL logging session\"\n >\n <i class=\"fa-solid fa-play\"></i>\n Start New Session\n </button>\n }\n </div>\n\n <!-- Stats Cards -->\n @if (isOwner && configEnabled) {\n <div class=\"stats-grid\" style=\"display: flex\">\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-status\">\n <i class=\"fa-solid fa-power-off\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ configEnabled ? 'Enabled' : 'Disabled' }}</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\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ activeSessions.length }}</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\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ sqlLoggingConfig?.maxActiveSessions || 5 }}</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\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getTotalStatementCount() }}</div>\n <div class=\"stat-label\">Total Statements</div>\n </div>\n </div>\n </div>\n }\n\n <!-- Loading State -->\n @if (loading && !activeSessions.length) {\n <div class=\"loading-container\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading SQL logging configuration...</div>\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\">\n <i class=\"fa-solid fa-lock empty-icon\"></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 \n class=\"btn-secondary\"\n (click)=\"refreshUserPermissions()\"\n style=\"margin-top: 1rem\"\n >\n <i class=\"fa-solid fa-sync\"></i>\n Refresh Permissions\n </button>\n </div>\n } @else if (!configEnabled) {\n <!-- Not enabled in config -->\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-exclamation-triangle empty-icon warning\"></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\">\n <i class=\"fa-solid fa-file-code empty-icon\"></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 \n class=\"btn-primary\"\n (click)=\"openStartSessionDialog()\"\n style=\"margin-top: 1rem\"\n >\n <i class=\"fa-solid fa-play\"></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\">\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 title=\"Stop all sessions\"\n >\n <i class=\"fa-solid fa-stop\"></i>\n Stop All\n </button>\n }\n </div>\n <div class=\"sessions-list\">\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 >\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\"></i>\n {{ getSessionDuration(session.startTime) }}\n </span>\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-database\"></i>\n {{ session.statementCount }} statements\n </span>\n </div>\n </div>\n <button\n class=\"action-btn action-btn-danger\"\n (click)=\"openStopSessionConfirm(session, $event)\"\n title=\"Stop session\"\n >\n <i class=\"fa-solid fa-stop\"></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\"></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\"></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\">\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 />\n Auto-refresh\n </label>\n <button\n class=\"action-btn\"\n (click)=\"loadSessionLog(selectedSession)\"\n title=\"Refresh log\"\n >\n <i class=\"fa-solid fa-sync\" [class.fa-spin]=\"loading\"></i>\n </button>\n <button\n class=\"action-btn\"\n (click)=\"toggleLogViewerExpand()\"\n [title]=\"isLogViewerExpanded ? 'Collapse' : 'Expand'\"\n >\n <i class=\"fa-solid\" [class.fa-expand]=\"!isLogViewerExpanded\" [class.fa-compress]=\"isLogViewerExpanded\"></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 ></mj-code-editor>\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-arrow-left empty-icon\"></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 class=\"modal-backdrop\" (click)=\"showStartSessionDialog = false\">\n <div class=\"modal-dialog modal-large\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\">\n <i class=\"fa-solid fa-play\"></i>\n Start SQL Logging Session\n </h3>\n <button class=\"modal-close\" (click)=\"showStartSessionDialog = false\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"form-group\">\n <label class=\"form-label\">Session Name</label>\n <input \n type=\"text\"\n class=\"form-input\" \n [(ngModel)]=\"newSessionOptions.sessionName\"\n placeholder=\"Enter a descriptive name for this session\"\n />\n </div>\n \n <div class=\"form-group\">\n <label class=\"form-label\">File Name</label>\n <input \n type=\"text\"\n class=\"form-input\" \n [(ngModel)]=\"newSessionOptions.fileName\"\n placeholder=\"sql-log-2024-01-01.sql\"\n />\n <div 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\">Statement Types</label>\n <select\n class=\"form-select\"\n [(ngModel)]=\"newSessionOptions.statementTypes\"\n >\n @for (option of statementTypeOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.text }}</option>\n }\n </select>\n </div>\n \n <div class=\"form-checkboxes\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"newSessionOptions.filterToCurrentUser\"\n />\n Filter to my SQL statements only\n </label>\n\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"newSessionOptions.formatAsMigration\"\n />\n Format as migration file\n </label>\n\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"newSessionOptions.prettyPrint\"\n />\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\"></i>\n SQL Pattern Filtering\n </h4>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Filter Mode</label>\n <select\n class=\"form-select\"\n [(ngModel)]=\"newSessionOptions.filterType\"\n >\n @for (option of filterTypeOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.text }}</option>\n }\n </select>\n <div class=\"form-hint\">\n Exclude: Skip SQL matching any pattern. Include: Only log SQL matching a pattern.\n </div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"form-label\">Filter Patterns (one per line or comma-separated)</label>\n <textarea\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 ></textarea>\n <div class=\"form-hint\">\n Supports wildcards (*) and regex (/pattern/flags).\n Example: *spCreate* matches any SP starting with spCreate.\n </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\"></i>\n Advanced Options\n </h4>\n\n @if (newSessionOptions.formatAsMigration) {\n <div class=\"form-group\">\n <label class=\"form-label\">Default Schema Name</label>\n <input\n type=\"text\"\n class=\"form-input\"\n [(ngModel)]=\"newSessionOptions.defaultSchemaName\"\n placeholder=\"__mj\"\n />\n <div class=\"form-hint\">\n Schema name to replace with $&#123;flyway:defaultSchema&#125; placeholder.\n </div>\n </div>\n }\n\n <div class=\"form-checkboxes\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"newSessionOptions.verboseOutput\"\n />\n Verbose Debug Output\n </label>\n <div class=\"form-hint\" style=\"margin-left: 1.5rem;\">\n Log detailed filter decisions to server console (for debugging).\n </div>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button class=\"btn-primary\" (click)=\"startNewSession()\" [disabled]=\"loading\">\n <i class=\"fa-solid fa-play\"></i>\n Start Session\n </button>\n <button class=\"btn-secondary\" (click)=\"showStartSessionDialog = false\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Stop Session Confirmation Dialog -->\n @if (showStopConfirmDialog) {\n <div class=\"modal-backdrop\" (click)=\"cancelStopConfirm()\">\n <div class=\"confirm-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"confirm-dialog-icon\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n </div>\n <div class=\"confirm-dialog-content\">\n <h3 class=\"confirm-dialog-title\">\n @if (isStoppingAll) {\n Stop All Sessions?\n } @else {\n Stop Session?\n }\n </h3>\n <p class=\"confirm-dialog-message\">\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\">\n This session has captured {{ sessionToStop.statementCount }} SQL statements.\n </span>\n }\n </p>\n </div>\n <div class=\"confirm-dialog-actions\">\n <button\n class=\"btn-danger\"\n (click)=\"confirmStopSession()\"\n [disabled]=\"loading\"\n >\n @if (loading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Stopping...\n } @else {\n <i class=\"fa-solid fa-stop\"></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\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n</div>", styles: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.sql-logging-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n max-width: 1400px;\n margin: 0 auto;\n padding: 2rem;\n}\n\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-bottom: 1.5rem;\n}\n@media (max-width: 768px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n.btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary i {\n font-size: 0.875rem;\n}\n.btn-primary:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n\n.btn-secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary i {\n font-size: 0.875rem;\n}\n.btn-secondary:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #f44336;\n color: white;\n}\n.btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-danger i {\n font-size: 0.875rem;\n}\n.btn-danger:hover {\n background-color: #d32f2f;\n}\n.btn-danger.btn-small {\n padding: 0.375rem 0.75rem;\n font-size: 0.875rem;\n}\n\n.stats-grid {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n margin-bottom: 2rem;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0;\n}\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.stat-icon {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n}\n.stat-icon-status {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n.stat-icon-active {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-limit {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n}\n.stat-icon-total {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n\n.stat-content {\n flex: 1;\n}\n.stat-content .stat-value {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content .stat-label {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.content-area {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n padding: 1.5rem;\n min-height: 400px;\n}\n\n.sessions-layout {\n display: flex;\n gap: 1.5rem;\n height: calc(100vh - 450px);\n min-height: 400px;\n max-height: 600px;\n}\n@media (max-width: 1024px) {\n .sessions-layout {\n flex-direction: column;\n height: auto;\n max-height: none;\n }\n}\n\n.sessions-panel {\n flex: 0 0 400px;\n display: flex;\n flex-direction: column;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n overflow: hidden;\n}\n@media (max-width: 1024px) {\n .sessions-panel {\n flex: 1;\n max-height: 400px;\n }\n}\n\n.panel-header {\n padding: 1rem;\n background: #f9fafb;\n border-bottom: 1px solid #e5e7eb;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n.panel-header .panel-title {\n margin: 0;\n font-size: 1.125rem;\n font-weight: 600;\n color: #1f2937;\n}\n\n.panel-actions {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.sessions-list {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n padding: 0.75rem;\n}\n\n.session-card {\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n padding: 1rem;\n margin-bottom: 0.75rem;\n cursor: pointer;\n transition: all 0.2s;\n}\n.session-card:hover {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n.session-card.selected {\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\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}\n.session-info .session-title {\n margin: 0 0 0.5rem 0;\n font-size: 0.95rem;\n font-weight: 600;\n color: #1f2937;\n}\n\n.session-meta {\n display: flex;\n gap: 1rem;\n font-size: 0.75rem;\n color: #6b7280;\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}\n\n.badge {\n padding: 0.25rem 0.5rem;\n border-radius: 12px;\n font-size: 0.625rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n.badge-user {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.badge-migration {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n.badge-type {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n}\n\n.action-btn {\n padding: 0.375rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.action-btn:hover {\n background: #f3f4f6;\n color: #374151;\n}\n.action-btn-danger:hover {\n color: #f44336;\n}\n\n.log-viewer-panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.log-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n background: #1e1e1e;\n color: #d4d4d4;\n padding: 0;\n min-height: 300px;\n height: 100%;\n position: relative;\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.log-content ::ng-deep .cm-scroller {\n font-family: inherit;\n}\n.log-content ::ng-deep .cm-content {\n background: #1e1e1e;\n color: #d4d4d4;\n}\n.log-content ::ng-deep .cm-gutters {\n background: #252526;\n color: #858585;\n border-right: 1px solid #464647;\n}\n.log-content ::ng-deep .cm-activeLineGutter {\n background: #2a2a2a;\n}\n.log-content ::ng-deep .cm-activeLine {\n background: rgba(255, 255, 255, 0.04);\n}\n\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state .empty-icon {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state .empty-icon.warning {\n color: #ffc107;\n}\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state .empty-subtext {\n color: #6b7280;\n margin: 0;\n}\n\n.info-box {\n background: #f3f4f6;\n border-radius: 8px;\n padding: 1.5rem;\n margin-top: 2rem;\n text-align: left;\n max-width: 500px;\n margin-left: auto;\n margin-right: auto;\n}\n.info-box h4 {\n margin: 0 0 1rem 0;\n color: #1f2937;\n}\n.info-box ol {\n margin: 0;\n padding-left: 1.25rem;\n color: #374151;\n}\n.info-box ol li {\n margin-bottom: 0.5rem;\n}\n.info-box code {\n background: #e5e7eb;\n padding: 0.125rem 0.375rem;\n border-radius: 4px;\n font-size: 0.875rem;\n}\n\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n min-height: 400px;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n}\n.loading-spinner .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n}\n.loading-spinner .spinner-ring:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner .spinner-ring:nth-child(2) {\n border-color: transparent #9c27b0 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner .spinner-ring:nth-child(3) {\n border-color: transparent transparent #4caf50 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.modal-dialog {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s ease;\n}\n.modal-dialog.modal-large {\n max-width: 700px;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n}\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n}\n.modal-header .modal-close {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.modal-header .modal-close:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body {\n padding: 1.5rem;\n max-height: 60vh;\n overflow-y: auto;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n.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: #374151;\n margin-bottom: 0.5rem;\n}\n\n.form-input {\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n}\n.form-input:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.form-select {\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n background: white;\n cursor: pointer;\n transition: all 0.2s;\n}\n.form-select:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.form-hint {\n font-size: 0.75rem;\n color: #6b7280;\n margin-top: 0.25rem;\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.5rem;\n color: #374151;\n font-size: 0.95rem;\n cursor: pointer;\n}\n.checkbox-label input[type=checkbox] {\n cursor: pointer;\n}\n\n/* Form Section Styles */\n.form-section {\n margin-top: 1.5rem;\n padding: 1.25rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: #f9fafb;\n}\n\n.form-section-title {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin: 0 0 1rem 0;\n font-size: 1rem;\n font-weight: 600;\n color: #374151;\n}\n\n.form-section-title i {\n color: #6b7280;\n}\n\n.form-textarea {\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n resize: vertical;\n transition: all 0.2s;\n}\n\n.form-textarea:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.form-textarea::placeholder {\n color: #9ca3af;\n font-style: italic;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n/* Expanded Log Viewer Styles */\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 ease;\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@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/* Confirmation Dialog Styles */\n.confirm-dialog {\n background: white;\n border-radius: 16px;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\n max-width: 420px;\n width: 90%;\n padding: 2rem;\n text-align: center;\n animation: dialogBounce 0.3s ease;\n}\n\n@keyframes dialogBounce {\n 0% {\n transform: scale(0.9) translateY(10px);\n opacity: 0;\n }\n 50% {\n transform: scale(1.02) translateY(-5px);\n }\n 100% {\n transform: scale(1) translateY(0);\n opacity: 1;\n }\n}\n\n.confirm-dialog-icon {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 1.5rem;\n box-shadow: 0 4px 12px rgba(255, 152, 0, 0.2);\n}\n\n.confirm-dialog-icon i {\n font-size: 1.75rem;\n color: #f57c00;\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: 700;\n color: #1f2937;\n}\n\n.confirm-dialog-message {\n margin: 0;\n font-size: 0.95rem;\n color: #4b5563;\n line-height: 1.6;\n}\n\n.confirm-dialog-message strong {\n color: #1f2937;\n font-weight: 600;\n}\n\n.confirm-dialog-details {\n display: block;\n margin-top: 0.75rem;\n padding: 0.75rem;\n background: #f3f4f6;\n border-radius: 8px;\n font-size: 0.875rem;\n color: #6b7280;\n}\n\n.confirm-dialog-actions {\n display: flex;\n gap: 0.75rem;\n justify-content: center;\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"] }]
1210
- }], () => [{ type: i1.SharedService }], { onEscapeKey: [{
1282
+ args: [{ 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\n class=\"action-btn action-btn-danger\"\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\n class=\"action-btn\"\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\n class=\"action-btn\"\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 SQL Logging Component - Material Design 3 Styles\n Following MD3 Design System with custom color palette and design tokens\n ============================================================================= */\n\n/* MD3 Design Tokens - Color Palette */\n:host {\n /* Primary - Deep Blue */\n --md-primary: #0076B6;\n --md-on-primary: #FFFFFF;\n --md-primary-container: #AAE7FD;\n --md-on-primary-container: #001F2A;\n\n /* Secondary - Light Orange */\n --md-secondary: #F5A623;\n --md-on-secondary: #FFFFFF;\n --md-secondary-container: #FFECD6;\n --md-on-secondary-container: #2D1600;\n\n /* Tertiary - Light Green */\n --md-tertiary: #4CAF50;\n --md-on-tertiary: #FFFFFF;\n --md-tertiary-container: #C8E6C9;\n --md-on-tertiary-container: #002204;\n\n /* Error - Red */\n --md-error: #D32F2F;\n --md-on-error: #FFFFFF;\n --md-error-container: #FFCDD2;\n --md-on-error-container: #410002;\n\n /* Surface Colors */\n --md-surface: #FAFCFF;\n --md-surface-container-lowest: #FFFFFF;\n --md-surface-container-low: #F3F5F9;\n --md-surface-container: #EDF0F4;\n --md-surface-container-high: #E7EAEE;\n --md-surface-container-highest: #E1E3E8;\n --md-on-surface: #191C20;\n --md-on-surface-variant: #43474E;\n --md-outline: #74777F;\n --md-outline-variant: #C4C6D0;\n\n /* Elevation (Box Shadows) */\n --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n --md-elevation-2: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n --md-elevation-3: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08);\n --md-elevation-4: 0 6px 12px rgba(0, 0, 0, 0.1), 0 12px 24px rgba(0, 0, 0, 0.08);\n --md-elevation-5: 0 8px 16px rgba(0, 0, 0, 0.12), 0 16px 32px rgba(0, 0, 0, 0.1);\n\n /* Corner Radii */\n --md-corner-extra-small: 4px;\n --md-corner-small: 8px;\n --md-corner-medium: 12px;\n --md-corner-large: 16px;\n --md-corner-extra-large: 28px;\n --md-corner-full: 9999px;\n\n /* Host element layout */\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(--md-surface);\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\n ----------------------------------------------------------------------------- */\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\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 - MD3 Pattern\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(--md-corner-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n min-width: 44px;\n}\n\n/* Primary Button - Dark blue, lightens on hover */\n.btn-primary {\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.btn-primary:active:not(:disabled) {\n background: #4BA5D4;\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 - Light, darkens/fills on hover */\n.btn-secondary {\n background: var(--md-surface);\n color: var(--md-primary);\n border: 1px solid var(--md-outline);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.btn-secondary:active:not(:disabled) {\n background: #005A8C;\n border-color: #005A8C;\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 - Dark red, lightens on hover */\n.btn-danger {\n background: var(--md-error);\n color: var(--md-on-error);\n box-shadow: var(--md-elevation-1);\n}\n\n.btn-danger:hover:not(:disabled) {\n background: #E57373;\n box-shadow: var(--md-elevation-2);\n}\n\n.btn-danger:active:not(:disabled) {\n background: #EF9A9A;\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 - MD3 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(--md-surface-container-low);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.stats-toggle-button:hover {\n background: var(--md-surface-container);\n border-color: var(--md-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.stats-toggle-button.expanded {\n border-color: var(--md-primary);\n background: var(--md-primary-container);\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(--md-corner-medium);\n background: var(--md-primary-container);\n color: var(--md-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(--md-primary);\n color: var(--md-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(--md-on-surface);\n margin: 0;\n}\n\n.stats-toggle-button.expanded .stats-toggle-title {\n color: var(--md-primary);\n}\n\n.stats-toggle-subtitle {\n font-size: 0.8125rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n.stats-toggle-arrow {\n font-size: 1.25rem;\n color: var(--md-on-surface-variant);\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(--md-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 /* Hide toggle button on desktop - stats always visible */\n .stats-toggle-button {\n display: none;\n }\n\n /* Always show stats grid on desktop */\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 - Non-interactive */\n.stat-card {\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n padding: 1.25rem;\n box-shadow: var(--md-elevation-1);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--md-outline-variant);\n cursor: default;\n}\n\n.stat-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--md-corner-medium);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n flex-shrink: 0;\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(--md-tertiary-container);\n color: var(--md-tertiary);\n}\n\n.stat-icon-active {\n background: var(--md-primary-container);\n color: var(--md-primary);\n}\n\n.stat-icon-limit {\n background: var(--md-secondary-container);\n color: #B5751A;\n}\n\n.stat-icon-total {\n background: var(--md-tertiary-container);\n color: var(--md-tertiary);\n}\n\n.stat-content {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content .stat-value {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--md-on-surface);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (max-width: 639px) {\n .stat-content .stat-value {\n font-size: 1.5rem;\n font-weight: 700;\n }\n}\n\n.stat-content .stat-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface-variant);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 0.25rem;\n}\n\n/* -----------------------------------------------------------------------------\n Content Area\n ----------------------------------------------------------------------------- */\n.content-area {\n flex: 1;\n overflow: visible;\n min-height: 0;\n position: relative;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n padding: 1rem;\n}\n\n@media (min-width: 640px) {\n .content-area {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .content-area {\n padding: 1.5rem;\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(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n overflow: hidden;\n background: var(--md-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(--md-surface-container-low);\n border-bottom: 1px solid var(--md-outline-variant);\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(--md-on-surface);\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 /* Hide checkbox label text on mobile, show only checkbox */\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(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\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(--md-elevation-1);\n border-color: var(--md-primary);\n}\n\n.session-card.selected {\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--md-primary-container);\n}\n\n.session-card:focus-visible {\n outline: 2px solid var(--md-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(--md-on-surface);\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(--md-on-surface-variant);\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 - MD3 Chips\n ----------------------------------------------------------------------------- */\n.badge {\n padding: 0.375rem 0.875rem;\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n}\n\n.badge-user {\n background: var(--md-primary-container);\n color: var(--md-primary);\n border: 1px solid var(--md-primary);\n}\n\n.badge-migration {\n background: var(--md-tertiary-container);\n color: #1B5E20;\n border: 1px solid var(--md-tertiary);\n}\n\n.badge-type {\n background: var(--md-secondary-container);\n color: #7A4D0C;\n border: 1px solid var(--md-secondary);\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(--md-on-surface-variant);\n font-size: 1rem;\n border-radius: var(--md-corner-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(--md-primary);\n color: var(--md-on-primary);\n}\n\n.action-btn:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.action-btn-danger:hover {\n background: var(--md-error);\n color: var(--md-on-error);\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(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n overflow: hidden;\n background: var(--md-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 (per design guide exception) */\n.log-content {\n flex: 1;\n overflow: hidden;\n min-height: 300px;\n height: 100%;\n position: relative;\n background: #1e1e1e;\n color: #d4d4d4;\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: #1e1e1e;\n color: #d4d4d4;\n}\n\n.log-content ::ng-deep .cm-gutters {\n background: #252526;\n color: #858585;\n border-right: 1px solid #464647;\n}\n\n.log-content ::ng-deep .cm-activeLineGutter {\n background: #2a2a2a;\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 - MD3 Pattern\n ----------------------------------------------------------------------------- */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 4rem 2rem;\n gap: 1rem;\n}\n\n.empty-state .empty-icon {\n font-size: 4rem;\n color: var(--md-outline-variant);\n margin-bottom: 0.5rem;\n}\n\n.empty-state .empty-icon.warning {\n color: var(--md-secondary);\n}\n\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n}\n\n.empty-state .empty-subtext {\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n max-width: 400px;\n}\n\n/* -----------------------------------------------------------------------------\n Info Box\n ----------------------------------------------------------------------------- */\n.info-box {\n background: var(--md-surface-container);\n border-radius: var(--md-corner-medium);\n padding: 1.5rem;\n margin-top: 1.5rem;\n text-align: left;\n max-width: 500px;\n border: 1px solid var(--md-outline-variant);\n}\n\n.info-box h4 {\n margin: 0 0 1rem 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n.info-box ol {\n margin: 0;\n padding-left: 1.25rem;\n font-size: 1rem;\n color: var(--md-on-surface);\n}\n\n.info-box ol li {\n margin-bottom: 0.5rem;\n}\n\n.info-box code {\n background: var(--md-surface-container-high);\n padding: 0.125rem 0.5rem;\n border-radius: var(--md-corner-extra-small);\n font-size: 0.8125rem;\n font-family: \"Consolas\", \"Monaco\", \"Courier New\", monospace;\n color: var(--md-on-surface);\n}\n\n/* -----------------------------------------------------------------------------\n Loading Container - Uses mj-loading component\n ----------------------------------------------------------------------------- */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n min-height: 300px;\n}\n\n.loading-text {\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n margin-top: 1rem;\n}\n\n/* -----------------------------------------------------------------------------\n Modal Dialogs - MD3 Pattern\n ----------------------------------------------------------------------------- */\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: fadeIn 0.2s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-dialog {\n background: var(--md-surface);\n border-radius: var(--md-corner-extra-large);\n box-shadow: var(--md-elevation-5);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n animation: slideUp 0.3s cubic-bezier(0, 0, 0.2, 1);\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: 20px;\n }\n\n .modal-dialog.fullscreen {\n border-radius: 0;\n max-height: 100vh;\n }\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--md-outline-variant);\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-header {\n padding: 1rem 1.25rem;\n }\n}\n\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n}\n\n/* Modal Header 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(--md-on-surface-variant);\n font-size: 1.125rem;\n cursor: pointer;\n border-radius: var(--md-corner-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(--md-primary);\n color: var(--md-on-primary);\n}\n\n.modal-action-btn:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.modal-header .modal-close {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--md-corner-full);\n transition: all 0.2s 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.modal-header .modal-close:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.modal-header .modal-close:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.modal-body {\n padding: 1.5rem;\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 display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--md-outline-variant);\n background: var(--md-surface-container-low);\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .modal-footer {\n padding: 1rem 1.25rem;\n flex-direction: column;\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 - MD3 Pattern\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(--md-on-surface);\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(--md-outline-variant);\n border-radius: var(--md-corner-small);\n font-size: 1rem;\n background: var(--md-surface);\n color: var(--md-on-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.form-input:hover,\n.form-select:hover,\n.form-textarea:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.form-input:focus,\n.form-select:focus,\n.form-textarea:focus {\n outline: none;\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--md-surface);\n}\n\n.form-input::placeholder,\n.form-textarea::placeholder {\n color: var(--md-on-surface-variant);\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(--md-on-surface-variant);\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(--md-on-surface);\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(--md-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(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n background: var(--md-surface-container-low);\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(--md-on-surface);\n}\n\n.form-section-title i {\n color: var(--md-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 - MD3 Pattern\n ----------------------------------------------------------------------------- */\n.confirm-dialog {\n background: var(--md-surface);\n border-radius: var(--md-corner-extra-large);\n box-shadow: var(--md-elevation-5);\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: 20px;\n }\n}\n\n.confirm-dialog-icon {\n width: 64px;\n height: 64px;\n border-radius: 50%;\n background: var(--md-secondary-container);\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: #B5751A;\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(--md-on-surface);\n}\n\n.confirm-dialog-message {\n margin: 0;\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n line-height: 1.6;\n}\n\n.confirm-dialog-message strong {\n color: var(--md-on-surface);\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(--md-surface-container);\n border-radius: var(--md-corner-small);\n font-size: 0.8125rem;\n color: var(--md-on-surface-variant);\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 Animations - MD3 Easing\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 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 Reduced Motion Support\n ----------------------------------------------------------------------------- */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Focus Indicators - Accessibility\n ----------------------------------------------------------------------------- */\nbutton:focus-visible,\ninput:focus-visible,\nselect:focus-visible,\ntextarea:focus-visible,\na:focus-visible,\n[tabindex]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\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"] }]
1283
+ }], () => [{ type: i1.SharedService }, { type: i0.ChangeDetectorRef }], { onEscapeKey: [{
1211
1284
  type: HostListener,
1212
1285
  args: ['document:keydown.escape']
1213
1286
  }] }); })();