@memberjunction/ng-explorer-core 5.42.0 → 5.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generated/lazy-feature-config.d.ts +1 -1
- package/dist/generated/lazy-feature-config.d.ts.map +1 -1
- package/dist/generated/lazy-feature-config.js +14 -3
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/about/about-dialog.component.d.ts +0 -1
- package/dist/lib/about/about-dialog.component.d.ts.map +1 -1
- package/dist/lib/about/about-dialog.component.js +217 -218
- package/dist/lib/about/about-dialog.component.js.map +1 -1
- package/dist/lib/command-palette/command-palette.component.js +8 -14
- package/dist/lib/command-palette/command-palette.component.js.map +1 -1
- package/dist/lib/conversation-feedback/conversation-feedback.js +66 -73
- package/dist/lib/conversation-feedback/conversation-feedback.js.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +35 -45
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +2 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +14 -8
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +9 -8
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts +62 -2
- package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/livekit-room-resource.component.js +604 -105
- package/dist/lib/resource-wrappers/livekit-room-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +35 -43
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +10 -2
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.js +19 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts +1 -0
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +3 -2
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/shell.module.d.ts +1 -1
- package/dist/lib/shell/shell.module.d.ts.map +1 -1
- package/dist/lib/shell/shell.module.js +4 -1
- package/dist/lib/shell/shell.module.js.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +5 -7
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js +17 -27
- package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts +6 -2
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.js +48 -57
- package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.js +17 -22
- package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +60 -75
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/module.d.ts +1 -1
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +12 -5
- package/dist/module.js.map +1 -1
- package/package.json +47 -47
- package/dist/lib/__tests__/explorer-core.test.d.ts +0 -2
- package/dist/lib/__tests__/explorer-core.test.d.ts.map +0 -1
- package/dist/lib/__tests__/explorer-core.test.js +0 -229
- package/dist/lib/__tests__/explorer-core.test.js.map +0 -1
|
@@ -22,17 +22,14 @@ function ConversationFeedbackResource_Conditional_1_Template(rf, ctx) { if (rf &
|
|
|
22
22
|
} }
|
|
23
23
|
function ConversationFeedbackResource_Conditional_2_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
24
24
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
25
|
-
i0.ɵɵelementStart(0, "
|
|
26
|
-
i0.ɵɵ
|
|
27
|
-
i0.ɵɵtext(
|
|
28
|
-
i0.ɵɵ
|
|
29
|
-
i0.ɵɵlistener("click", function ConversationFeedbackResource_Conditional_2_Conditional_14_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.error = null); });
|
|
30
|
-
i0.ɵɵtext(4, "\u00D7");
|
|
31
|
-
i0.ɵɵelementEnd()();
|
|
25
|
+
i0.ɵɵelementStart(0, "mj-alert", 44);
|
|
26
|
+
i0.ɵɵlistener("Dismissed", function ConversationFeedbackResource_Conditional_2_Conditional_14_Template_mj_alert_Dismissed_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.error = null); });
|
|
27
|
+
i0.ɵɵtext(1);
|
|
28
|
+
i0.ɵɵelementEnd();
|
|
32
29
|
} if (rf & 2) {
|
|
33
30
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
34
|
-
i0.ɵɵadvance(
|
|
35
|
-
i0.ɵɵ
|
|
31
|
+
i0.ɵɵadvance();
|
|
32
|
+
i0.ɵɵtextInterpolate(ctx_r1.error);
|
|
36
33
|
} }
|
|
37
34
|
function ConversationFeedbackResource_Conditional_2_Conditional_85_Template(rf, ctx) { if (rf & 1) {
|
|
38
35
|
i0.ɵɵelementStart(0, "div", 1);
|
|
@@ -41,14 +38,10 @@ function ConversationFeedbackResource_Conditional_2_Conditional_85_Template(rf,
|
|
|
41
38
|
i0.ɵɵelementEnd();
|
|
42
39
|
} }
|
|
43
40
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
44
|
-
i0.ɵɵ
|
|
45
|
-
i0.ɵɵelement(1, "i", 47);
|
|
46
|
-
i0.ɵɵelementStart(2, "p");
|
|
47
|
-
i0.ɵɵtext(3, "No feedback matches the current filters.");
|
|
48
|
-
i0.ɵɵelementEnd()();
|
|
41
|
+
i0.ɵɵelement(0, "mj-empty-state", 45);
|
|
49
42
|
} }
|
|
50
43
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
51
|
-
i0.ɵɵelementStart(0, "div",
|
|
44
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
52
45
|
i0.ɵɵtext(1);
|
|
53
46
|
i0.ɵɵelementEnd();
|
|
54
47
|
} if (rf & 2) {
|
|
@@ -57,12 +50,12 @@ function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1
|
|
|
57
50
|
i0.ɵɵtextInterpolate(row_r6.comments);
|
|
58
51
|
} }
|
|
59
52
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
60
|
-
i0.ɵɵelementStart(0, "span",
|
|
53
|
+
i0.ɵɵelementStart(0, "span", 65);
|
|
61
54
|
i0.ɵɵtext(1, "(no comment)");
|
|
62
55
|
i0.ɵɵelementEnd();
|
|
63
56
|
} }
|
|
64
57
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
65
|
-
i0.ɵɵelementStart(0, "span",
|
|
58
|
+
i0.ɵɵelementStart(0, "span", 67);
|
|
66
59
|
i0.ɵɵtext(1);
|
|
67
60
|
i0.ɵɵelementEnd();
|
|
68
61
|
} if (rf & 2) {
|
|
@@ -71,12 +64,12 @@ function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1
|
|
|
71
64
|
i0.ɵɵtextInterpolate(row_r6.messageSnippet);
|
|
72
65
|
} }
|
|
73
66
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
74
|
-
i0.ɵɵelementStart(0, "span",
|
|
67
|
+
i0.ɵɵelementStart(0, "span", 65);
|
|
75
68
|
i0.ɵɵtext(1, "\u2014");
|
|
76
69
|
i0.ɵɵelementEnd();
|
|
77
70
|
} }
|
|
78
71
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
79
|
-
i0.ɵɵelementStart(0, "div",
|
|
72
|
+
i0.ɵɵelementStart(0, "div", 69);
|
|
80
73
|
i0.ɵɵtext(1);
|
|
81
74
|
i0.ɵɵelementEnd();
|
|
82
75
|
} if (rf & 2) {
|
|
@@ -86,28 +79,28 @@ function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1
|
|
|
86
79
|
} }
|
|
87
80
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Template(rf, ctx) { if (rf & 1) {
|
|
88
81
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
89
|
-
i0.ɵɵelementStart(0, "tr",
|
|
82
|
+
i0.ɵɵelementStart(0, "tr", 62);
|
|
90
83
|
i0.ɵɵlistener("click", function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Template_tr_click_0_listener() { const row_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.openDrawer(row_r6)); });
|
|
91
|
-
i0.ɵɵelementStart(1, "td",
|
|
84
|
+
i0.ɵɵelementStart(1, "td", 48)(2, "span", 63);
|
|
92
85
|
i0.ɵɵtext(3);
|
|
93
86
|
i0.ɵɵelementStart(4, "small");
|
|
94
87
|
i0.ɵɵtext(5, "/10");
|
|
95
88
|
i0.ɵɵelementEnd()()();
|
|
96
|
-
i0.ɵɵelementStart(6, "td",
|
|
97
|
-
i0.ɵɵconditionalCreate(7, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_7_Template, 2, 1, "div",
|
|
89
|
+
i0.ɵɵelementStart(6, "td", 49);
|
|
90
|
+
i0.ɵɵconditionalCreate(7, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_7_Template, 2, 1, "div", 64)(8, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_8_Template, 2, 0, "span", 65);
|
|
98
91
|
i0.ɵɵelementEnd();
|
|
99
|
-
i0.ɵɵelementStart(9, "td",
|
|
92
|
+
i0.ɵɵelementStart(9, "td", 50)(10, "span", 66);
|
|
100
93
|
i0.ɵɵtext(11);
|
|
101
94
|
i0.ɵɵelementEnd()();
|
|
102
|
-
i0.ɵɵelementStart(12, "td",
|
|
103
|
-
i0.ɵɵconditionalCreate(13, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_13_Template, 2, 1, "span",
|
|
95
|
+
i0.ɵɵelementStart(12, "td", 51);
|
|
96
|
+
i0.ɵɵconditionalCreate(13, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_13_Template, 2, 1, "span", 67)(14, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_14_Template, 2, 0, "span", 65);
|
|
104
97
|
i0.ɵɵelementEnd();
|
|
105
|
-
i0.ɵɵelementStart(15, "td",
|
|
98
|
+
i0.ɵɵelementStart(15, "td", 52)(16, "div", 68);
|
|
106
99
|
i0.ɵɵtext(17);
|
|
107
100
|
i0.ɵɵelementEnd();
|
|
108
|
-
i0.ɵɵconditionalCreate(18, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_18_Template, 2, 1, "div",
|
|
101
|
+
i0.ɵɵconditionalCreate(18, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Conditional_18_Template, 2, 1, "div", 69);
|
|
109
102
|
i0.ɵɵelementEnd();
|
|
110
|
-
i0.ɵɵelementStart(19, "td",
|
|
103
|
+
i0.ɵɵelementStart(19, "td", 53)(20, "span", 70);
|
|
111
104
|
i0.ɵɵtext(21);
|
|
112
105
|
i0.ɵɵpipe(22, "date");
|
|
113
106
|
i0.ɵɵelementEnd()()();
|
|
@@ -133,7 +126,7 @@ function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1
|
|
|
133
126
|
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(22, 10, row_r6.createdAt, "short"));
|
|
134
127
|
} }
|
|
135
128
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
136
|
-
i0.ɵɵelementStart(0, "span",
|
|
129
|
+
i0.ɵɵelementStart(0, "span", 56);
|
|
137
130
|
i0.ɵɵtext(1);
|
|
138
131
|
i0.ɵɵpipe(2, "number");
|
|
139
132
|
i0.ɵɵpipe(3, "number");
|
|
@@ -146,7 +139,7 @@ function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1
|
|
|
146
139
|
} }
|
|
147
140
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
148
141
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
149
|
-
i0.ɵɵelementStart(0, "mj-pagination",
|
|
142
|
+
i0.ɵɵelementStart(0, "mj-pagination", 71);
|
|
150
143
|
i0.ɵɵlistener("PageChange", function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_Conditional_21_Template_mj_pagination_PageChange_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.onPageChange($event)); });
|
|
151
144
|
i0.ɵɵelementEnd();
|
|
152
145
|
} if (rf & 2) {
|
|
@@ -154,7 +147,7 @@ function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1
|
|
|
154
147
|
i0.ɵɵproperty("TotalRowCount", ctx_r1.totalRowCount)("PageNumber", ctx_r1.currentPage)("PageSize", ctx_r1.pageSize)("IsLoading", ctx_r1.loading);
|
|
155
148
|
} }
|
|
156
149
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_27_Template(rf, ctx) { if (rf & 1) {
|
|
157
|
-
i0.ɵɵelementStart(0, "option",
|
|
150
|
+
i0.ɵɵelementStart(0, "option", 61);
|
|
158
151
|
i0.ɵɵtext(1);
|
|
159
152
|
i0.ɵɵelementEnd();
|
|
160
153
|
} if (rf & 2) {
|
|
@@ -165,35 +158,35 @@ function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1
|
|
|
165
158
|
} }
|
|
166
159
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
167
160
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
168
|
-
i0.ɵɵelementStart(0, "div",
|
|
161
|
+
i0.ɵɵelementStart(0, "div", 46)(1, "table", 47)(2, "thead")(3, "tr")(4, "th", 48);
|
|
169
162
|
i0.ɵɵtext(5, "Rating");
|
|
170
163
|
i0.ɵɵelementEnd();
|
|
171
|
-
i0.ɵɵelementStart(6, "th",
|
|
164
|
+
i0.ɵɵelementStart(6, "th", 49);
|
|
172
165
|
i0.ɵɵtext(7, "Comments");
|
|
173
166
|
i0.ɵɵelementEnd();
|
|
174
|
-
i0.ɵɵelementStart(8, "th",
|
|
167
|
+
i0.ɵɵelementStart(8, "th", 50);
|
|
175
168
|
i0.ɵɵtext(9, "Agent");
|
|
176
169
|
i0.ɵɵelementEnd();
|
|
177
|
-
i0.ɵɵelementStart(10, "th",
|
|
170
|
+
i0.ɵɵelementStart(10, "th", 51);
|
|
178
171
|
i0.ɵɵtext(11, "Message");
|
|
179
172
|
i0.ɵɵelementEnd();
|
|
180
|
-
i0.ɵɵelementStart(12, "th",
|
|
173
|
+
i0.ɵɵelementStart(12, "th", 52);
|
|
181
174
|
i0.ɵɵtext(13, "Rater");
|
|
182
175
|
i0.ɵɵelementEnd();
|
|
183
|
-
i0.ɵɵelementStart(14, "th",
|
|
176
|
+
i0.ɵɵelementStart(14, "th", 53);
|
|
184
177
|
i0.ɵɵtext(15, "When");
|
|
185
178
|
i0.ɵɵelementEnd()()();
|
|
186
179
|
i0.ɵɵelementStart(16, "tbody");
|
|
187
|
-
i0.ɵɵrepeaterCreate(17, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Template, 23, 13, "tr",
|
|
180
|
+
i0.ɵɵrepeaterCreate(17, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_18_Template, 23, 13, "tr", 54, i0.ɵɵcomponentInstance().trackByRatingID, true);
|
|
188
181
|
i0.ɵɵelementEnd()()();
|
|
189
|
-
i0.ɵɵelementStart(19, "div",
|
|
190
|
-
i0.ɵɵconditionalCreate(20, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_Conditional_20_Template, 5, 10, "span",
|
|
191
|
-
i0.ɵɵelementStart(22, "label",
|
|
182
|
+
i0.ɵɵelementStart(19, "div", 55);
|
|
183
|
+
i0.ɵɵconditionalCreate(20, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_Conditional_20_Template, 5, 10, "span", 56)(21, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_Conditional_21_Template, 1, 4, "mj-pagination", 57);
|
|
184
|
+
i0.ɵɵelementStart(22, "label", 58)(23, "span", 59);
|
|
192
185
|
i0.ɵɵtext(24, "Rows");
|
|
193
186
|
i0.ɵɵelementEnd();
|
|
194
|
-
i0.ɵɵelementStart(25, "select",
|
|
187
|
+
i0.ɵɵelementStart(25, "select", 60);
|
|
195
188
|
i0.ɵɵlistener("ngModelChange", function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_Template_select_ngModelChange_25_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onPageSizeChange($event)); });
|
|
196
|
-
i0.ɵɵrepeaterCreate(26, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_27_Template, 2, 2, "option",
|
|
189
|
+
i0.ɵɵrepeaterCreate(26, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_For_27_Template, 2, 2, "option", 61, i0.ɵɵrepeaterTrackByIdentity);
|
|
197
190
|
i0.ɵɵelementEnd()()();
|
|
198
191
|
} if (rf & 2) {
|
|
199
192
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -207,7 +200,7 @@ function ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1
|
|
|
207
200
|
i0.ɵɵrepeater(ctx_r1.pageSizeOptions);
|
|
208
201
|
} }
|
|
209
202
|
function ConversationFeedbackResource_Conditional_2_Conditional_86_Template(rf, ctx) { if (rf & 1) {
|
|
210
|
-
i0.ɵɵconditionalCreate(0, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_0_Template,
|
|
203
|
+
i0.ɵɵconditionalCreate(0, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_0_Template, 1, 0, "mj-empty-state", 45)(1, ConversationFeedbackResource_Conditional_2_Conditional_86_Conditional_1_Template, 28, 2);
|
|
211
204
|
} if (rf & 2) {
|
|
212
205
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
213
206
|
i0.ɵɵconditional(ctx_r1.rows.length === 0 ? 0 : 1);
|
|
@@ -228,7 +221,7 @@ function ConversationFeedbackResource_Conditional_2_Template(rf, ctx) { if (rf &
|
|
|
228
221
|
i0.ɵɵelement(12, "i", 14);
|
|
229
222
|
i0.ɵɵtext(13, " Refresh ");
|
|
230
223
|
i0.ɵɵelementEnd()()();
|
|
231
|
-
i0.ɵɵconditionalCreate(14, ConversationFeedbackResource_Conditional_2_Conditional_14_Template,
|
|
224
|
+
i0.ɵɵconditionalCreate(14, ConversationFeedbackResource_Conditional_2_Conditional_14_Template, 2, 1, "mj-alert", 15);
|
|
232
225
|
i0.ɵɵelementStart(15, "div", 16)(16, "div", 17)(17, "div", 18);
|
|
233
226
|
i0.ɵɵelement(18, "i", 9);
|
|
234
227
|
i0.ɵɵelementEnd();
|
|
@@ -368,12 +361,12 @@ function ConversationFeedbackResource_Conditional_2_Template(rf, ctx) { if (rf &
|
|
|
368
361
|
} }
|
|
369
362
|
function ConversationFeedbackResource_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
370
363
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
371
|
-
i0.ɵɵelementStart(0, "div",
|
|
364
|
+
i0.ɵɵelementStart(0, "div", 72);
|
|
372
365
|
i0.ɵɵlistener("click", function ConversationFeedbackResource_Conditional_3_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeDrawer()); });
|
|
373
366
|
i0.ɵɵelementEnd();
|
|
374
367
|
} }
|
|
375
368
|
function ConversationFeedbackResource_Conditional_5_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
376
|
-
i0.ɵɵelementStart(0, "div",
|
|
369
|
+
i0.ɵɵelementStart(0, "div", 83);
|
|
377
370
|
i0.ɵɵtext(1);
|
|
378
371
|
i0.ɵɵelementEnd();
|
|
379
372
|
} if (rf & 2) {
|
|
@@ -382,7 +375,7 @@ function ConversationFeedbackResource_Conditional_5_Conditional_23_Template(rf,
|
|
|
382
375
|
i0.ɵɵtextInterpolate(r_r11.comments);
|
|
383
376
|
} }
|
|
384
377
|
function ConversationFeedbackResource_Conditional_5_Conditional_24_Template(rf, ctx) { if (rf & 1) {
|
|
385
|
-
i0.ɵɵelementStart(0, "div",
|
|
378
|
+
i0.ɵɵelementStart(0, "div", 84);
|
|
386
379
|
i0.ɵɵtext(1, "(no comment was provided)");
|
|
387
380
|
i0.ɵɵelementEnd();
|
|
388
381
|
} }
|
|
@@ -393,18 +386,18 @@ function ConversationFeedbackResource_Conditional_5_Conditional_48_Template(rf,
|
|
|
393
386
|
i0.ɵɵtextInterpolate1(" ", r_r11.messageText, " ");
|
|
394
387
|
} }
|
|
395
388
|
function ConversationFeedbackResource_Conditional_5_Conditional_49_Template(rf, ctx) { if (rf & 1) {
|
|
396
|
-
i0.ɵɵelementStart(0, "span",
|
|
389
|
+
i0.ɵɵelementStart(0, "span", 65);
|
|
397
390
|
i0.ɵɵtext(1, "(message text unavailable)");
|
|
398
391
|
i0.ɵɵelementEnd();
|
|
399
392
|
} }
|
|
400
393
|
function ConversationFeedbackResource_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
401
394
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
402
|
-
i0.ɵɵelementStart(0, "div",
|
|
395
|
+
i0.ɵɵelementStart(0, "div", 73)(1, "div", 74);
|
|
403
396
|
i0.ɵɵelement(2, "i", 9);
|
|
404
|
-
i0.ɵɵelementStart(3, "div",
|
|
397
|
+
i0.ɵɵelementStart(3, "div", 75)(4, "h2", 76);
|
|
405
398
|
i0.ɵɵtext(5);
|
|
406
399
|
i0.ɵɵelementEnd();
|
|
407
|
-
i0.ɵɵelementStart(6, "div",
|
|
400
|
+
i0.ɵɵelementStart(6, "div", 77)(7, "span", 63);
|
|
408
401
|
i0.ɵɵtext(8);
|
|
409
402
|
i0.ɵɵelementStart(9, "small");
|
|
410
403
|
i0.ɵɵtext(10, "/10");
|
|
@@ -417,47 +410,47 @@ function ConversationFeedbackResource_Conditional_5_Template(rf, ctx) { if (rf &
|
|
|
417
410
|
i0.ɵɵtext(15);
|
|
418
411
|
i0.ɵɵpipe(16, "date");
|
|
419
412
|
i0.ɵɵelementEnd()()()();
|
|
420
|
-
i0.ɵɵelementStart(17, "button",
|
|
413
|
+
i0.ɵɵelementStart(17, "button", 78);
|
|
421
414
|
i0.ɵɵlistener("click", function ConversationFeedbackResource_Conditional_5_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeDrawer()); });
|
|
422
|
-
i0.ɵɵelement(18, "i",
|
|
415
|
+
i0.ɵɵelement(18, "i", 79);
|
|
423
416
|
i0.ɵɵelementEnd()();
|
|
424
|
-
i0.ɵɵelementStart(19, "div",
|
|
417
|
+
i0.ɵɵelementStart(19, "div", 80)(20, "div", 81)(21, "div", 82);
|
|
425
418
|
i0.ɵɵtext(22, "Reviewer Comment");
|
|
426
419
|
i0.ɵɵelementEnd();
|
|
427
|
-
i0.ɵɵconditionalCreate(23, ConversationFeedbackResource_Conditional_5_Conditional_23_Template, 2, 1, "div",
|
|
420
|
+
i0.ɵɵconditionalCreate(23, ConversationFeedbackResource_Conditional_5_Conditional_23_Template, 2, 1, "div", 83)(24, ConversationFeedbackResource_Conditional_5_Conditional_24_Template, 2, 0, "div", 84);
|
|
428
421
|
i0.ɵɵelementEnd();
|
|
429
|
-
i0.ɵɵelementStart(25, "div",
|
|
422
|
+
i0.ɵɵelementStart(25, "div", 81)(26, "div", 85)(27, "div", 86)(28, "div", 87);
|
|
430
423
|
i0.ɵɵtext(29, "Agent");
|
|
431
424
|
i0.ɵɵelementEnd();
|
|
432
|
-
i0.ɵɵelementStart(30, "div",
|
|
425
|
+
i0.ɵɵelementStart(30, "div", 88);
|
|
433
426
|
i0.ɵɵtext(31);
|
|
434
427
|
i0.ɵɵelementEnd()();
|
|
435
|
-
i0.ɵɵelementStart(32, "div",
|
|
428
|
+
i0.ɵɵelementStart(32, "div", 86)(33, "div", 87);
|
|
436
429
|
i0.ɵɵtext(34, "Conversation");
|
|
437
430
|
i0.ɵɵelementEnd();
|
|
438
|
-
i0.ɵɵelementStart(35, "div",
|
|
431
|
+
i0.ɵɵelementStart(35, "div", 88);
|
|
439
432
|
i0.ɵɵtext(36);
|
|
440
433
|
i0.ɵɵelementEnd()();
|
|
441
|
-
i0.ɵɵelementStart(37, "div",
|
|
434
|
+
i0.ɵɵelementStart(37, "div", 86)(38, "div", 87);
|
|
442
435
|
i0.ɵɵtext(39, "Message Role");
|
|
443
436
|
i0.ɵɵelementEnd();
|
|
444
|
-
i0.ɵɵelementStart(40, "div",
|
|
437
|
+
i0.ɵɵelementStart(40, "div", 88);
|
|
445
438
|
i0.ɵɵtext(41);
|
|
446
439
|
i0.ɵɵelementEnd()()()();
|
|
447
|
-
i0.ɵɵelementStart(42, "div",
|
|
448
|
-
i0.ɵɵelement(45, "i",
|
|
440
|
+
i0.ɵɵelementStart(42, "div", 81)(43, "div", 89)(44, "div", 90);
|
|
441
|
+
i0.ɵɵelement(45, "i", 91);
|
|
449
442
|
i0.ɵɵtext(46, " Rated Message ");
|
|
450
443
|
i0.ɵɵelementEnd();
|
|
451
|
-
i0.ɵɵelementStart(47, "div",
|
|
452
|
-
i0.ɵɵconditionalCreate(48, ConversationFeedbackResource_Conditional_5_Conditional_48_Template, 1, 1)(49, ConversationFeedbackResource_Conditional_5_Conditional_49_Template, 2, 0, "span",
|
|
444
|
+
i0.ɵɵelementStart(47, "div", 92);
|
|
445
|
+
i0.ɵɵconditionalCreate(48, ConversationFeedbackResource_Conditional_5_Conditional_48_Template, 1, 1)(49, ConversationFeedbackResource_Conditional_5_Conditional_49_Template, 2, 0, "span", 65);
|
|
453
446
|
i0.ɵɵelementEnd()()()();
|
|
454
|
-
i0.ɵɵelementStart(50, "div",
|
|
447
|
+
i0.ɵɵelementStart(50, "div", 93)(51, "button", 94);
|
|
455
448
|
i0.ɵɵlistener("click", function ConversationFeedbackResource_Conditional_5_Template_button_click_51_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeDrawer()); });
|
|
456
449
|
i0.ɵɵtext(52, "Close");
|
|
457
450
|
i0.ɵɵelementEnd();
|
|
458
|
-
i0.ɵɵelementStart(53, "button",
|
|
451
|
+
i0.ɵɵelementStart(53, "button", 95);
|
|
459
452
|
i0.ɵɵlistener("click", function ConversationFeedbackResource_Conditional_5_Template_button_click_53_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openConversation()); });
|
|
460
|
-
i0.ɵɵelement(54, "i",
|
|
453
|
+
i0.ɵɵelement(54, "i", 96);
|
|
461
454
|
i0.ɵɵtext(55, " Open Conversation ");
|
|
462
455
|
i0.ɵɵelementEnd()();
|
|
463
456
|
} if (rf & 2) {
|
|
@@ -772,7 +765,7 @@ let ConversationFeedbackResource = class ConversationFeedbackResource extends Ba
|
|
|
772
765
|
static ɵfac = /*@__PURE__*/ (() => { let ɵConversationFeedbackResource_BaseFactory; return function ConversationFeedbackResource_Factory(__ngFactoryType__) { return (ɵConversationFeedbackResource_BaseFactory || (ɵConversationFeedbackResource_BaseFactory = i0.ɵɵgetInheritedFactory(ConversationFeedbackResource)))(__ngFactoryType__ || ConversationFeedbackResource); }; })();
|
|
773
766
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationFeedbackResource, selectors: [["mj-conversation-feedback"]], hostBindings: function ConversationFeedbackResource_HostBindings(rf, ctx) { if (rf & 1) {
|
|
774
767
|
i0.ɵɵlistener("keydown.escape", function ConversationFeedbackResource_keydown_escape_HostBindingHandler() { return ctx.onEscape(); }, i0.ɵɵresolveDocument);
|
|
775
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 6, vars: 6, consts: [[1, "feedback-container"], [1, "loading-overlay"], [1, "slideout-backdrop"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "slideout-title", 1, "slideout-panel"], [1, "spinner"], [1, "sticky-header"], [1, "page-header"], [1, "page-title-area"], [1, "page-icon"], [1, "fa-solid", "fa-comment-dots"], [1, "page-title"], [1, "page-subtitle"], [1, "page-actions"], [1, "btn-action", 3, "click", "disabled"], [1, "fa-solid", "fa-arrows-rotate"], [1, "error-
|
|
768
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 6, vars: 6, consts: [[1, "feedback-container"], [1, "loading-overlay"], [1, "slideout-backdrop"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "slideout-title", 1, "slideout-panel"], [1, "spinner"], [1, "sticky-header"], [1, "page-header"], [1, "page-title-area"], [1, "page-icon"], [1, "fa-solid", "fa-comment-dots"], [1, "page-title"], [1, "page-subtitle"], [1, "page-actions"], [1, "btn-action", 3, "click", "disabled"], [1, "fa-solid", "fa-arrows-rotate"], ["Variant", "error", "Dismissible", "", 1, "feedback-error-spacing"], [1, "stats-grid"], [1, "stat-card"], [1, "stat-icon", "stat-icon-total"], [1, "stat-content"], [1, "stat-value"], [1, "stat-label"], [1, "stat-icon", "stat-icon-avg"], [1, "fa-solid", "fa-star"], [1, "stat-unit"], [1, "stat-icon", "stat-icon-positive"], [1, "fa-solid", "fa-thumbs-up"], [1, "stat-value", "rating-high-text"], [1, "stat-icon", "stat-icon-negative"], [1, "fa-solid", "fa-thumbs-down"], [1, "stat-value", "rating-low-text"], [1, "filter-bar"], [1, "filter-row"], [1, "filter-group"], [1, "filter-label"], [1, "btn-group"], [1, "btn-filter", 3, "click"], [1, "btn-filter", "band-high", 3, "click"], [1, "btn-filter", "band-mid", 3, "click"], [1, "btn-filter", "band-low", 3, "click"], [1, "filter-group", "filter-search"], ["type", "text", "placeholder", "Search comments, message, agent, rater...", 1, "input-search", 3, "ngModelChange", "input", "ngModel"], [1, "diagnostic-line"], [1, "scrollable-content"], ["Variant", "error", "Dismissible", "", 1, "feedback-error-spacing", 3, "Dismissed"], ["Variant", "no-results", "Icon", "fa-solid fa-comment-slash", "Title", "No feedback matches the current filters.", 1, "feedback-empty-state"], [1, "feedback-table-wrapper"], [1, "feedback-table"], [1, "col-rating"], [1, "col-comment"], [1, "col-agent"], [1, "col-message"], [1, "col-rater"], [1, "col-when"], [1, "feedback-row", 3, "expanded"], [1, "pagination-bar"], [1, "pagination-summary"], [1, "feedback-pagination", 3, "TotalRowCount", "PageNumber", "PageSize", "IsLoading"], [1, "page-size-control"], [1, "page-size-label"], [1, "page-size-select", 3, "ngModelChange", "ngModel"], [3, "ngValue"], [1, "feedback-row", 3, "click"], [1, "rating-badge", 3, "ngClass"], [1, "comment-text", "clamped"], [1, "muted"], [1, "agent-name"], [1, "message-snippet"], [1, "rater-name"], [1, "rater-email"], [1, "when"], [1, "feedback-pagination", 3, "PageChange", "TotalRowCount", "PageNumber", "PageSize", "IsLoading"], [1, "slideout-backdrop", 3, "click"], [1, "slideout-header"], [1, "slideout-title"], [1, "slideout-title-text"], ["id", "slideout-title", 1, "slideout-title-line"], [1, "slideout-subtitle"], ["title", "Close (Esc)", "aria-label", "Close", 1, "slideout-close", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "slideout-content"], [1, "slideout-section"], [1, "section-label"], [1, "comment-body"], [1, "comment-body", "muted"], [1, "meta-grid"], [1, "meta-card"], [1, "meta-label"], [1, "meta-value"], [1, "message-card"], [1, "message-card-header"], [1, "fa-solid", "fa-message"], [1, "message-card-body"], [1, "slideout-footer"], ["mjButton", "", "variant", "flat", "size", "lg", 3, "click"], ["mjButton", "", "variant", "primary", "size", "lg", 3, "click", "disabled", "title"], [1, "fa-solid", "fa-arrow-up-right-from-square"]], template: function ConversationFeedbackResource_Template(rf, ctx) { if (rf & 1) {
|
|
776
769
|
i0.ɵɵelementStart(0, "div", 0);
|
|
777
770
|
i0.ɵɵconditionalCreate(1, ConversationFeedbackResource_Conditional_1_Template, 3, 0, "div", 1);
|
|
778
771
|
i0.ɵɵconditionalCreate(2, ConversationFeedbackResource_Conditional_2_Template, 87, 31);
|
|
@@ -792,7 +785,7 @@ let ConversationFeedbackResource = class ConversationFeedbackResource extends Ba
|
|
|
792
785
|
i0.ɵɵclassProp("open", !!ctx.selectedRow);
|
|
793
786
|
i0.ɵɵadvance();
|
|
794
787
|
i0.ɵɵconditional((tmp_4_0 = ctx.selectedRow) ? 5 : -1, tmp_4_0);
|
|
795
|
-
} }, dependencies: [i1.NgClass, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJButtonDirective, i4.PaginationComponent, i1.DecimalPipe, i1.DatePipe], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.feedback-container[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n overflow: hidden;\n}\n\n\n\n\n\n.sticky-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n\n\n\n\n.page-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n padding: 1rem 1.5rem;\n}\n\n.page-title-area[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 0.75rem; }\n\n.page-icon[_ngcontent-%COMP%] {\n width: 40px; height: 40px;\n display: flex; align-items: center; justify-content: center;\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n font-size: 1.125rem;\n}\n\n.page-title[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 700;\n margin: 0;\n letter-spacing: -0.02em;\n color: var(--mj-text-primary);\n}\n\n.page-subtitle[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.page-actions[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 0.5rem; }\n\n.btn-action[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.875rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 180ms, border-color 180ms, color 180ms;\n}\n.btn-action[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n.btn-action[_ngcontent-%COMP%]:disabled { opacity: 0.5; cursor: default; }\n\n\n\n\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.75rem;\n padding: 0 1.5rem 1rem;\n}\n\n@media (min-width: 768px) {\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(4, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem 1.25rem;\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: var(--mj-radius-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.125rem;\n flex-shrink: 0;\n}\n\n.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n}\n.stat-icon-avg[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-tertiary) 16%, transparent);\n color: var(--mj-brand-tertiary);\n}\n.stat-icon-positive[_ngcontent-%COMP%] {\n background: var(--rating-high-bg, #ecfdf5);\n color: var(--rating-high, #10b981);\n}\n.stat-icon-negative[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.stat-content[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n font-weight: 700;\n letter-spacing: -0.02em;\n color: var(--mj-text-primary);\n line-height: 1.1;\n}\n.stat-unit[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n font-weight: 500;\n margin-left: 2px;\n}\n.stat-label[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n margin-top: 0.125rem;\n}\n\n.rating-high-text[_ngcontent-%COMP%] { color: var(--rating-high, #10b981); }\n.rating-low-text[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n\n\n\n\n\n.filter-bar[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem 1rem;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.filter-row[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n align-items: flex-end;\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.3rem;\n}\n\n.filter-search[_ngcontent-%COMP%] {\n flex: 0 1 auto;\n width: 280px;\n min-width: 200px;\n max-width: 360px;\n}\n\n.filter-label[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n}\n\n.btn-group[_ngcontent-%COMP%] { display: flex; gap: 0; }\n.btn-group[_ngcontent-%COMP%] .btn-filter[_ngcontent-%COMP%]:first-child { border-radius: var(--mj-radius-sm) 0 0 var(--mj-radius-sm); }\n.btn-group[_ngcontent-%COMP%] .btn-filter[_ngcontent-%COMP%]:last-child { border-radius: 0 var(--mj-radius-sm) var(--mj-radius-sm) 0; }\n.btn-group[_ngcontent-%COMP%] .btn-filter[_ngcontent-%COMP%]:not(:first-child) { margin-left: -1px; }\n\n.btn-filter[_ngcontent-%COMP%] {\n padding: 0.4rem 0.75rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 180ms, color 180ms, border-color 180ms;\n white-space: nowrap;\n}\n.btn-filter[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n.btn-filter.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n z-index: 1;\n position: relative;\n}\n.btn-filter.band-high.active[_ngcontent-%COMP%] {\n background: var(--rating-high, #10b981);\n border-color: var(--rating-high, #10b981);\n color: var(--mj-text-inverse);\n}\n.btn-filter.band-mid.active[_ngcontent-%COMP%] {\n background: var(--rating-mid, #f59e0b);\n border-color: var(--rating-mid, #f59e0b);\n color: var(--mj-text-inverse);\n}\n.btn-filter.band-low.active[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.input-search[_ngcontent-%COMP%] {\n padding: 0.45rem 0.75rem;\n font-size: 0.875rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n width: 100%;\n}\n.input-search[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n.diagnostic-line[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n color: var(--mj-text-secondary);\n letter-spacing: 0.02em;\n}\n\n\n\n\n\n.error-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n margin: 0 1.5rem 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-status-error-bg);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 35%, transparent);\n border-radius: var(--mj-radius-md);\n color: var(--mj-status-error-text);\n font-size: 0.8125rem;\n font-weight: 500;\n}\n.error-banner[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n font-size: 1.125rem;\n color: var(--mj-status-error);\n padding: 0 0.25rem;\n}\n\n\n\n\n\n.scrollable-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 1.25rem 1.5rem 1.5rem;\n}\n\n.loading-overlay[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.625rem;\n padding: 3rem;\n color: var(--mj-text-secondary);\n font-size: 0.8125rem;\n font-weight: 500;\n}\n.spinner[_ngcontent-%COMP%] {\n width: 20px; height: 20px;\n border: 2px solid var(--mj-border-default);\n border-top-color: var(--mj-brand-primary);\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 0.6s linear infinite;\n}\n@keyframes _ngcontent-%COMP%_spin { to { transform: rotate(360deg); } }\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 padding: 4rem 1.25rem;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n}\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2.25rem;\n margin-bottom: 0.875rem;\n opacity: 0.5;\n}\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 500;\n margin: 0;\n}\n\n\n\n\n\n.feedback-table-wrapper[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n overflow: auto;\n}\n\n.feedback-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.8125rem;\n table-layout: fixed;\n}\n\n.feedback-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n.feedback-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n font-size: 0.6875rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n padding: 0.75rem 0.875rem;\n}\n.feedback-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 0.875rem;\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-primary);\n vertical-align: top;\n}\n\n.feedback-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: background 180ms;\n}\n.feedback-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.feedback-row.expanded[_ngcontent-%COMP%] { background: var(--mj-brand-accent-subtle); }\n\n.col-rating[_ngcontent-%COMP%] { width: 90px; }\n.col-comment[_ngcontent-%COMP%] { width: 28%; }\n.col-agent[_ngcontent-%COMP%] { width: 14%; }\n.col-message[_ngcontent-%COMP%] { width: 26%; }\n.col-rater[_ngcontent-%COMP%] { width: 16%; }\n.col-when[_ngcontent-%COMP%] { width: 12%; }\n\n.rating-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: baseline;\n gap: 2px;\n padding: 0.35rem 0.625rem;\n border-radius: var(--mj-radius-md);\n font-size: 0.875rem;\n font-weight: 700;\n letter-spacing: -0.02em;\n}\n.rating-badge[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n font-weight: 500;\n opacity: 0.7;\n}\n.rating-badge.rating-high[_ngcontent-%COMP%] { background: var(--rating-high-bg, #ecfdf5); color: var(--rating-high, #10b981); }\n.rating-badge.rating-mid[_ngcontent-%COMP%] { background: var(--rating-mid-bg, #fffbeb); color: var(--rating-mid, #f59e0b); }\n.rating-badge.rating-low[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); color: var(--mj-status-error); }\n\n.comment-text[_ngcontent-%COMP%] {\n white-space: pre-wrap;\n word-break: break-word;\n line-height: 1.5;\n}\n.comment-text.clamped[_ngcontent-%COMP%] {\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n line-clamp: 2;\n overflow: hidden;\n}\n.message-snippet[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n line-clamp: 2;\n overflow: hidden;\n}\n\n\n\n.pagination-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-top: 0.5rem;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n.pagination-summary[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n color: var(--mj-text-secondary);\n padding: 0.5rem 0;\n}\n.feedback-pagination[_ngcontent-%COMP%] {\n display: block;\n flex: 1;\n min-width: 0;\n}\n\n.page-size-control[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n.page-size-label[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n}\n.page-size-select[_ngcontent-%COMP%] {\n padding: 0.3rem 0.5rem;\n font-size: 0.8125rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n.page-size-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n.agent-name[_ngcontent-%COMP%] { font-weight: 500; color: var(--mj-text-primary); }\n.rater-name[_ngcontent-%COMP%] { font-weight: 500; color: var(--mj-text-primary); }\n.rater-email[_ngcontent-%COMP%] { font-size: 0.6875rem; color: var(--mj-text-secondary); margin-top: 2px; }\n.when[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-size: 0.75rem; white-space: nowrap; }\n.muted[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-style: italic; }\n\n\n\n\n\n\n\n\n\n.slideout-backdrop[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: var(--mj-bg-overlay, rgba(28, 28, 34, 0.45));\n z-index: 100;\n animation: _ngcontent-%COMP%_feedback-fadeIn 0.2s ease;\n}\n@keyframes _ngcontent-%COMP%_feedback-fadeIn { from { opacity: 0; } to { opacity: 1; } }\n\n.slideout-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n width: 560px;\n max-width: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay, rgba(0, 0, 0, 0.25));\n z-index: 101;\n display: flex;\n flex-direction: column;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n transform: translateX(100%);\n overflow: hidden;\n}\n.slideout-panel.open[_ngcontent-%COMP%] { transform: translateX(0); }\n\n\n\n.slideout-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 1rem;\n padding: 20px 24px;\n background: var(--mj-brand-accent-subtle);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n.slideout-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n.slideout-title[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 22px;\n flex-shrink: 0;\n line-height: 1.2;\n}\n.slideout-title-text[_ngcontent-%COMP%] { min-width: 0; }\n.slideout-title-line[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 17px;\n color: var(--mj-text-primary);\n margin: 0 0 6px;\n line-height: 1.3;\n word-break: break-word;\n}\n.slideout-subtitle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n flex-wrap: wrap;\n}\n.slideout-subtitle[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] { color: var(--mj-text-primary); font-weight: 600; }\n\n.slideout-close[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface-hover);\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.slideout-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n\n\n.slideout-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n background: var(--mj-bg-surface);\n}\n.slideout-section[_ngcontent-%COMP%] {\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.slideout-section[_ngcontent-%COMP%]:last-child { border-bottom: none; }\n\n.section-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n margin-bottom: 0.5rem;\n}\n.comment-body[_ngcontent-%COMP%] {\n font-size: 14px;\n line-height: 1.55;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n}\n.comment-body.muted[_ngcontent-%COMP%] { font-style: italic; color: var(--mj-text-secondary); }\n\n.meta-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 0.75rem;\n}\n.meta-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 0.75rem 0.875rem;\n}\n.meta-label[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n font-weight: 600;\n margin-bottom: 0.25rem;\n}\n.meta-value[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.message-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n}\n.message-card-header[_ngcontent-%COMP%] {\n padding: 0.75rem 1.125rem;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n font-size: 0.8125rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.message-card-body[_ngcontent-%COMP%] {\n padding: 1rem 1.125rem;\n font-size: 0.875rem;\n line-height: 1.55;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 320px;\n overflow-y: auto;\n}\n\n\n\n.slideout-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n.slideout-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] { min-width: 96px; }\n.slideout-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { margin-right: 6px; }"] });
|
|
788
|
+
} }, dependencies: [i1.NgClass, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJButtonDirective, i4.PaginationComponent, i3.MJEmptyStateComponent, i3.MJAlertComponent, i1.DecimalPipe, i1.DatePipe], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.feedback-container[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n overflow: hidden;\n}\n\n\n\n\n\n.sticky-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n\n\n\n\n.page-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n padding: 1rem 1.5rem;\n}\n\n.page-title-area[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 0.75rem; }\n\n.page-icon[_ngcontent-%COMP%] {\n width: 40px; height: 40px;\n display: flex; align-items: center; justify-content: center;\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n font-size: 1.125rem;\n}\n\n.page-title[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 700;\n margin: 0;\n letter-spacing: -0.02em;\n color: var(--mj-text-primary);\n}\n\n.page-subtitle[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.page-actions[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 0.5rem; }\n\n.btn-action[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.875rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 180ms, border-color 180ms, color 180ms;\n}\n.btn-action[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n.btn-action[_ngcontent-%COMP%]:disabled { opacity: 0.5; cursor: default; }\n\n\n\n\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.75rem;\n padding: 0 1.5rem 1rem;\n}\n\n@media (min-width: 768px) {\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(4, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem 1.25rem;\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: var(--mj-radius-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.125rem;\n flex-shrink: 0;\n}\n\n.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n}\n.stat-icon-avg[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-tertiary) 16%, transparent);\n color: var(--mj-brand-tertiary);\n}\n.stat-icon-positive[_ngcontent-%COMP%] {\n background: var(--rating-high-bg, #ecfdf5);\n color: var(--rating-high, #10b981);\n}\n.stat-icon-negative[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.stat-content[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n font-weight: 700;\n letter-spacing: -0.02em;\n color: var(--mj-text-primary);\n line-height: 1.1;\n}\n.stat-unit[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n font-weight: 500;\n margin-left: 2px;\n}\n.stat-label[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n margin-top: 0.125rem;\n}\n\n.rating-high-text[_ngcontent-%COMP%] { color: var(--rating-high, #10b981); }\n.rating-low-text[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n\n\n\n\n\n.filter-bar[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem 1rem;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.filter-row[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n align-items: flex-end;\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.3rem;\n}\n\n.filter-search[_ngcontent-%COMP%] {\n flex: 0 1 auto;\n width: 280px;\n min-width: 200px;\n max-width: 360px;\n}\n\n.filter-label[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n}\n\n.btn-group[_ngcontent-%COMP%] { display: flex; gap: 0; }\n.btn-group[_ngcontent-%COMP%] .btn-filter[_ngcontent-%COMP%]:first-child { border-radius: var(--mj-radius-sm) 0 0 var(--mj-radius-sm); }\n.btn-group[_ngcontent-%COMP%] .btn-filter[_ngcontent-%COMP%]:last-child { border-radius: 0 var(--mj-radius-sm) var(--mj-radius-sm) 0; }\n.btn-group[_ngcontent-%COMP%] .btn-filter[_ngcontent-%COMP%]:not(:first-child) { margin-left: -1px; }\n\n.btn-filter[_ngcontent-%COMP%] {\n padding: 0.4rem 0.75rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 180ms, color 180ms, border-color 180ms;\n white-space: nowrap;\n}\n.btn-filter[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n.btn-filter.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n z-index: 1;\n position: relative;\n}\n.btn-filter.band-high.active[_ngcontent-%COMP%] {\n background: var(--rating-high, #10b981);\n border-color: var(--rating-high, #10b981);\n color: var(--mj-text-inverse);\n}\n.btn-filter.band-mid.active[_ngcontent-%COMP%] {\n background: var(--rating-mid, #f59e0b);\n border-color: var(--rating-mid, #f59e0b);\n color: var(--mj-text-inverse);\n}\n.btn-filter.band-low.active[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.input-search[_ngcontent-%COMP%] {\n padding: 0.45rem 0.75rem;\n font-size: 0.875rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n width: 100%;\n}\n.input-search[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n.diagnostic-line[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n color: var(--mj-text-secondary);\n letter-spacing: 0.02em;\n}\n\n\n\n\n\n.feedback-error-spacing[_ngcontent-%COMP%] { margin: 0 1.5rem 0.75rem; }\n\n\n\n\n\n.scrollable-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 1.25rem 1.5rem 1.5rem;\n}\n\n.loading-overlay[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.625rem;\n padding: 3rem;\n color: var(--mj-text-secondary);\n font-size: 0.8125rem;\n font-weight: 500;\n}\n.spinner[_ngcontent-%COMP%] {\n width: 20px; height: 20px;\n border: 2px solid var(--mj-border-default);\n border-top-color: var(--mj-brand-primary);\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 0.6s linear infinite;\n}\n@keyframes _ngcontent-%COMP%_spin { to { transform: rotate(360deg); } }\n\n\n\n\n\n.feedback-empty-state[_ngcontent-%COMP%] {\n display: block;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n}\n\n\n\n\n\n.feedback-table-wrapper[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n overflow: auto;\n}\n\n.feedback-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.8125rem;\n table-layout: fixed;\n}\n\n.feedback-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n.feedback-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n font-size: 0.6875rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n padding: 0.75rem 0.875rem;\n}\n.feedback-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 0.875rem;\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-primary);\n vertical-align: top;\n}\n\n.feedback-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: background 180ms;\n}\n.feedback-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.feedback-row.expanded[_ngcontent-%COMP%] { background: var(--mj-brand-accent-subtle); }\n\n.col-rating[_ngcontent-%COMP%] { width: 90px; }\n.col-comment[_ngcontent-%COMP%] { width: 28%; }\n.col-agent[_ngcontent-%COMP%] { width: 14%; }\n.col-message[_ngcontent-%COMP%] { width: 26%; }\n.col-rater[_ngcontent-%COMP%] { width: 16%; }\n.col-when[_ngcontent-%COMP%] { width: 12%; }\n\n.rating-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: baseline;\n gap: 2px;\n padding: 0.35rem 0.625rem;\n border-radius: var(--mj-radius-md);\n font-size: 0.875rem;\n font-weight: 700;\n letter-spacing: -0.02em;\n}\n.rating-badge[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n font-weight: 500;\n opacity: 0.7;\n}\n.rating-badge.rating-high[_ngcontent-%COMP%] { background: var(--rating-high-bg, #ecfdf5); color: var(--rating-high, #10b981); }\n.rating-badge.rating-mid[_ngcontent-%COMP%] { background: var(--rating-mid-bg, #fffbeb); color: var(--rating-mid, #f59e0b); }\n.rating-badge.rating-low[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); color: var(--mj-status-error); }\n\n.comment-text[_ngcontent-%COMP%] {\n white-space: pre-wrap;\n word-break: break-word;\n line-height: 1.5;\n}\n.comment-text.clamped[_ngcontent-%COMP%] {\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n line-clamp: 2;\n overflow: hidden;\n}\n.message-snippet[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n line-clamp: 2;\n overflow: hidden;\n}\n\n\n\n.pagination-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-top: 0.5rem;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n.pagination-summary[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n color: var(--mj-text-secondary);\n padding: 0.5rem 0;\n}\n.feedback-pagination[_ngcontent-%COMP%] {\n display: block;\n flex: 1;\n min-width: 0;\n}\n\n.page-size-control[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n.page-size-label[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n}\n.page-size-select[_ngcontent-%COMP%] {\n padding: 0.3rem 0.5rem;\n font-size: 0.8125rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n.page-size-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n.agent-name[_ngcontent-%COMP%] { font-weight: 500; color: var(--mj-text-primary); }\n.rater-name[_ngcontent-%COMP%] { font-weight: 500; color: var(--mj-text-primary); }\n.rater-email[_ngcontent-%COMP%] { font-size: 0.6875rem; color: var(--mj-text-secondary); margin-top: 2px; }\n.when[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-size: 0.75rem; white-space: nowrap; }\n.muted[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-style: italic; }\n\n\n\n\n\n\n\n\n\n.slideout-backdrop[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: var(--mj-bg-overlay, rgba(28, 28, 34, 0.45));\n z-index: 100;\n animation: _ngcontent-%COMP%_feedback-fadeIn 0.2s ease;\n}\n@keyframes _ngcontent-%COMP%_feedback-fadeIn { from { opacity: 0; } to { opacity: 1; } }\n\n.slideout-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n width: 560px;\n max-width: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay, rgba(0, 0, 0, 0.25));\n z-index: 101;\n display: flex;\n flex-direction: column;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n transform: translateX(100%);\n overflow: hidden;\n}\n.slideout-panel.open[_ngcontent-%COMP%] { transform: translateX(0); }\n\n\n\n.slideout-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 1rem;\n padding: 20px 24px;\n background: var(--mj-brand-accent-subtle);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n.slideout-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n.slideout-title[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 22px;\n flex-shrink: 0;\n line-height: 1.2;\n}\n.slideout-title-text[_ngcontent-%COMP%] { min-width: 0; }\n.slideout-title-line[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 17px;\n color: var(--mj-text-primary);\n margin: 0 0 6px;\n line-height: 1.3;\n word-break: break-word;\n}\n.slideout-subtitle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n flex-wrap: wrap;\n}\n.slideout-subtitle[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] { color: var(--mj-text-primary); font-weight: 600; }\n\n.slideout-close[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface-hover);\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.slideout-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n\n\n.slideout-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n background: var(--mj-bg-surface);\n}\n.slideout-section[_ngcontent-%COMP%] {\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.slideout-section[_ngcontent-%COMP%]:last-child { border-bottom: none; }\n\n.section-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n margin-bottom: 0.5rem;\n}\n.comment-body[_ngcontent-%COMP%] {\n font-size: 14px;\n line-height: 1.55;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n}\n.comment-body.muted[_ngcontent-%COMP%] { font-style: italic; color: var(--mj-text-secondary); }\n\n.meta-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 0.75rem;\n}\n.meta-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 0.75rem 0.875rem;\n}\n.meta-label[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n font-weight: 600;\n margin-bottom: 0.25rem;\n}\n.meta-value[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.message-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n}\n.message-card-header[_ngcontent-%COMP%] {\n padding: 0.75rem 1.125rem;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n font-size: 0.8125rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.message-card-body[_ngcontent-%COMP%] {\n padding: 1rem 1.125rem;\n font-size: 0.875rem;\n line-height: 1.55;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 320px;\n overflow-y: auto;\n}\n\n\n\n.slideout-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n.slideout-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] { min-width: 96px; }\n.slideout-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { margin-right: 6px; }"] });
|
|
796
789
|
};
|
|
797
790
|
ConversationFeedbackResource = __decorate([
|
|
798
791
|
RegisterClass(BaseResourceComponent, 'ConversationFeedbackResource')
|
|
@@ -800,7 +793,7 @@ ConversationFeedbackResource = __decorate([
|
|
|
800
793
|
export { ConversationFeedbackResource };
|
|
801
794
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationFeedbackResource, [{
|
|
802
795
|
type: Component,
|
|
803
|
-
args: [{ standalone: false, selector: 'mj-conversation-feedback', template: "<div class=\"feedback-container\">\n\n @if (isInitializing) {\n <div class=\"loading-overlay\"><div class=\"spinner\"></div> Loading...</div>\n }\n\n @if (!isInitializing) {\n\n <div class=\"sticky-header\">\n <div class=\"page-header\">\n <div class=\"page-title-area\">\n <div class=\"page-icon\"><i class=\"fa-solid fa-comment-dots\"></i></div>\n <div>\n <h1 class=\"page-title\">Agent Feedback</h1>\n <p class=\"page-subtitle\">User ratings and comments on AI messages</p>\n </div>\n </div>\n <div class=\"page-actions\">\n <button class=\"btn-action\" (click)=\"loadFeedback()\" [disabled]=\"loading\">\n <i class=\"fa-solid fa-arrows-rotate\" [class.fa-spin]=\"loading\"></i> Refresh\n </button>\n </div>\n </div>\n\n @if (error) {\n <div class=\"error-banner\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n {{ error }}\n <button (click)=\"error = null\" aria-label=\"Dismiss error\">\u00D7</button>\n </div>\n }\n\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-total\"><i class=\"fa-solid fa-comment-dots\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.total }}</div>\n <div class=\"stat-label\">Total Ratings</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-avg\"><i class=\"fa-solid fa-star\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.avgRating }}<span class=\"stat-unit\">/10</span></div>\n <div class=\"stat-label\">Avg Rating</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-positive\"><i class=\"fa-solid fa-thumbs-up\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value rating-high-text\">{{ stats.percentPositive }}%</div>\n <div class=\"stat-label\">Positive (8-10)</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-negative\"><i class=\"fa-solid fa-thumbs-down\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value rating-low-text\">{{ stats.percentNegative }}%</div>\n <div class=\"stat-label\">Negative (1-3)</div>\n </div>\n </div>\n </div>\n\n <div class=\"filter-bar\">\n <div class=\"filter-row\">\n <div class=\"filter-group\">\n <span class=\"filter-label\">Date Range</span>\n <div class=\"btn-group\">\n <button class=\"btn-filter\" [class.active]=\"dateRange === '1d'\" (click)=\"setDateRange('1d')\">1d</button>\n <button class=\"btn-filter\" [class.active]=\"dateRange === '7d'\" (click)=\"setDateRange('7d')\">7d</button>\n <button class=\"btn-filter\" [class.active]=\"dateRange === '30d'\" (click)=\"setDateRange('30d')\">30d</button>\n <button class=\"btn-filter\" [class.active]=\"dateRange === '90d'\" (click)=\"setDateRange('90d')\">90d</button>\n <button class=\"btn-filter\" [class.active]=\"dateRange === 'all'\" (click)=\"setDateRange('all')\">All</button>\n </div>\n </div>\n <div class=\"filter-group\">\n <span class=\"filter-label\">Rating Band</span>\n <div class=\"btn-group\">\n <button class=\"btn-filter\" [class.active]=\"ratingBand === 'all'\" (click)=\"setBand('all')\">All</button>\n <button class=\"btn-filter band-high\" [class.active]=\"ratingBand === 'high'\" (click)=\"setBand('high')\">High 8-10</button>\n <button class=\"btn-filter band-mid\" [class.active]=\"ratingBand === 'mid'\" (click)=\"setBand('mid')\">Mid 4-7</button>\n <button class=\"btn-filter band-low\" [class.active]=\"ratingBand === 'low'\" (click)=\"setBand('low')\">Low 1-3</button>\n </div>\n </div>\n <div class=\"filter-group filter-search\">\n <span class=\"filter-label\">Search</span>\n <input\n type=\"text\"\n class=\"input-search\"\n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchChange()\"\n placeholder=\"Search comments, message, agent, rater...\" />\n </div>\n </div>\n <div class=\"diagnostic-line\">\n {{ totalRowCount }} {{ totalRowCount === 1 ? 'rating' : 'ratings' }} match the current filters\n </div>\n </div>\n </div>\n\n <div class=\"scrollable-content\">\n @if (loading) {\n <div class=\"loading-overlay\"><div class=\"spinner\"></div> Loading feedback...</div>\n }\n\n @if (!loading) {\n @if (rows.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-comment-slash\"></i>\n <p>No feedback matches the current filters.</p>\n </div>\n } @else {\n <div class=\"feedback-table-wrapper\">\n <table class=\"feedback-table\">\n <thead>\n <tr>\n <th class=\"col-rating\">Rating</th>\n <th class=\"col-comment\">Comments</th>\n <th class=\"col-agent\">Agent</th>\n <th class=\"col-message\">Message</th>\n <th class=\"col-rater\">Rater</th>\n <th class=\"col-when\">When</th>\n </tr>\n </thead>\n <tbody>\n @for (row of rows; track trackByRatingID($index, row)) {\n <tr\n class=\"feedback-row\"\n [class.expanded]=\"selectedRow?.ratingID === row.ratingID\"\n (click)=\"openDrawer(row)\">\n <td class=\"col-rating\">\n <span class=\"rating-badge\" [ngClass]=\"bandClassFor(row.rating)\">\n {{ row.rating }}<small>/10</small>\n </span>\n </td>\n <td class=\"col-comment\">\n @if (row.comments) {\n <div class=\"comment-text clamped\">{{ row.comments }}</div>\n } @else {\n <span class=\"muted\">(no comment)</span>\n }\n </td>\n <td class=\"col-agent\">\n <span class=\"agent-name\">{{ row.agentName || '\u2014' }}</span>\n </td>\n <td class=\"col-message\">\n @if (row.messageSnippet) {\n <span class=\"message-snippet\">{{ row.messageSnippet }}</span>\n } @else {\n <span class=\"muted\">\u2014</span>\n }\n </td>\n <td class=\"col-rater\">\n <div class=\"rater-name\">{{ row.raterName || row.raterEmail || '\u2014' }}</div>\n @if (row.raterEmail && row.raterName) {\n <div class=\"rater-email\">{{ row.raterEmail }}</div>\n }\n </td>\n <td class=\"col-when\">\n <span class=\"when\">{{ row.createdAt | date:'short' }}</span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n <!--\n Bottom bar. When the filtered set spans multiple pages mj-pagination\n renders its own full-width `1-N of M | controls` row. When it fits\n on a single page mj-pagination self-hides, so the footer renders\n a single fallback summary line in its place.\n -->\n <!--\n Bottom bar: mj-pagination on the left (it has its own internal\n `1-N of M | nav controls` layout) + page-size selector hugging the\n right edge. The selector lives outside mj-pagination because the\n shared component doesn't expose a size-change output; the parent\n owns PageSize.\n -->\n <div class=\"pagination-bar\">\n @if (isSinglePage) {\n <span class=\"pagination-summary\">\n {{ rangeStart | number }}-{{ rangeEnd | number }} of {{ totalRowCount | number }}\n {{ totalRowCount === 1 ? 'rating' : 'ratings' }}\n </span>\n } @else {\n <mj-pagination\n class=\"feedback-pagination\"\n [TotalRowCount]=\"totalRowCount\"\n [PageNumber]=\"currentPage\"\n [PageSize]=\"pageSize\"\n [IsLoading]=\"loading\"\n (PageChange)=\"onPageChange($event)\">\n </mj-pagination>\n }\n\n <label class=\"page-size-control\">\n <span class=\"page-size-label\">Rows</span>\n <select\n class=\"page-size-select\"\n [ngModel]=\"pageSize\"\n (ngModelChange)=\"onPageSizeChange($event)\">\n @for (size of pageSizeOptions; track size) {\n <option [ngValue]=\"size\">{{ size }}</option>\n }\n </select>\n </label>\n </div>\n }\n }\n </div>\n }\n\n <!-- ===== Detail slide-out panel ===== -->\n @if (selectedRow) {\n <div class=\"slideout-backdrop\" (click)=\"closeDrawer()\"></div>\n }\n\n <aside class=\"slideout-panel\"\n [class.open]=\"!!selectedRow\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"slideout-title\">\n @if (selectedRow; as r) {\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-comment-dots\"></i>\n <div class=\"slideout-title-text\">\n <h2 id=\"slideout-title\" class=\"slideout-title-line\">\n Feedback on {{ r.agentName || 'AI message' }}\n </h2>\n <div class=\"slideout-subtitle\">\n <span class=\"rating-badge\" [ngClass]=\"bandClassFor(r.rating)\">\n {{ r.rating }}<small>/10</small>\n </span>\n <span>\n Rated by <strong>{{ r.raterName || r.raterEmail || 'Unknown user' }}</strong>\n \u00B7 {{ r.createdAt | date:'medium' }}\n </span>\n </div>\n </div>\n </div>\n <button class=\"slideout-close\" (click)=\"closeDrawer()\" title=\"Close (Esc)\" aria-label=\"Close\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <div class=\"slideout-content\">\n <div class=\"slideout-section\">\n <div class=\"section-label\">Reviewer Comment</div>\n @if (r.comments) {\n <div class=\"comment-body\">{{ r.comments }}</div>\n } @else {\n <div class=\"comment-body muted\">(no comment was provided)</div>\n }\n </div>\n\n <div class=\"slideout-section\">\n <div class=\"meta-grid\">\n <div class=\"meta-card\">\n <div class=\"meta-label\">Agent</div>\n <div class=\"meta-value\">{{ r.agentName || '\u2014' }}</div>\n </div>\n <div class=\"meta-card\">\n <div class=\"meta-label\">Conversation</div>\n <div class=\"meta-value\">{{ r.conversationName || '\u2014' }}</div>\n </div>\n <div class=\"meta-card\">\n <div class=\"meta-label\">Message Role</div>\n <div class=\"meta-value\">{{ r.messageRole || '\u2014' }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"slideout-section\">\n <div class=\"message-card\">\n <div class=\"message-card-header\">\n <i class=\"fa-solid fa-message\"></i> Rated Message\n </div>\n <div class=\"message-card-body\">\n @if (r.messageText) {\n {{ r.messageText }}\n } @else {\n <span class=\"muted\">(message text unavailable)</span>\n }\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"slideout-footer\">\n <button mjButton variant=\"flat\" size=\"lg\" (click)=\"closeDrawer()\">Close</button>\n <button mjButton variant=\"primary\" size=\"lg\"\n (click)=\"openConversation()\"\n [disabled]=\"!r.conversationID\"\n [title]=\"r.conversationID ? 'Open the source conversation' : 'No conversation linked'\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n Open Conversation\n </button>\n </div>\n }\n </aside>\n</div>\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.feedback-container {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n overflow: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Sticky Header\n ----------------------------------------------------------------------------- */\n.sticky-header {\n flex-shrink: 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n/* -----------------------------------------------------------------------------\n Page Header\n ----------------------------------------------------------------------------- */\n.page-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n padding: 1rem 1.5rem;\n}\n\n.page-title-area { display: flex; align-items: center; gap: 0.75rem; }\n\n.page-icon {\n width: 40px; height: 40px;\n display: flex; align-items: center; justify-content: center;\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n font-size: 1.125rem;\n}\n\n.page-title {\n font-size: 1.25rem;\n font-weight: 700;\n margin: 0;\n letter-spacing: -0.02em;\n color: var(--mj-text-primary);\n}\n\n.page-subtitle {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.page-actions { display: flex; align-items: center; gap: 0.5rem; }\n\n.btn-action {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.875rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 180ms, border-color 180ms, color 180ms;\n}\n.btn-action:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n.btn-action:disabled { opacity: 0.5; cursor: default; }\n\n/* -----------------------------------------------------------------------------\n Stats Grid\n ----------------------------------------------------------------------------- */\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.75rem;\n padding: 0 1.5rem 1rem;\n}\n\n@media (min-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(4, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem 1.25rem;\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.stat-icon {\n width: 44px;\n height: 44px;\n border-radius: var(--mj-radius-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.125rem;\n flex-shrink: 0;\n}\n\n.stat-icon-total {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n}\n.stat-icon-avg {\n background: color-mix(in srgb, var(--mj-brand-tertiary) 16%, transparent);\n color: var(--mj-brand-tertiary);\n}\n.stat-icon-positive {\n background: var(--rating-high-bg, #ecfdf5);\n color: var(--rating-high, #10b981);\n}\n.stat-icon-negative {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.stat-content { flex: 1; min-width: 0; }\n\n.stat-value {\n font-size: 1.5rem;\n font-weight: 700;\n letter-spacing: -0.02em;\n color: var(--mj-text-primary);\n line-height: 1.1;\n}\n.stat-unit {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n font-weight: 500;\n margin-left: 2px;\n}\n.stat-label {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n margin-top: 0.125rem;\n}\n\n.rating-high-text { color: var(--rating-high, #10b981); }\n.rating-low-text { color: var(--mj-status-error); }\n\n/* -----------------------------------------------------------------------------\n Filter Bar\n ----------------------------------------------------------------------------- */\n.filter-bar {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem 1rem;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.filter-row {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n align-items: flex-end;\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.3rem;\n}\n\n.filter-search {\n flex: 0 1 auto;\n width: 280px;\n min-width: 200px;\n max-width: 360px;\n}\n\n.filter-label {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n}\n\n.btn-group { display: flex; gap: 0; }\n.btn-group .btn-filter:first-child { border-radius: var(--mj-radius-sm) 0 0 var(--mj-radius-sm); }\n.btn-group .btn-filter:last-child { border-radius: 0 var(--mj-radius-sm) var(--mj-radius-sm) 0; }\n.btn-group .btn-filter:not(:first-child) { margin-left: -1px; }\n\n.btn-filter {\n padding: 0.4rem 0.75rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 180ms, color 180ms, border-color 180ms;\n white-space: nowrap;\n}\n.btn-filter:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n.btn-filter.active {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n z-index: 1;\n position: relative;\n}\n.btn-filter.band-high.active {\n background: var(--rating-high, #10b981);\n border-color: var(--rating-high, #10b981);\n color: var(--mj-text-inverse);\n}\n.btn-filter.band-mid.active {\n background: var(--rating-mid, #f59e0b);\n border-color: var(--rating-mid, #f59e0b);\n color: var(--mj-text-inverse);\n}\n.btn-filter.band-low.active {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.input-search {\n padding: 0.45rem 0.75rem;\n font-size: 0.875rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n width: 100%;\n}\n.input-search:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n.diagnostic-line {\n font-size: 0.6875rem;\n color: var(--mj-text-secondary);\n letter-spacing: 0.02em;\n}\n\n/* -----------------------------------------------------------------------------\n Error banner\n ----------------------------------------------------------------------------- */\n.error-banner {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n margin: 0 1.5rem 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-status-error-bg);\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 35%, transparent);\n border-radius: var(--mj-radius-md);\n color: var(--mj-status-error-text);\n font-size: 0.8125rem;\n font-weight: 500;\n}\n.error-banner button {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n font-size: 1.125rem;\n color: var(--mj-status-error);\n padding: 0 0.25rem;\n}\n\n/* -----------------------------------------------------------------------------\n Scrollable Content\n ----------------------------------------------------------------------------- */\n.scrollable-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 1.25rem 1.5rem 1.5rem;\n}\n\n.loading-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.625rem;\n padding: 3rem;\n color: var(--mj-text-secondary);\n font-size: 0.8125rem;\n font-weight: 500;\n}\n.spinner {\n width: 20px; height: 20px;\n border: 2px solid var(--mj-border-default);\n border-top-color: var(--mj-brand-primary);\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n}\n@keyframes spin { to { transform: rotate(360deg); } }\n\n/* -----------------------------------------------------------------------------\n Empty State\n ----------------------------------------------------------------------------- */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 1.25rem;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n}\n.empty-state i {\n font-size: 2.25rem;\n margin-bottom: 0.875rem;\n opacity: 0.5;\n}\n.empty-state p {\n font-size: 0.875rem;\n font-weight: 500;\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Feedback Table\n ----------------------------------------------------------------------------- */\n.feedback-table-wrapper {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n overflow: auto;\n}\n\n.feedback-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.8125rem;\n table-layout: fixed;\n}\n\n.feedback-table thead {\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n.feedback-table th {\n text-align: left;\n font-size: 0.6875rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n padding: 0.75rem 0.875rem;\n}\n.feedback-table td {\n padding: 0.875rem;\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-primary);\n vertical-align: top;\n}\n\n.feedback-row {\n cursor: pointer;\n transition: background 180ms;\n}\n.feedback-row:hover { background: var(--mj-bg-surface-hover); }\n.feedback-row.expanded { background: var(--mj-brand-accent-subtle); }\n\n.col-rating { width: 90px; }\n.col-comment { width: 28%; }\n.col-agent { width: 14%; }\n.col-message { width: 26%; }\n.col-rater { width: 16%; }\n.col-when { width: 12%; }\n\n.rating-badge {\n display: inline-flex;\n align-items: baseline;\n gap: 2px;\n padding: 0.35rem 0.625rem;\n border-radius: var(--mj-radius-md);\n font-size: 0.875rem;\n font-weight: 700;\n letter-spacing: -0.02em;\n}\n.rating-badge small {\n font-size: 0.625rem;\n font-weight: 500;\n opacity: 0.7;\n}\n.rating-badge.rating-high { background: var(--rating-high-bg, #ecfdf5); color: var(--rating-high, #10b981); }\n.rating-badge.rating-mid { background: var(--rating-mid-bg, #fffbeb); color: var(--rating-mid, #f59e0b); }\n.rating-badge.rating-low { background: var(--mj-status-error-bg); color: var(--mj-status-error); }\n\n.comment-text {\n white-space: pre-wrap;\n word-break: break-word;\n line-height: 1.5;\n}\n.comment-text.clamped {\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n line-clamp: 2;\n overflow: hidden;\n}\n.message-snippet {\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n line-clamp: 2;\n overflow: hidden;\n}\n/* Bottom row: mj-pagination (or the single-page summary) takes flex:1; the\n page-size selector hugs the right edge next to the nav controls. */\n.pagination-bar {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-top: 0.5rem;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n.pagination-summary {\n flex: 1;\n font-weight: 500;\n color: var(--mj-text-secondary);\n padding: 0.5rem 0;\n}\n.feedback-pagination {\n display: block;\n flex: 1;\n min-width: 0;\n}\n\n.page-size-control {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n.page-size-label {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n}\n.page-size-select {\n padding: 0.3rem 0.5rem;\n font-size: 0.8125rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n.page-size-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n.agent-name { font-weight: 500; color: var(--mj-text-primary); }\n.rater-name { font-weight: 500; color: var(--mj-text-primary); }\n.rater-email { font-size: 0.6875rem; color: var(--mj-text-secondary); margin-top: 2px; }\n.when { color: var(--mj-text-secondary); font-size: 0.75rem; white-space: nowrap; }\n.muted { color: var(--mj-text-secondary); font-style: italic; }\n\n/* -----------------------------------------------------------------------------\n Slide-out Panel \u2014 matches the MJ slideout pattern used elsewhere in Explorer\n (see api-key-edit-panel.component.css). Scoped to the feedback-container\n via `position: absolute` so the MJ Explorer chrome (tab bar, app nav) sits\n above it correctly \u2014 `position: fixed` would otherwise be re-anchored by\n any ancestor with a `transform` set.\n ----------------------------------------------------------------------------- */\n.slideout-backdrop {\n position: absolute;\n inset: 0;\n background: var(--mj-bg-overlay, rgba(28, 28, 34, 0.45));\n z-index: 100;\n animation: feedback-fadeIn 0.2s ease;\n}\n@keyframes feedback-fadeIn { from { opacity: 0; } to { opacity: 1; } }\n\n.slideout-panel {\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n width: 560px;\n max-width: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay, rgba(0, 0, 0, 0.25));\n z-index: 101;\n display: flex;\n flex-direction: column;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n transform: translateX(100%);\n overflow: hidden;\n}\n.slideout-panel.open { transform: translateX(0); }\n\n/* Header */\n.slideout-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 1rem;\n padding: 20px 24px;\n background: var(--mj-brand-accent-subtle);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n.slideout-title {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n.slideout-title > i {\n color: var(--mj-brand-primary);\n font-size: 22px;\n flex-shrink: 0;\n line-height: 1.2;\n}\n.slideout-title-text { min-width: 0; }\n.slideout-title-line {\n font-weight: 700;\n font-size: 17px;\n color: var(--mj-text-primary);\n margin: 0 0 6px;\n line-height: 1.3;\n word-break: break-word;\n}\n.slideout-subtitle {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n flex-wrap: wrap;\n}\n.slideout-subtitle strong { color: var(--mj-text-primary); font-weight: 600; }\n\n.slideout-close {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface-hover);\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.slideout-close:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n/* Content */\n.slideout-content {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n background: var(--mj-bg-surface);\n}\n.slideout-section {\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.slideout-section:last-child { border-bottom: none; }\n\n.section-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n margin-bottom: 0.5rem;\n}\n.comment-body {\n font-size: 14px;\n line-height: 1.55;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n}\n.comment-body.muted { font-style: italic; color: var(--mj-text-secondary); }\n\n.meta-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 0.75rem;\n}\n.meta-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 0.75rem 0.875rem;\n}\n.meta-label {\n font-size: 0.625rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n font-weight: 600;\n margin-bottom: 0.25rem;\n}\n.meta-value {\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.message-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n}\n.message-card-header {\n padding: 0.75rem 1.125rem;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n font-size: 0.8125rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.message-card-body {\n padding: 1rem 1.125rem;\n font-size: 0.875rem;\n line-height: 1.55;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 320px;\n overflow-y: auto;\n}\n\n/* Footer */\n.slideout-footer {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n.slideout-footer button { min-width: 96px; }\n.slideout-footer button i { margin-right: 6px; }\n"] }]
|
|
796
|
+
args: [{ standalone: false, selector: 'mj-conversation-feedback', template: "<div class=\"feedback-container\">\n\n @if (isInitializing) {\n <div class=\"loading-overlay\"><div class=\"spinner\"></div> Loading...</div>\n }\n\n @if (!isInitializing) {\n\n <div class=\"sticky-header\">\n <div class=\"page-header\">\n <div class=\"page-title-area\">\n <div class=\"page-icon\"><i class=\"fa-solid fa-comment-dots\"></i></div>\n <div>\n <h1 class=\"page-title\">Agent Feedback</h1>\n <p class=\"page-subtitle\">User ratings and comments on AI messages</p>\n </div>\n </div>\n <div class=\"page-actions\">\n <button class=\"btn-action\" (click)=\"loadFeedback()\" [disabled]=\"loading\">\n <i class=\"fa-solid fa-arrows-rotate\" [class.fa-spin]=\"loading\"></i> Refresh\n </button>\n </div>\n </div>\n\n @if (error) {\n <mj-alert Variant=\"error\" class=\"feedback-error-spacing\" Dismissible (Dismissed)=\"error = null\">{{ error }}</mj-alert>\n }\n\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-total\"><i class=\"fa-solid fa-comment-dots\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.total }}</div>\n <div class=\"stat-label\">Total Ratings</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-avg\"><i class=\"fa-solid fa-star\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.avgRating }}<span class=\"stat-unit\">/10</span></div>\n <div class=\"stat-label\">Avg Rating</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-positive\"><i class=\"fa-solid fa-thumbs-up\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value rating-high-text\">{{ stats.percentPositive }}%</div>\n <div class=\"stat-label\">Positive (8-10)</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon stat-icon-negative\"><i class=\"fa-solid fa-thumbs-down\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value rating-low-text\">{{ stats.percentNegative }}%</div>\n <div class=\"stat-label\">Negative (1-3)</div>\n </div>\n </div>\n </div>\n\n <div class=\"filter-bar\">\n <div class=\"filter-row\">\n <div class=\"filter-group\">\n <span class=\"filter-label\">Date Range</span>\n <div class=\"btn-group\">\n <button class=\"btn-filter\" [class.active]=\"dateRange === '1d'\" (click)=\"setDateRange('1d')\">1d</button>\n <button class=\"btn-filter\" [class.active]=\"dateRange === '7d'\" (click)=\"setDateRange('7d')\">7d</button>\n <button class=\"btn-filter\" [class.active]=\"dateRange === '30d'\" (click)=\"setDateRange('30d')\">30d</button>\n <button class=\"btn-filter\" [class.active]=\"dateRange === '90d'\" (click)=\"setDateRange('90d')\">90d</button>\n <button class=\"btn-filter\" [class.active]=\"dateRange === 'all'\" (click)=\"setDateRange('all')\">All</button>\n </div>\n </div>\n <div class=\"filter-group\">\n <span class=\"filter-label\">Rating Band</span>\n <div class=\"btn-group\">\n <button class=\"btn-filter\" [class.active]=\"ratingBand === 'all'\" (click)=\"setBand('all')\">All</button>\n <button class=\"btn-filter band-high\" [class.active]=\"ratingBand === 'high'\" (click)=\"setBand('high')\">High 8-10</button>\n <button class=\"btn-filter band-mid\" [class.active]=\"ratingBand === 'mid'\" (click)=\"setBand('mid')\">Mid 4-7</button>\n <button class=\"btn-filter band-low\" [class.active]=\"ratingBand === 'low'\" (click)=\"setBand('low')\">Low 1-3</button>\n </div>\n </div>\n <div class=\"filter-group filter-search\">\n <span class=\"filter-label\">Search</span>\n <input\n type=\"text\"\n class=\"input-search\"\n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchChange()\"\n placeholder=\"Search comments, message, agent, rater...\" />\n </div>\n </div>\n <div class=\"diagnostic-line\">\n {{ totalRowCount }} {{ totalRowCount === 1 ? 'rating' : 'ratings' }} match the current filters\n </div>\n </div>\n </div>\n\n <div class=\"scrollable-content\">\n @if (loading) {\n <div class=\"loading-overlay\"><div class=\"spinner\"></div> Loading feedback...</div>\n }\n\n @if (!loading) {\n @if (rows.length === 0) {\n <mj-empty-state\n class=\"feedback-empty-state\"\n Variant=\"no-results\"\n Icon=\"fa-solid fa-comment-slash\"\n Title=\"No feedback matches the current filters.\" />\n } @else {\n <div class=\"feedback-table-wrapper\">\n <table class=\"feedback-table\">\n <thead>\n <tr>\n <th class=\"col-rating\">Rating</th>\n <th class=\"col-comment\">Comments</th>\n <th class=\"col-agent\">Agent</th>\n <th class=\"col-message\">Message</th>\n <th class=\"col-rater\">Rater</th>\n <th class=\"col-when\">When</th>\n </tr>\n </thead>\n <tbody>\n @for (row of rows; track trackByRatingID($index, row)) {\n <tr\n class=\"feedback-row\"\n [class.expanded]=\"selectedRow?.ratingID === row.ratingID\"\n (click)=\"openDrawer(row)\">\n <td class=\"col-rating\">\n <span class=\"rating-badge\" [ngClass]=\"bandClassFor(row.rating)\">\n {{ row.rating }}<small>/10</small>\n </span>\n </td>\n <td class=\"col-comment\">\n @if (row.comments) {\n <div class=\"comment-text clamped\">{{ row.comments }}</div>\n } @else {\n <span class=\"muted\">(no comment)</span>\n }\n </td>\n <td class=\"col-agent\">\n <span class=\"agent-name\">{{ row.agentName || '\u2014' }}</span>\n </td>\n <td class=\"col-message\">\n @if (row.messageSnippet) {\n <span class=\"message-snippet\">{{ row.messageSnippet }}</span>\n } @else {\n <span class=\"muted\">\u2014</span>\n }\n </td>\n <td class=\"col-rater\">\n <div class=\"rater-name\">{{ row.raterName || row.raterEmail || '\u2014' }}</div>\n @if (row.raterEmail && row.raterName) {\n <div class=\"rater-email\">{{ row.raterEmail }}</div>\n }\n </td>\n <td class=\"col-when\">\n <span class=\"when\">{{ row.createdAt | date:'short' }}</span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n <!--\n Bottom bar. When the filtered set spans multiple pages mj-pagination\n renders its own full-width `1-N of M | controls` row. When it fits\n on a single page mj-pagination self-hides, so the footer renders\n a single fallback summary line in its place.\n -->\n <!--\n Bottom bar: mj-pagination on the left (it has its own internal\n `1-N of M | nav controls` layout) + page-size selector hugging the\n right edge. The selector lives outside mj-pagination because the\n shared component doesn't expose a size-change output; the parent\n owns PageSize.\n -->\n <div class=\"pagination-bar\">\n @if (isSinglePage) {\n <span class=\"pagination-summary\">\n {{ rangeStart | number }}-{{ rangeEnd | number }} of {{ totalRowCount | number }}\n {{ totalRowCount === 1 ? 'rating' : 'ratings' }}\n </span>\n } @else {\n <mj-pagination\n class=\"feedback-pagination\"\n [TotalRowCount]=\"totalRowCount\"\n [PageNumber]=\"currentPage\"\n [PageSize]=\"pageSize\"\n [IsLoading]=\"loading\"\n (PageChange)=\"onPageChange($event)\">\n </mj-pagination>\n }\n\n <label class=\"page-size-control\">\n <span class=\"page-size-label\">Rows</span>\n <select\n class=\"page-size-select\"\n [ngModel]=\"pageSize\"\n (ngModelChange)=\"onPageSizeChange($event)\">\n @for (size of pageSizeOptions; track size) {\n <option [ngValue]=\"size\">{{ size }}</option>\n }\n </select>\n </label>\n </div>\n }\n }\n </div>\n }\n\n <!-- ===== Detail slide-out panel ===== -->\n @if (selectedRow) {\n <div class=\"slideout-backdrop\" (click)=\"closeDrawer()\"></div>\n }\n\n <aside class=\"slideout-panel\"\n [class.open]=\"!!selectedRow\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"slideout-title\">\n @if (selectedRow; as r) {\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-comment-dots\"></i>\n <div class=\"slideout-title-text\">\n <h2 id=\"slideout-title\" class=\"slideout-title-line\">\n Feedback on {{ r.agentName || 'AI message' }}\n </h2>\n <div class=\"slideout-subtitle\">\n <span class=\"rating-badge\" [ngClass]=\"bandClassFor(r.rating)\">\n {{ r.rating }}<small>/10</small>\n </span>\n <span>\n Rated by <strong>{{ r.raterName || r.raterEmail || 'Unknown user' }}</strong>\n \u00B7 {{ r.createdAt | date:'medium' }}\n </span>\n </div>\n </div>\n </div>\n <button class=\"slideout-close\" (click)=\"closeDrawer()\" title=\"Close (Esc)\" aria-label=\"Close\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <div class=\"slideout-content\">\n <div class=\"slideout-section\">\n <div class=\"section-label\">Reviewer Comment</div>\n @if (r.comments) {\n <div class=\"comment-body\">{{ r.comments }}</div>\n } @else {\n <div class=\"comment-body muted\">(no comment was provided)</div>\n }\n </div>\n\n <div class=\"slideout-section\">\n <div class=\"meta-grid\">\n <div class=\"meta-card\">\n <div class=\"meta-label\">Agent</div>\n <div class=\"meta-value\">{{ r.agentName || '\u2014' }}</div>\n </div>\n <div class=\"meta-card\">\n <div class=\"meta-label\">Conversation</div>\n <div class=\"meta-value\">{{ r.conversationName || '\u2014' }}</div>\n </div>\n <div class=\"meta-card\">\n <div class=\"meta-label\">Message Role</div>\n <div class=\"meta-value\">{{ r.messageRole || '\u2014' }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"slideout-section\">\n <div class=\"message-card\">\n <div class=\"message-card-header\">\n <i class=\"fa-solid fa-message\"></i> Rated Message\n </div>\n <div class=\"message-card-body\">\n @if (r.messageText) {\n {{ r.messageText }}\n } @else {\n <span class=\"muted\">(message text unavailable)</span>\n }\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"slideout-footer\">\n <button mjButton variant=\"flat\" size=\"lg\" (click)=\"closeDrawer()\">Close</button>\n <button mjButton variant=\"primary\" size=\"lg\"\n (click)=\"openConversation()\"\n [disabled]=\"!r.conversationID\"\n [title]=\"r.conversationID ? 'Open the source conversation' : 'No conversation linked'\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n Open Conversation\n </button>\n </div>\n }\n </aside>\n</div>\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.feedback-container {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n overflow: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Sticky Header\n ----------------------------------------------------------------------------- */\n.sticky-header {\n flex-shrink: 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n/* -----------------------------------------------------------------------------\n Page Header\n ----------------------------------------------------------------------------- */\n.page-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n padding: 1rem 1.5rem;\n}\n\n.page-title-area { display: flex; align-items: center; gap: 0.75rem; }\n\n.page-icon {\n width: 40px; height: 40px;\n display: flex; align-items: center; justify-content: center;\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n font-size: 1.125rem;\n}\n\n.page-title {\n font-size: 1.25rem;\n font-weight: 700;\n margin: 0;\n letter-spacing: -0.02em;\n color: var(--mj-text-primary);\n}\n\n.page-subtitle {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.page-actions { display: flex; align-items: center; gap: 0.5rem; }\n\n.btn-action {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.875rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 180ms, border-color 180ms, color 180ms;\n}\n.btn-action:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n.btn-action:disabled { opacity: 0.5; cursor: default; }\n\n/* -----------------------------------------------------------------------------\n Stats Grid\n ----------------------------------------------------------------------------- */\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.75rem;\n padding: 0 1.5rem 1rem;\n}\n\n@media (min-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(4, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem 1.25rem;\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.stat-icon {\n width: 44px;\n height: 44px;\n border-radius: var(--mj-radius-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.125rem;\n flex-shrink: 0;\n}\n\n.stat-icon-total {\n background: var(--mj-brand-accent-subtle);\n color: var(--mj-brand-primary);\n}\n.stat-icon-avg {\n background: color-mix(in srgb, var(--mj-brand-tertiary) 16%, transparent);\n color: var(--mj-brand-tertiary);\n}\n.stat-icon-positive {\n background: var(--rating-high-bg, #ecfdf5);\n color: var(--rating-high, #10b981);\n}\n.stat-icon-negative {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.stat-content { flex: 1; min-width: 0; }\n\n.stat-value {\n font-size: 1.5rem;\n font-weight: 700;\n letter-spacing: -0.02em;\n color: var(--mj-text-primary);\n line-height: 1.1;\n}\n.stat-unit {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n font-weight: 500;\n margin-left: 2px;\n}\n.stat-label {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n margin-top: 0.125rem;\n}\n\n.rating-high-text { color: var(--rating-high, #10b981); }\n.rating-low-text { color: var(--mj-status-error); }\n\n/* -----------------------------------------------------------------------------\n Filter Bar\n ----------------------------------------------------------------------------- */\n.filter-bar {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem 1rem;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.filter-row {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n align-items: flex-end;\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.3rem;\n}\n\n.filter-search {\n flex: 0 1 auto;\n width: 280px;\n min-width: 200px;\n max-width: 360px;\n}\n\n.filter-label {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n}\n\n.btn-group { display: flex; gap: 0; }\n.btn-group .btn-filter:first-child { border-radius: var(--mj-radius-sm) 0 0 var(--mj-radius-sm); }\n.btn-group .btn-filter:last-child { border-radius: 0 var(--mj-radius-sm) var(--mj-radius-sm) 0; }\n.btn-group .btn-filter:not(:first-child) { margin-left: -1px; }\n\n.btn-filter {\n padding: 0.4rem 0.75rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 180ms, color 180ms, border-color 180ms;\n white-space: nowrap;\n}\n.btn-filter:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n.btn-filter.active {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n z-index: 1;\n position: relative;\n}\n.btn-filter.band-high.active {\n background: var(--rating-high, #10b981);\n border-color: var(--rating-high, #10b981);\n color: var(--mj-text-inverse);\n}\n.btn-filter.band-mid.active {\n background: var(--rating-mid, #f59e0b);\n border-color: var(--rating-mid, #f59e0b);\n color: var(--mj-text-inverse);\n}\n.btn-filter.band-low.active {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.input-search {\n padding: 0.45rem 0.75rem;\n font-size: 0.875rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n width: 100%;\n}\n.input-search:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n.diagnostic-line {\n font-size: 0.6875rem;\n color: var(--mj-text-secondary);\n letter-spacing: 0.02em;\n}\n\n/* -----------------------------------------------------------------------------\n Error banner \u2014 positions the error mj-alert (component is margin-less but for bottom)\n ----------------------------------------------------------------------------- */\n.feedback-error-spacing { margin: 0 1.5rem 0.75rem; }\n\n/* -----------------------------------------------------------------------------\n Scrollable Content\n ----------------------------------------------------------------------------- */\n.scrollable-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 1.25rem 1.5rem 1.5rem;\n}\n\n.loading-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.625rem;\n padding: 3rem;\n color: var(--mj-text-secondary);\n font-size: 0.8125rem;\n font-weight: 500;\n}\n.spinner {\n width: 20px; height: 20px;\n border: 2px solid var(--mj-border-default);\n border-top-color: var(--mj-brand-primary);\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n}\n@keyframes spin { to { transform: rotate(360deg); } }\n\n/* -----------------------------------------------------------------------------\n Empty State\n ----------------------------------------------------------------------------- */\n.feedback-empty-state {\n display: block;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n}\n\n/* -----------------------------------------------------------------------------\n Feedback Table\n ----------------------------------------------------------------------------- */\n.feedback-table-wrapper {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n overflow: auto;\n}\n\n.feedback-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.8125rem;\n table-layout: fixed;\n}\n\n.feedback-table thead {\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n.feedback-table th {\n text-align: left;\n font-size: 0.6875rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n padding: 0.75rem 0.875rem;\n}\n.feedback-table td {\n padding: 0.875rem;\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-primary);\n vertical-align: top;\n}\n\n.feedback-row {\n cursor: pointer;\n transition: background 180ms;\n}\n.feedback-row:hover { background: var(--mj-bg-surface-hover); }\n.feedback-row.expanded { background: var(--mj-brand-accent-subtle); }\n\n.col-rating { width: 90px; }\n.col-comment { width: 28%; }\n.col-agent { width: 14%; }\n.col-message { width: 26%; }\n.col-rater { width: 16%; }\n.col-when { width: 12%; }\n\n.rating-badge {\n display: inline-flex;\n align-items: baseline;\n gap: 2px;\n padding: 0.35rem 0.625rem;\n border-radius: var(--mj-radius-md);\n font-size: 0.875rem;\n font-weight: 700;\n letter-spacing: -0.02em;\n}\n.rating-badge small {\n font-size: 0.625rem;\n font-weight: 500;\n opacity: 0.7;\n}\n.rating-badge.rating-high { background: var(--rating-high-bg, #ecfdf5); color: var(--rating-high, #10b981); }\n.rating-badge.rating-mid { background: var(--rating-mid-bg, #fffbeb); color: var(--rating-mid, #f59e0b); }\n.rating-badge.rating-low { background: var(--mj-status-error-bg); color: var(--mj-status-error); }\n\n.comment-text {\n white-space: pre-wrap;\n word-break: break-word;\n line-height: 1.5;\n}\n.comment-text.clamped {\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n line-clamp: 2;\n overflow: hidden;\n}\n.message-snippet {\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n line-clamp: 2;\n overflow: hidden;\n}\n/* Bottom row: mj-pagination (or the single-page summary) takes flex:1; the\n page-size selector hugs the right edge next to the nav controls. */\n.pagination-bar {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-top: 0.5rem;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n.pagination-summary {\n flex: 1;\n font-weight: 500;\n color: var(--mj-text-secondary);\n padding: 0.5rem 0;\n}\n.feedback-pagination {\n display: block;\n flex: 1;\n min-width: 0;\n}\n\n.page-size-control {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n.page-size-label {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n}\n.page-size-select {\n padding: 0.3rem 0.5rem;\n font-size: 0.8125rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n.page-size-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n.agent-name { font-weight: 500; color: var(--mj-text-primary); }\n.rater-name { font-weight: 500; color: var(--mj-text-primary); }\n.rater-email { font-size: 0.6875rem; color: var(--mj-text-secondary); margin-top: 2px; }\n.when { color: var(--mj-text-secondary); font-size: 0.75rem; white-space: nowrap; }\n.muted { color: var(--mj-text-secondary); font-style: italic; }\n\n/* -----------------------------------------------------------------------------\n Slide-out Panel \u2014 matches the MJ slideout pattern used elsewhere in Explorer\n (see api-key-edit-panel.component.css). Scoped to the feedback-container\n via `position: absolute` so the MJ Explorer chrome (tab bar, app nav) sits\n above it correctly \u2014 `position: fixed` would otherwise be re-anchored by\n any ancestor with a `transform` set.\n ----------------------------------------------------------------------------- */\n.slideout-backdrop {\n position: absolute;\n inset: 0;\n background: var(--mj-bg-overlay, rgba(28, 28, 34, 0.45));\n z-index: 100;\n animation: feedback-fadeIn 0.2s ease;\n}\n@keyframes feedback-fadeIn { from { opacity: 0; } to { opacity: 1; } }\n\n.slideout-panel {\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n width: 560px;\n max-width: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay, rgba(0, 0, 0, 0.25));\n z-index: 101;\n display: flex;\n flex-direction: column;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n transform: translateX(100%);\n overflow: hidden;\n}\n.slideout-panel.open { transform: translateX(0); }\n\n/* Header */\n.slideout-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 1rem;\n padding: 20px 24px;\n background: var(--mj-brand-accent-subtle);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n.slideout-title {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n.slideout-title > i {\n color: var(--mj-brand-primary);\n font-size: 22px;\n flex-shrink: 0;\n line-height: 1.2;\n}\n.slideout-title-text { min-width: 0; }\n.slideout-title-line {\n font-weight: 700;\n font-size: 17px;\n color: var(--mj-text-primary);\n margin: 0 0 6px;\n line-height: 1.3;\n word-break: break-word;\n}\n.slideout-subtitle {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n flex-wrap: wrap;\n}\n.slideout-subtitle strong { color: var(--mj-text-primary); font-weight: 600; }\n\n.slideout-close {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface-hover);\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.slideout-close:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n/* Content */\n.slideout-content {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n background: var(--mj-bg-surface);\n}\n.slideout-section {\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.slideout-section:last-child { border-bottom: none; }\n\n.section-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n margin-bottom: 0.5rem;\n}\n.comment-body {\n font-size: 14px;\n line-height: 1.55;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n}\n.comment-body.muted { font-style: italic; color: var(--mj-text-secondary); }\n\n.meta-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 0.75rem;\n}\n.meta-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 0.75rem 0.875rem;\n}\n.meta-label {\n font-size: 0.625rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-secondary);\n font-weight: 600;\n margin-bottom: 0.25rem;\n}\n.meta-value {\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.message-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n}\n.message-card-header {\n padding: 0.75rem 1.125rem;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n font-size: 0.8125rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.message-card-body {\n padding: 1rem 1.125rem;\n font-size: 0.875rem;\n line-height: 1.55;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 320px;\n overflow-y: auto;\n}\n\n/* Footer */\n.slideout-footer {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n.slideout-footer button { min-width: 96px; }\n.slideout-footer button i { margin-right: 6px; }\n"] }]
|
|
804
797
|
}], null, { onEscape: [{
|
|
805
798
|
type: HostListener,
|
|
806
799
|
args: ['document:keydown.escape']
|