@memberjunction/ng-artifacts 5.21.0 → 5.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (19) hide show
  1. package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts +10 -0
  2. package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts.map +1 -1
  3. package/dist/lib/components/artifact-type-plugin-viewer.component.js +15 -1
  4. package/dist/lib/components/artifact-type-plugin-viewer.component.js.map +1 -1
  5. package/dist/lib/components/artifact-viewer-panel.component.js +155 -145
  6. package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
  7. package/dist/lib/components/base-artifact-viewer.component.d.ts +16 -0
  8. package/dist/lib/components/base-artifact-viewer.component.d.ts.map +1 -1
  9. package/dist/lib/components/base-artifact-viewer.component.js +20 -0
  10. package/dist/lib/components/base-artifact-viewer.component.js.map +1 -1
  11. package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts +8 -1
  12. package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts.map +1 -1
  13. package/dist/lib/components/plugins/component-artifact-viewer.component.js +26 -27
  14. package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
  15. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.d.ts +4 -2
  16. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.d.ts.map +1 -1
  17. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js +79 -63
  18. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js.map +1 -1
  19. package/package.json +15 -16
@@ -2,8 +2,10 @@ import { Component, Input, Output, EventEmitter, ChangeDetectorRef, inject } fro
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { FormsModule } from '@angular/forms';
4
4
  import { Metadata } from '@memberjunction/core';
5
+ import { MarkdownModule } from '@memberjunction/ng-markdown';
5
6
  import * as i0 from "@angular/core";
6
7
  import * as i1 from "@angular/forms";
8
+ import * as i2 from "@memberjunction/ng-markdown";
7
9
  const _c0 = () => [1, 2, 3, 4, 5];
8
10
  const _forTrack0 = ($index, $item) => $item.spec.name;
9
11
  function ComponentFeedbackPanelComponent_Conditional_15_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
@@ -64,40 +66,44 @@ function ComponentFeedbackPanelComponent_Conditional_16_Template(rf, ctx) { if (
64
66
  i0.ɵɵelementEnd()();
65
67
  } }
66
68
  function ComponentFeedbackPanelComponent_Conditional_18_Conditional_5_Template(rf, ctx) { if (rf & 1) {
67
- i0.ɵɵelementStart(0, "p", 27);
68
- i0.ɵɵtext(1);
69
- i0.ɵɵelementEnd();
69
+ i0.ɵɵelement(0, "mj-markdown", 27);
70
70
  } if (rf & 2) {
71
71
  const ctx_r2 = i0.ɵɵnextContext(2);
72
- i0.ɵɵadvance();
73
- i0.ɵɵtextInterpolate(ctx_r2.SelectedSpec.description);
72
+ i0.ɵɵproperty("data", ctx_r2.SelectedSpec.description);
73
+ } }
74
+ function ComponentFeedbackPanelComponent_Conditional_18_For_11_Case_3_Template(rf, ctx) { if (rf & 1) {
75
+ i0.ɵɵelement(0, "i", 44);
76
+ } }
77
+ function ComponentFeedbackPanelComponent_Conditional_18_For_11_Case_4_Template(rf, ctx) { if (rf & 1) {
78
+ i0.ɵɵelement(0, "i", 45);
79
+ } }
80
+ function ComponentFeedbackPanelComponent_Conditional_18_For_11_Case_5_Template(rf, ctx) { if (rf & 1) {
81
+ i0.ɵɵelement(0, "i", 46);
74
82
  } }
75
83
  function ComponentFeedbackPanelComponent_Conditional_18_For_11_Template(rf, ctx) { if (rf & 1) {
76
84
  const _r6 = i0.ɵɵgetCurrentView();
77
- i0.ɵɵelementStart(0, "i", 43);
78
- i0.ɵɵlistener("click", function ComponentFeedbackPanelComponent_Conditional_18_For_11_Template_i_click_0_listener() { const star_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SetRating(star_r7)); })("mouseenter", function ComponentFeedbackPanelComponent_Conditional_18_For_11_Template_i_mouseenter_0_listener() { const star_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SetHoverRating(star_r7)); })("mouseleave", function ComponentFeedbackPanelComponent_Conditional_18_For_11_Template_i_mouseleave_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.ClearHoverRating()); });
85
+ i0.ɵɵelementStart(0, "span", 31)(1, "span", 42);
86
+ i0.ɵɵlistener("click", function ComponentFeedbackPanelComponent_Conditional_18_For_11_Template_span_click_1_listener() { const star_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SetRating(star_r7 - 0.5)); })("mouseenter", function ComponentFeedbackPanelComponent_Conditional_18_For_11_Template_span_mouseenter_1_listener() { const star_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SetHoverRating(star_r7 - 0.5)); });
87
+ i0.ɵɵelementEnd();
88
+ i0.ɵɵelementStart(2, "span", 43);
89
+ i0.ɵɵlistener("click", function ComponentFeedbackPanelComponent_Conditional_18_For_11_Template_span_click_2_listener() { const star_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SetRating(star_r7)); })("mouseenter", function ComponentFeedbackPanelComponent_Conditional_18_For_11_Template_span_mouseenter_2_listener() { const star_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SetHoverRating(star_r7)); });
90
+ i0.ɵɵelementEnd();
91
+ i0.ɵɵconditionalCreate(3, ComponentFeedbackPanelComponent_Conditional_18_For_11_Case_3_Template, 1, 0, "i", 44)(4, ComponentFeedbackPanelComponent_Conditional_18_For_11_Case_4_Template, 1, 0, "i", 45)(5, ComponentFeedbackPanelComponent_Conditional_18_For_11_Case_5_Template, 1, 0, "i", 46);
79
92
  i0.ɵɵelementEnd();
80
93
  } if (rf & 2) {
94
+ let tmp_11_0;
81
95
  const star_r7 = ctx.$implicit;
82
96
  const ctx_r2 = i0.ɵɵnextContext(2);
83
- i0.ɵɵclassProp("fa-solid", ctx_r2.IsStarFilled(star_r7))("fa-regular", !ctx_r2.IsStarFilled(star_r7))("fa-star", true);
97
+ i0.ɵɵadvance(3);
98
+ i0.ɵɵconditional((tmp_11_0 = ctx_r2.GetStarState(star_r7)) === "full" ? 3 : tmp_11_0 === "half" ? 4 : 5);
84
99
  } }
85
100
  function ComponentFeedbackPanelComponent_Conditional_18_Conditional_12_Template(rf, ctx) { if (rf & 1) {
86
101
  i0.ɵɵelementStart(0, "span", 32);
87
- i0.ɵɵtext(1);
88
- i0.ɵɵelementEnd();
89
- } if (rf & 2) {
90
- const ctx_r2 = i0.ɵɵnextContext(2);
91
- i0.ɵɵadvance();
92
- i0.ɵɵtextInterpolate1("", ctx_r2.StarRating, " out of 5 stars");
93
- } }
94
- function ComponentFeedbackPanelComponent_Conditional_18_Conditional_13_Template(rf, ctx) { if (rf & 1) {
95
- i0.ɵɵelementStart(0, "span", 33);
96
102
  i0.ɵɵtext(1, "Click to rate");
97
103
  i0.ɵɵelementEnd();
98
104
  } }
99
- function ComponentFeedbackPanelComponent_Conditional_18_Conditional_21_Template(rf, ctx) { if (rf & 1) {
100
- i0.ɵɵelementStart(0, "span", 38);
105
+ function ComponentFeedbackPanelComponent_Conditional_18_Conditional_20_Template(rf, ctx) { if (rf & 1) {
106
+ i0.ɵɵelementStart(0, "span", 37);
101
107
  i0.ɵɵtext(1);
102
108
  i0.ɵɵelementEnd();
103
109
  } if (rf & 2) {
@@ -105,28 +111,28 @@ function ComponentFeedbackPanelComponent_Conditional_18_Conditional_21_Template(
105
111
  i0.ɵɵadvance();
106
112
  i0.ɵɵtextInterpolate1("", ctx_r2.FeedbackComments.length, "/1000");
107
113
  } }
108
- function ComponentFeedbackPanelComponent_Conditional_18_Conditional_24_Template(rf, ctx) { if (rf & 1) {
109
- i0.ɵɵelement(0, "i", 44);
114
+ function ComponentFeedbackPanelComponent_Conditional_18_Conditional_23_Template(rf, ctx) { if (rf & 1) {
115
+ i0.ɵɵelement(0, "i", 47);
110
116
  i0.ɵɵelementStart(1, "span");
111
117
  i0.ɵɵtext(2, "Submitting...");
112
118
  i0.ɵɵelementEnd();
113
119
  } }
114
- function ComponentFeedbackPanelComponent_Conditional_18_Conditional_25_Template(rf, ctx) { if (rf & 1) {
115
- i0.ɵɵelement(0, "i", 45);
120
+ function ComponentFeedbackPanelComponent_Conditional_18_Conditional_24_Template(rf, ctx) { if (rf & 1) {
121
+ i0.ɵɵelement(0, "i", 48);
116
122
  i0.ɵɵelementStart(1, "span");
117
123
  i0.ɵɵtext(2, "Submit Feedback");
118
124
  i0.ɵɵelementEnd();
119
125
  } }
120
- function ComponentFeedbackPanelComponent_Conditional_18_Conditional_26_Template(rf, ctx) { if (rf & 1) {
121
- i0.ɵɵelementStart(0, "div", 41);
122
- i0.ɵɵelement(1, "i", 46);
126
+ function ComponentFeedbackPanelComponent_Conditional_18_Conditional_25_Template(rf, ctx) { if (rf & 1) {
127
+ i0.ɵɵelementStart(0, "div", 40);
128
+ i0.ɵɵelement(1, "i", 49);
123
129
  i0.ɵɵelementStart(2, "span");
124
130
  i0.ɵɵtext(3, "Feedback submitted successfully!");
125
131
  i0.ɵɵelementEnd()();
126
132
  } }
127
- function ComponentFeedbackPanelComponent_Conditional_18_Conditional_27_Template(rf, ctx) { if (rf & 1) {
128
- i0.ɵɵelementStart(0, "div", 42);
129
- i0.ɵɵelement(1, "i", 47);
133
+ function ComponentFeedbackPanelComponent_Conditional_18_Conditional_26_Template(rf, ctx) { if (rf & 1) {
134
+ i0.ɵɵelementStart(0, "div", 41);
135
+ i0.ɵɵelement(1, "i", 50);
130
136
  i0.ɵɵelementStart(2, "span");
131
137
  i0.ɵɵtext(3);
132
138
  i0.ɵɵelementEnd()();
@@ -142,32 +148,33 @@ function ComponentFeedbackPanelComponent_Conditional_18_Template(rf, ctx) { if (
142
148
  i0.ɵɵelementStart(3, "span");
143
149
  i0.ɵɵtext(4);
144
150
  i0.ɵɵelementEnd()();
145
- i0.ɵɵconditionalCreate(5, ComponentFeedbackPanelComponent_Conditional_18_Conditional_5_Template, 2, 1, "p", 27);
151
+ i0.ɵɵconditionalCreate(5, ComponentFeedbackPanelComponent_Conditional_18_Conditional_5_Template, 1, 1, "mj-markdown", 27);
146
152
  i0.ɵɵelementStart(6, "div", 28)(7, "label", 29);
147
153
  i0.ɵɵtext(8, "Your Rating");
148
154
  i0.ɵɵelementEnd();
149
155
  i0.ɵɵelementStart(9, "div", 30);
150
- i0.ɵɵrepeaterCreate(10, ComponentFeedbackPanelComponent_Conditional_18_For_11_Template, 1, 6, "i", 31, i0.ɵɵrepeaterTrackByIdentity);
156
+ i0.ɵɵlistener("mouseleave", function ComponentFeedbackPanelComponent_Conditional_18_Template_div_mouseleave_9_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ClearHoverRating()); });
157
+ i0.ɵɵrepeaterCreate(10, ComponentFeedbackPanelComponent_Conditional_18_For_11_Template, 6, 1, "span", 31, i0.ɵɵrepeaterTrackByIdentity);
151
158
  i0.ɵɵelementEnd();
152
- i0.ɵɵconditionalCreate(12, ComponentFeedbackPanelComponent_Conditional_18_Conditional_12_Template, 2, 1, "span", 32)(13, ComponentFeedbackPanelComponent_Conditional_18_Conditional_13_Template, 2, 0, "span", 33);
159
+ i0.ɵɵconditionalCreate(12, ComponentFeedbackPanelComponent_Conditional_18_Conditional_12_Template, 2, 0, "span", 32);
153
160
  i0.ɵɵelementEnd();
154
- i0.ɵɵelementStart(14, "div", 34)(15, "label", 35);
155
- i0.ɵɵtext(16, " Comments ");
156
- i0.ɵɵelementStart(17, "span", 36);
157
- i0.ɵɵtext(18, "(optional)");
161
+ i0.ɵɵelementStart(13, "div", 33)(14, "label", 34);
162
+ i0.ɵɵtext(15, " Comments ");
163
+ i0.ɵɵelementStart(16, "span", 35);
164
+ i0.ɵɵtext(17, "(optional)");
158
165
  i0.ɵɵelementEnd()();
159
- i0.ɵɵelementStart(19, "textarea", 37);
160
- i0.ɵɵtwoWayListener("ngModelChange", function ComponentFeedbackPanelComponent_Conditional_18_Template_textarea_ngModelChange_19_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.FeedbackComments, $event) || (ctx_r2.FeedbackComments = $event); return i0.ɵɵresetView($event); });
161
- i0.ɵɵtext(20, " ");
166
+ i0.ɵɵelementStart(18, "textarea", 36);
167
+ i0.ɵɵtwoWayListener("ngModelChange", function ComponentFeedbackPanelComponent_Conditional_18_Template_textarea_ngModelChange_18_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.FeedbackComments, $event) || (ctx_r2.FeedbackComments = $event); return i0.ɵɵresetView($event); });
168
+ i0.ɵɵtext(19, " ");
162
169
  i0.ɵɵelementEnd();
163
- i0.ɵɵconditionalCreate(21, ComponentFeedbackPanelComponent_Conditional_18_Conditional_21_Template, 2, 1, "span", 38);
170
+ i0.ɵɵconditionalCreate(20, ComponentFeedbackPanelComponent_Conditional_18_Conditional_20_Template, 2, 1, "span", 37);
164
171
  i0.ɵɵelementEnd();
165
- i0.ɵɵelementStart(22, "div", 39)(23, "button", 40);
166
- i0.ɵɵlistener("click", function ComponentFeedbackPanelComponent_Conditional_18_Template_button_click_23_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SubmitFeedback()); });
167
- i0.ɵɵconditionalCreate(24, ComponentFeedbackPanelComponent_Conditional_18_Conditional_24_Template, 3, 0)(25, ComponentFeedbackPanelComponent_Conditional_18_Conditional_25_Template, 3, 0);
172
+ i0.ɵɵelementStart(21, "div", 38)(22, "button", 39);
173
+ i0.ɵɵlistener("click", function ComponentFeedbackPanelComponent_Conditional_18_Template_button_click_22_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SubmitFeedback()); });
174
+ i0.ɵɵconditionalCreate(23, ComponentFeedbackPanelComponent_Conditional_18_Conditional_23_Template, 3, 0)(24, ComponentFeedbackPanelComponent_Conditional_18_Conditional_24_Template, 3, 0);
168
175
  i0.ɵɵelementEnd()();
169
- i0.ɵɵconditionalCreate(26, ComponentFeedbackPanelComponent_Conditional_18_Conditional_26_Template, 4, 0, "div", 41);
170
- i0.ɵɵconditionalCreate(27, ComponentFeedbackPanelComponent_Conditional_18_Conditional_27_Template, 4, 1, "div", 42);
176
+ i0.ɵɵconditionalCreate(25, ComponentFeedbackPanelComponent_Conditional_18_Conditional_25_Template, 4, 0, "div", 40);
177
+ i0.ɵɵconditionalCreate(26, ComponentFeedbackPanelComponent_Conditional_18_Conditional_26_Template, 4, 1, "div", 41);
171
178
  i0.ɵɵelementEnd();
172
179
  } if (rf & 2) {
173
180
  const ctx_r2 = i0.ɵɵnextContext();
@@ -178,23 +185,23 @@ function ComponentFeedbackPanelComponent_Conditional_18_Template(rf, ctx) { if (
178
185
  i0.ɵɵadvance(5);
179
186
  i0.ɵɵrepeater(i0.ɵɵpureFunction0(9, _c0));
180
187
  i0.ɵɵadvance(2);
181
- i0.ɵɵconditional(ctx_r2.StarRating > 0 ? 12 : 13);
182
- i0.ɵɵadvance(7);
188
+ i0.ɵɵconditional(ctx_r2.StarRating === 0 ? 12 : -1);
189
+ i0.ɵɵadvance(6);
183
190
  i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FeedbackComments);
184
191
  i0.ɵɵadvance(2);
185
- i0.ɵɵconditional(ctx_r2.FeedbackComments.length > 0 ? 21 : -1);
192
+ i0.ɵɵconditional(ctx_r2.FeedbackComments.length > 0 ? 20 : -1);
186
193
  i0.ɵɵadvance(2);
187
194
  i0.ɵɵproperty("disabled", !ctx_r2.CanSubmit());
188
195
  i0.ɵɵadvance();
189
- i0.ɵɵconditional(ctx_r2.IsSubmitting ? 24 : 25);
196
+ i0.ɵɵconditional(ctx_r2.IsSubmitting ? 23 : 24);
190
197
  i0.ɵɵadvance(2);
191
- i0.ɵɵconditional(ctx_r2.SubmitSuccess ? 26 : -1);
198
+ i0.ɵɵconditional(ctx_r2.SubmitSuccess ? 25 : -1);
192
199
  i0.ɵɵadvance();
193
- i0.ɵɵconditional(ctx_r2.SubmitError ? 27 : -1);
200
+ i0.ɵɵconditional(ctx_r2.SubmitError ? 26 : -1);
194
201
  } }
195
202
  function ComponentFeedbackPanelComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
196
203
  i0.ɵɵelementStart(0, "div", 15);
197
- i0.ɵɵelement(1, "i", 48);
204
+ i0.ɵɵelement(1, "i", 51);
198
205
  i0.ɵɵelementStart(2, "p");
199
206
  i0.ɵɵtext(3, "Select a component from the tree to provide feedback");
200
207
  i0.ɵɵelementEnd()();
@@ -271,12 +278,12 @@ export class ComponentFeedbackPanelComponent {
271
278
  GetIndentation(depth) {
272
279
  return `${depth * 20}px`;
273
280
  }
274
- // --- Star Rating ---
275
- SetRating(stars) {
276
- this.StarRating = stars;
281
+ // --- Star Rating (supports half-star increments) ---
282
+ SetRating(value) {
283
+ this.StarRating = value;
277
284
  }
278
- SetHoverRating(stars) {
279
- this.HoverRating = stars;
285
+ SetHoverRating(value) {
286
+ this.HoverRating = value;
280
287
  }
281
288
  ClearHoverRating() {
282
289
  this.HoverRating = 0;
@@ -284,6 +291,15 @@ export class ComponentFeedbackPanelComponent {
284
291
  GetDisplayRating() {
285
292
  return this.HoverRating || this.StarRating;
286
293
  }
294
+ /** Returns 'full' | 'half' | 'empty' for the given 1-based star index */
295
+ GetStarState(index) {
296
+ const rating = this.GetDisplayRating();
297
+ if (index <= rating)
298
+ return 'full';
299
+ if (index - 0.5 <= rating)
300
+ return 'half';
301
+ return 'empty';
302
+ }
287
303
  IsStarFilled(index) {
288
304
  return index <= this.GetDisplayRating();
289
305
  }
@@ -520,7 +536,7 @@ export class ComponentFeedbackPanelComponent {
520
536
  this.ClearHighlight();
521
537
  }
522
538
  static ɵfac = function ComponentFeedbackPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ComponentFeedbackPanelComponent)(); };
523
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ComponentFeedbackPanelComponent, selectors: [["mj-component-feedback-panel"]], inputs: { ComponentSpec: "ComponentSpec", ReactContainerElement: "ReactContainerElement", ConversationId: "ConversationId", ConversationDetailId: "ConversationDetailId" }, outputs: { Closed: "Closed" }, decls: 20, vars: 2, consts: [[1, "feedback-panel-overlay", 3, "click"], [1, "feedback-panel", 3, "click"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-comment-dots"], [1, "close-button", 3, "click"], [1, "fa-solid", "fa-times"], [1, "panel-content"], [1, "tree-section"], [1, "section-header"], [1, "fa-solid", "fa-sitemap"], [1, "component-tree"], [1, "empty-state"], [1, "feedback-section"], [1, "selected-component-info"], [1, "no-selection-message"], [1, "tree-item", 3, "selected", "padding-left"], [1, "tree-item", 3, "click", "mouseenter", "mouseleave"], [1, "tree-toggle", "fa-solid", 3, "fa-chevron-right", "fa-chevron-down"], [1, "tree-spacer"], [1, "fa-solid", "fa-cube", "component-icon"], [1, "component-info"], [1, "component-name"], [1, "component-badge", "registry"], [1, "tree-toggle", "fa-solid", 3, "click"], [1, "fa-solid", "fa-info-circle"], [1, "fa-solid", "fa-star"], [1, "component-description"], [1, "star-rating-container"], [1, "rating-label"], [1, "star-rating"], [1, "star", 3, "fa-solid", "fa-regular", "fa-star"], [1, "rating-text"], [1, "rating-text", "placeholder"], [1, "comment-container"], [1, "comment-label"], [1, "optional-label"], ["placeholder", "Share your thoughts about this component...", "rows", "4", "maxlength", "1000", 1, "comment-input", 3, "ngModelChange", "ngModel"], [1, "char-count"], [1, "submit-container"], [1, "submit-button", 3, "click", "disabled"], [1, "message", "success-message"], [1, "message", "error-message"], [1, "star", 3, "click", "mouseenter", "mouseleave"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-paper-plane"], [1, "fa-solid", "fa-check-circle"], [1, "fa-solid", "fa-exclamation-circle"], [1, "fa-solid", "fa-hand-pointer"]], template: function ComponentFeedbackPanelComponent_Template(rf, ctx) { if (rf & 1) {
539
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ComponentFeedbackPanelComponent, selectors: [["mj-component-feedback-panel"]], inputs: { ComponentSpec: "ComponentSpec", ReactContainerElement: "ReactContainerElement", ConversationId: "ConversationId", ConversationDetailId: "ConversationDetailId" }, outputs: { Closed: "Closed" }, decls: 20, vars: 2, consts: [[1, "feedback-panel-overlay", 3, "click"], [1, "feedback-panel", 3, "click"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-magnifying-glass"], [1, "close-button", 3, "click"], [1, "fa-solid", "fa-times"], [1, "panel-content"], [1, "tree-section"], [1, "section-header"], [1, "fa-solid", "fa-sitemap"], [1, "component-tree"], [1, "empty-state"], [1, "feedback-section"], [1, "selected-component-info"], [1, "no-selection-message"], [1, "tree-item", 3, "selected", "padding-left"], [1, "tree-item", 3, "click", "mouseenter", "mouseleave"], [1, "tree-toggle", "fa-solid", 3, "fa-chevron-right", "fa-chevron-down"], [1, "tree-spacer"], [1, "fa-solid", "fa-cube", "component-icon"], [1, "component-info"], [1, "component-name"], [1, "component-badge", "registry"], [1, "tree-toggle", "fa-solid", 3, "click"], [1, "fa-solid", "fa-info-circle"], [1, "fa-solid", "fa-star"], [1, "component-description", 3, "data"], [1, "star-rating-container"], [1, "rating-label"], [1, "star-rating", 3, "mouseleave"], [1, "star-wrapper"], [1, "rating-text", "placeholder"], [1, "comment-container"], [1, "comment-label"], [1, "optional-label"], ["placeholder", "Share your thoughts about this component...", "rows", "4", "maxlength", "1000", 1, "comment-input", 3, "ngModelChange", "ngModel"], [1, "char-count"], [1, "submit-container"], [1, "submit-button", 3, "click", "disabled"], [1, "message", "success-message"], [1, "message", "error-message"], [1, "star-zone", "star-zone-left", 3, "click", "mouseenter"], [1, "star-zone", "star-zone-right", 3, "click", "mouseenter"], [1, "star", "fa-solid", "fa-star"], [1, "star", "fa-solid", "fa-star-half-stroke"], [1, "star", "fa-regular", "fa-star"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-paper-plane"], [1, "fa-solid", "fa-check-circle"], [1, "fa-solid", "fa-exclamation-circle"], [1, "fa-solid", "fa-hand-pointer"]], template: function ComponentFeedbackPanelComponent_Template(rf, ctx) { if (rf & 1) {
524
540
  i0.ɵɵelementStart(0, "div", 0);
525
541
  i0.ɵɵlistener("click", function ComponentFeedbackPanelComponent_Template_div_click_0_listener() { return ctx.ClosePanel(); });
526
542
  i0.ɵɵelementStart(1, "div", 1);
@@ -528,7 +544,7 @@ export class ComponentFeedbackPanelComponent {
528
544
  i0.ɵɵelementStart(2, "div", 2)(3, "div", 3);
529
545
  i0.ɵɵelement(4, "i", 4);
530
546
  i0.ɵɵelementStart(5, "span");
531
- i0.ɵɵtext(6, "Component Feedback");
547
+ i0.ɵɵtext(6, "Inspect & Rate");
532
548
  i0.ɵɵelementEnd()();
533
549
  i0.ɵɵelementStart(7, "button", 5);
534
550
  i0.ɵɵlistener("click", function ComponentFeedbackPanelComponent_Template_button_click_7_listener() { return ctx.ClosePanel(); });
@@ -542,18 +558,18 @@ export class ComponentFeedbackPanelComponent {
542
558
  i0.ɵɵconditionalCreate(15, ComponentFeedbackPanelComponent_Conditional_15_Template, 3, 0, "div", 11)(16, ComponentFeedbackPanelComponent_Conditional_16_Template, 4, 0, "div", 12);
543
559
  i0.ɵɵelementEnd();
544
560
  i0.ɵɵelementStart(17, "div", 13);
545
- i0.ɵɵconditionalCreate(18, ComponentFeedbackPanelComponent_Conditional_18_Template, 28, 10, "div", 14)(19, ComponentFeedbackPanelComponent_Conditional_19_Template, 4, 0, "div", 15);
561
+ i0.ɵɵconditionalCreate(18, ComponentFeedbackPanelComponent_Conditional_18_Template, 27, 10, "div", 14)(19, ComponentFeedbackPanelComponent_Conditional_19_Template, 4, 0, "div", 15);
546
562
  i0.ɵɵelementEnd()()()();
547
563
  } if (rf & 2) {
548
564
  i0.ɵɵadvance(15);
549
565
  i0.ɵɵconditional(ctx.ComponentSpec ? 15 : 16);
550
566
  i0.ɵɵadvance(3);
551
567
  i0.ɵɵconditional(ctx.SelectedSpec ? 18 : 19);
552
- } }, dependencies: [CommonModule, FormsModule, i1.DefaultValueAccessor, i1.NgControlStatus, i1.MaxLengthValidator, i1.NgModel], styles: ["\n\n.feedback-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--mj-bg-overlay, rgba(0, 0, 0, 0.4));\n z-index: 9999;\n display: flex;\n justify-content: flex-start;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.feedback-panel[_ngcontent-%COMP%] {\n width: 450px;\n height: 100%;\n background-color: var(--mj-bg-surface, #ffffff);\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideInFromLeft 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideInFromLeft {\n from { transform: translateX(-100%); }\n to { transform: translateX(0); }\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default, #e0e0e0);\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary, #333);\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary, #3B82F6);\n font-size: 20px;\n}\n\n.close-button[_ngcontent-%COMP%] {\n min-width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n background: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary, #555);\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-button[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-bg-surface-hover, #e0e0e0);\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 20px;\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary, #555);\n margin-bottom: 12px;\n padding-bottom: 8px;\n border-bottom: 2px solid var(--mj-brand-primary, #3B82F6);\n}\n\n.section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n\n\n.tree-section[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 8px;\n padding: 16px;\n}\n\n.component-tree[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.tree-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s ease;\n user-select: none;\n}\n\n.tree-item[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n}\n\n.tree-item.selected[_ngcontent-%COMP%] {\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n font-weight: 500;\n}\n\n.tree-item.selected[_ngcontent-%COMP%] .component-icon[_ngcontent-%COMP%], \n.tree-item.selected[_ngcontent-%COMP%] .tree-toggle[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse, #ffffff);\n}\n\n.tree-item.selected[_ngcontent-%COMP%] .component-badge[_ngcontent-%COMP%] {\n background-color: rgba(255, 255, 255, 0.2);\n color: var(--mj-text-inverse, #ffffff);\n border-color: rgba(255, 255, 255, 0.3);\n}\n\n.tree-toggle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted, #666);\n cursor: pointer;\n transition: transform 0.2s ease;\n width: 16px;\n text-align: center;\n}\n\n.tree-spacer[_ngcontent-%COMP%] {\n width: 16px;\n display: inline-block;\n}\n\n.component-icon[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n.component-info[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n overflow: hidden;\n}\n\n.component-name[_ngcontent-%COMP%] {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n}\n\n.component-badge[_ngcontent-%COMP%] {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 10px;\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n color: var(--mj-brand-primary, #3B82F6);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 30%, var(--mj-bg-surface, #ffffff));\n white-space: nowrap;\n font-weight: 500;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: var(--mj-text-disabled, #999);\n font-size: 14px;\n}\n\n\n\n.feedback-section[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface, #ffffff);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default, #e0e0e0);\n padding: 16px;\n min-height: 300px;\n}\n\n.selected-component-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.component-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n line-height: 1.5;\n margin: 0;\n padding: 12px;\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary, #3B82F6);\n}\n\n\n\n.star-rating-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.rating-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n}\n\n.star-rating[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.star[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #ffd700;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.star[_ngcontent-%COMP%]:hover {\n transform: scale(1.2);\n filter: brightness(1.1);\n}\n\n.star.fa-regular[_ngcontent-%COMP%] {\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.rating-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n margin-top: 4px;\n}\n\n.rating-text.placeholder[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled, #999);\n font-style: italic;\n}\n\n\n\n.comment-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.comment-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.optional-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: normal;\n color: var(--mj-text-disabled, #999);\n}\n\n.comment-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--mj-border-default, #d0d0d0);\n border-radius: 6px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n transition: border-color 0.2s ease;\n background-color: var(--mj-bg-surface, #ffffff);\n color: var(--mj-text-primary, #333);\n box-sizing: border-box;\n}\n\n.comment-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary, #3B82F6);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 15%, transparent);\n}\n\n.char-count[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 8px;\n right: 12px;\n font-size: 11px;\n color: var(--mj-text-disabled, #999);\n background-color: var(--mj-bg-surface, #ffffff);\n padding: 2px 4px;\n}\n\n\n\n.submit-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n}\n\n.submit-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n transition: background-color 0.2s ease;\n}\n\n.submit-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: var(--mj-brand-primary-hover, #2563EB);\n}\n\n.submit-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border-radius: 6px;\n font-size: 14px;\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.success-message[_ngcontent-%COMP%] {\n background-color: var(--mj-status-success-bg, #d4edda);\n color: var(--mj-status-success-text, #155724);\n border: 1px solid var(--mj-status-success-border, #c3e6cb);\n}\n\n.success-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success, #28a745);\n}\n\n.error-message[_ngcontent-%COMP%] {\n background-color: var(--mj-status-error-bg, #f8d7da);\n color: var(--mj-status-error-text, #721c24);\n border: 1px solid var(--mj-status-error-border, #f5c6cb);\n}\n\n.error-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error, #dc3545);\n}\n\n\n\n.no-selection-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-disabled, #999);\n text-align: center;\n}\n\n.no-selection-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.no-selection-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n}\n\n\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background-color: var(--mj-bg-surface-sunken, #f1f1f1);\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background-color: var(--mj-border-strong, #c0c0c0);\n border-radius: 4px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background-color: var(--mj-text-disabled, #a0a0a0);\n}"] });
568
+ } }, dependencies: [CommonModule, FormsModule, i1.DefaultValueAccessor, i1.NgControlStatus, i1.MaxLengthValidator, i1.NgModel, MarkdownModule, i2.MarkdownComponent], styles: ["\n\n.feedback-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--mj-bg-overlay, rgba(0, 0, 0, 0.4));\n z-index: 9999;\n display: flex;\n justify-content: flex-start;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.feedback-panel[_ngcontent-%COMP%] {\n width: 540px;\n height: 100%;\n background-color: var(--mj-bg-surface, #ffffff);\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideInFromLeft 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideInFromLeft {\n from { transform: translateX(-100%); }\n to { transform: translateX(0); }\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default, #e0e0e0);\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary, #333);\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary, #3B82F6);\n font-size: 20px;\n}\n\n.close-button[_ngcontent-%COMP%] {\n min-width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n background: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary, #555);\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-button[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-bg-surface-hover, #e0e0e0);\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 20px;\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary, #555);\n margin-bottom: 12px;\n padding-bottom: 8px;\n border-bottom: 2px solid var(--mj-brand-primary, #3B82F6);\n}\n\n.section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n\n\n.tree-section[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 8px;\n padding: 16px;\n}\n\n.component-tree[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.tree-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s ease;\n user-select: none;\n}\n\n.tree-item[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n}\n\n.tree-item.selected[_ngcontent-%COMP%] {\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n font-weight: 500;\n}\n\n.tree-item.selected[_ngcontent-%COMP%] .component-icon[_ngcontent-%COMP%], \n.tree-item.selected[_ngcontent-%COMP%] .tree-toggle[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse, #ffffff);\n}\n\n.tree-item.selected[_ngcontent-%COMP%] .component-badge[_ngcontent-%COMP%] {\n background-color: rgba(255, 255, 255, 0.2);\n color: var(--mj-text-inverse, #ffffff);\n border-color: rgba(255, 255, 255, 0.3);\n}\n\n.tree-toggle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted, #666);\n cursor: pointer;\n transition: transform 0.2s ease;\n width: 16px;\n text-align: center;\n}\n\n.tree-spacer[_ngcontent-%COMP%] {\n width: 16px;\n display: inline-block;\n}\n\n.component-icon[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n.component-info[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n overflow: hidden;\n}\n\n.component-name[_ngcontent-%COMP%] {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n}\n\n.component-badge[_ngcontent-%COMP%] {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 10px;\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n color: var(--mj-brand-primary, #3B82F6);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 30%, var(--mj-bg-surface, #ffffff));\n white-space: nowrap;\n font-weight: 500;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: var(--mj-text-disabled, #999);\n font-size: 14px;\n}\n\n\n\n.feedback-section[_ngcontent-%COMP%] {\n background-color: var(--mj-bg-surface, #ffffff);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default, #e0e0e0);\n padding: 16px;\n min-height: 300px;\n}\n\n.selected-component-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.component-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n line-height: 1.5;\n margin: 0;\n padding: 12px;\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary, #3B82F6);\n}\n\n\n\n.star-rating-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.rating-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n}\n\n.star-rating[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.star-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: inline-block;\n cursor: pointer;\n}\n\n.star-wrapper[_ngcontent-%COMP%]:hover .star[_ngcontent-%COMP%] {\n transform: scale(1.2);\n filter: brightness(1.1);\n}\n\n.star-zone[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n height: 100%;\n width: 50%;\n z-index: 1;\n}\n\n.star-zone-left[_ngcontent-%COMP%] {\n left: 0;\n}\n\n.star-zone-right[_ngcontent-%COMP%] {\n right: 0;\n}\n\n.star[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #ffd700;\n transition: all 0.2s ease;\n pointer-events: none;\n}\n\n.star.fa-regular[_ngcontent-%COMP%] {\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.rating-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n margin-top: 4px;\n}\n\n.rating-text.placeholder[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled, #999);\n font-style: italic;\n}\n\n\n\n.comment-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.comment-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.optional-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: normal;\n color: var(--mj-text-disabled, #999);\n}\n\n.comment-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--mj-border-default, #d0d0d0);\n border-radius: 6px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n transition: border-color 0.2s ease;\n background-color: var(--mj-bg-surface, #ffffff);\n color: var(--mj-text-primary, #333);\n box-sizing: border-box;\n}\n\n.comment-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary, #3B82F6);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 15%, transparent);\n}\n\n.char-count[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 8px;\n right: 12px;\n font-size: 11px;\n color: var(--mj-text-disabled, #999);\n background-color: var(--mj-bg-surface, #ffffff);\n padding: 2px 4px;\n}\n\n\n\n.submit-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n}\n\n.submit-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n transition: background-color 0.2s ease;\n}\n\n.submit-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: var(--mj-brand-primary-hover, #2563EB);\n}\n\n.submit-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border-radius: 6px;\n font-size: 14px;\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.success-message[_ngcontent-%COMP%] {\n background-color: var(--mj-status-success-bg, #d4edda);\n color: var(--mj-status-success-text, #155724);\n border: 1px solid var(--mj-status-success-border, #c3e6cb);\n}\n\n.success-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-success, #28a745);\n}\n\n.error-message[_ngcontent-%COMP%] {\n background-color: var(--mj-status-error-bg, #f8d7da);\n color: var(--mj-status-error-text, #721c24);\n border: 1px solid var(--mj-status-error-border, #f5c6cb);\n}\n\n.error-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error, #dc3545);\n}\n\n\n\n.no-selection-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-disabled, #999);\n text-align: center;\n}\n\n.no-selection-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.no-selection-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n}\n\n\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background-color: var(--mj-bg-surface-sunken, #f1f1f1);\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background-color: var(--mj-border-strong, #c0c0c0);\n border-radius: 4px;\n}\n\n.panel-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background-color: var(--mj-text-disabled, #a0a0a0);\n}"] });
553
569
  }
554
570
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ComponentFeedbackPanelComponent, [{
555
571
  type: Component,
556
- args: [{ selector: 'mj-component-feedback-panel', standalone: true, imports: [CommonModule, FormsModule], template: "<div class=\"feedback-panel-overlay\" (click)=\"ClosePanel()\">\n <div class=\"feedback-panel\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-comment-dots\"></i>\n <span>Component Feedback</span>\n </div>\n <button class=\"close-button\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"panel-content\">\n <!-- Component Tree Section -->\n <div class=\"tree-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <span>Select Component</span>\n </div>\n\n @if (ComponentSpec) {\n <div class=\"component-tree\">\n @for (item of GetTreeItems(); track item.spec.name) {\n <div\n class=\"tree-item\"\n [class.selected]=\"IsSelected(item.spec)\"\n [style.padding-left]=\"GetIndentation(item.depth)\"\n (click)=\"SelectComponent(item.spec)\"\n (mouseenter)=\"HoverTreeItem(item.spec)\"\n (mouseleave)=\"ClearTreeItemHover()\">\n\n @if (item.hasChildren) {\n <i\n class=\"tree-toggle fa-solid\"\n [class.fa-chevron-right]=\"!IsNodeExpanded(item.spec)\"\n [class.fa-chevron-down]=\"IsNodeExpanded(item.spec)\"\n (click)=\"ToggleNode(item.spec, $event)\">\n </i>\n } @else {\n <span class=\"tree-spacer\"></span>\n }\n\n <i class=\"fa-solid fa-cube component-icon\"></i>\n\n <div class=\"component-info\">\n <span class=\"component-name\">{{ item.spec.title || item.spec.name }}</span>\n @if (item.spec.location === 'registry') {\n <span class=\"component-badge registry\">Registry</span>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No component hierarchy available</span>\n </div>\n }\n </div>\n\n <!-- Feedback Form Section -->\n <div class=\"feedback-section\">\n @if (SelectedSpec) {\n <div class=\"selected-component-info\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-star\"></i>\n <span>Rate: {{ SelectedSpec.title || SelectedSpec.name }}</span>\n </div>\n\n @if (SelectedSpec.description) {\n <p class=\"component-description\">{{ SelectedSpec.description }}</p>\n }\n\n <!-- Star Rating -->\n <div class=\"star-rating-container\">\n <label class=\"rating-label\">Your Rating</label>\n <div class=\"star-rating\">\n @for (star of [1, 2, 3, 4, 5]; track star) {\n <i\n class=\"star\"\n [class.fa-solid]=\"IsStarFilled(star)\"\n [class.fa-regular]=\"!IsStarFilled(star)\"\n [class.fa-star]=\"true\"\n (click)=\"SetRating(star)\"\n (mouseenter)=\"SetHoverRating(star)\"\n (mouseleave)=\"ClearHoverRating()\">\n </i>\n }\n </div>\n @if (StarRating > 0) {\n <span class=\"rating-text\">{{ StarRating }} out of 5 stars</span>\n } @else {\n <span class=\"rating-text placeholder\">Click to rate</span>\n }\n </div>\n\n <!-- Comment Input -->\n <div class=\"comment-container\">\n <label class=\"comment-label\">\n Comments\n <span class=\"optional-label\">(optional)</span>\n </label>\n <textarea\n class=\"comment-input\"\n [(ngModel)]=\"FeedbackComments\"\n placeholder=\"Share your thoughts about this component...\"\n rows=\"4\"\n maxlength=\"1000\">\n </textarea>\n @if (FeedbackComments.length > 0) {\n <span class=\"char-count\">{{ FeedbackComments.length }}/1000</span>\n }\n </div>\n\n <!-- Submit Button -->\n <div class=\"submit-container\">\n <button\n class=\"submit-button\"\n [disabled]=\"!CanSubmit()\"\n (click)=\"SubmitFeedback()\">\n @if (IsSubmitting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Submitting...</span>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>Submit Feedback</span>\n }\n </button>\n </div>\n\n <!-- Success/Error Messages -->\n @if (SubmitSuccess) {\n <div class=\"message success-message\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>Feedback submitted successfully!</span>\n </div>\n }\n @if (SubmitError) {\n <div class=\"message error-message\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ SubmitError }}</span>\n </div>\n }\n </div>\n } @else {\n <div class=\"no-selection-message\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n <p>Select a component from the tree to provide feedback</p>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n", styles: ["/* Overlay */\n.feedback-panel-overlay {\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--mj-bg-overlay, rgba(0, 0, 0, 0.4));\n z-index: 9999;\n display: flex;\n justify-content: flex-start;\n animation: fadeIn 0.2s ease-in-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Panel Container */\n.feedback-panel {\n width: 450px;\n height: 100%;\n background-color: var(--mj-bg-surface, #ffffff);\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n display: flex;\n flex-direction: column;\n animation: slideInFromLeft 0.3s ease-out;\n}\n\n@keyframes slideInFromLeft {\n from { transform: translateX(-100%); }\n to { transform: translateX(0); }\n}\n\n/* Header */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default, #e0e0e0);\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary, #333);\n}\n\n.panel-title i {\n color: var(--mj-brand-primary, #3B82F6);\n font-size: 20px;\n}\n\n.close-button {\n min-width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n background: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary, #555);\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-button:hover {\n background-color: var(--mj-bg-surface-hover, #e0e0e0);\n}\n\n/* Content */\n.panel-content {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 20px;\n}\n\n/* Section Headers */\n.section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary, #555);\n margin-bottom: 12px;\n padding-bottom: 8px;\n border-bottom: 2px solid var(--mj-brand-primary, #3B82F6);\n}\n\n.section-header i {\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n/* Component Tree */\n.tree-section {\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 8px;\n padding: 16px;\n}\n\n.component-tree {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.tree-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s ease;\n user-select: none;\n}\n\n.tree-item:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n}\n\n.tree-item.selected {\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n font-weight: 500;\n}\n\n.tree-item.selected .component-icon,\n.tree-item.selected .tree-toggle {\n color: var(--mj-text-inverse, #ffffff);\n}\n\n.tree-item.selected .component-badge {\n background-color: rgba(255, 255, 255, 0.2);\n color: var(--mj-text-inverse, #ffffff);\n border-color: rgba(255, 255, 255, 0.3);\n}\n\n.tree-toggle {\n font-size: 12px;\n color: var(--mj-text-muted, #666);\n cursor: pointer;\n transition: transform 0.2s ease;\n width: 16px;\n text-align: center;\n}\n\n.tree-spacer {\n width: 16px;\n display: inline-block;\n}\n\n.component-icon {\n font-size: 16px;\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n.component-info {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n overflow: hidden;\n}\n\n.component-name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n}\n\n.component-badge {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 10px;\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n color: var(--mj-brand-primary, #3B82F6);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 30%, var(--mj-bg-surface, #ffffff));\n white-space: nowrap;\n font-weight: 500;\n}\n\n.empty-state {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: var(--mj-text-disabled, #999);\n font-size: 14px;\n}\n\n/* Feedback Form Section */\n.feedback-section {\n background-color: var(--mj-bg-surface, #ffffff);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default, #e0e0e0);\n padding: 16px;\n min-height: 300px;\n}\n\n.selected-component-info {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.component-description {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n line-height: 1.5;\n margin: 0;\n padding: 12px;\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary, #3B82F6);\n}\n\n/* Star Rating */\n.star-rating-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.rating-label {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n}\n\n.star-rating {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.star {\n font-size: 32px;\n color: #ffd700;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.star:hover {\n transform: scale(1.2);\n filter: brightness(1.1);\n}\n\n.star.fa-regular {\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.rating-text {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n margin-top: 4px;\n}\n\n.rating-text.placeholder {\n color: var(--mj-text-disabled, #999);\n font-style: italic;\n}\n\n/* Comment Input */\n.comment-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.comment-label {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.optional-label {\n font-size: 12px;\n font-weight: normal;\n color: var(--mj-text-disabled, #999);\n}\n\n.comment-input {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--mj-border-default, #d0d0d0);\n border-radius: 6px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n transition: border-color 0.2s ease;\n background-color: var(--mj-bg-surface, #ffffff);\n color: var(--mj-text-primary, #333);\n box-sizing: border-box;\n}\n\n.comment-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary, #3B82F6);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 15%, transparent);\n}\n\n.char-count {\n position: absolute;\n bottom: 8px;\n right: 12px;\n font-size: 11px;\n color: var(--mj-text-disabled, #999);\n background-color: var(--mj-bg-surface, #ffffff);\n padding: 2px 4px;\n}\n\n/* Submit Button */\n.submit-container {\n display: flex;\n justify-content: flex-start;\n}\n\n.submit-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n transition: background-color 0.2s ease;\n}\n\n.submit-button:hover:not(:disabled) {\n background-color: var(--mj-brand-primary-hover, #2563EB);\n}\n\n.submit-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Messages */\n.message {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border-radius: 6px;\n font-size: 14px;\n animation: slideDown 0.3s ease-out;\n}\n\n@keyframes slideDown {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.success-message {\n background-color: var(--mj-status-success-bg, #d4edda);\n color: var(--mj-status-success-text, #155724);\n border: 1px solid var(--mj-status-success-border, #c3e6cb);\n}\n\n.success-message i {\n color: var(--mj-status-success, #28a745);\n}\n\n.error-message {\n background-color: var(--mj-status-error-bg, #f8d7da);\n color: var(--mj-status-error-text, #721c24);\n border: 1px solid var(--mj-status-error-border, #f5c6cb);\n}\n\n.error-message i {\n color: var(--mj-status-error, #dc3545);\n}\n\n/* No Selection Message */\n.no-selection-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-disabled, #999);\n text-align: center;\n}\n\n.no-selection-message i {\n font-size: 48px;\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.no-selection-message p {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n}\n\n/* Scrollbar Styling */\n.panel-content::-webkit-scrollbar {\n width: 8px;\n}\n\n.panel-content::-webkit-scrollbar-track {\n background-color: var(--mj-bg-surface-sunken, #f1f1f1);\n}\n\n.panel-content::-webkit-scrollbar-thumb {\n background-color: var(--mj-border-strong, #c0c0c0);\n border-radius: 4px;\n}\n\n.panel-content::-webkit-scrollbar-thumb:hover {\n background-color: var(--mj-text-disabled, #a0a0a0);\n}\n"] }]
572
+ args: [{ selector: 'mj-component-feedback-panel', standalone: true, imports: [CommonModule, FormsModule, MarkdownModule], template: "<div class=\"feedback-panel-overlay\" (click)=\"ClosePanel()\">\n <div class=\"feedback-panel\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span>Inspect & Rate</span>\n </div>\n <button class=\"close-button\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"panel-content\">\n <!-- Component Tree Section -->\n <div class=\"tree-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <span>Select Component</span>\n </div>\n\n @if (ComponentSpec) {\n <div class=\"component-tree\">\n @for (item of GetTreeItems(); track item.spec.name) {\n <div\n class=\"tree-item\"\n [class.selected]=\"IsSelected(item.spec)\"\n [style.padding-left]=\"GetIndentation(item.depth)\"\n (click)=\"SelectComponent(item.spec)\"\n (mouseenter)=\"HoverTreeItem(item.spec)\"\n (mouseleave)=\"ClearTreeItemHover()\">\n\n @if (item.hasChildren) {\n <i\n class=\"tree-toggle fa-solid\"\n [class.fa-chevron-right]=\"!IsNodeExpanded(item.spec)\"\n [class.fa-chevron-down]=\"IsNodeExpanded(item.spec)\"\n (click)=\"ToggleNode(item.spec, $event)\">\n </i>\n } @else {\n <span class=\"tree-spacer\"></span>\n }\n\n <i class=\"fa-solid fa-cube component-icon\"></i>\n\n <div class=\"component-info\">\n <span class=\"component-name\">{{ item.spec.title || item.spec.name }}</span>\n @if (item.spec.location === 'registry') {\n <span class=\"component-badge registry\">Registry</span>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No component hierarchy available</span>\n </div>\n }\n </div>\n\n <!-- Feedback Form Section -->\n <div class=\"feedback-section\">\n @if (SelectedSpec) {\n <div class=\"selected-component-info\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-star\"></i>\n <span>Rate: {{ SelectedSpec.title || SelectedSpec.name }}</span>\n </div>\n\n @if (SelectedSpec.description) {\n <mj-markdown [data]=\"SelectedSpec.description\" class=\"component-description\"></mj-markdown>\n }\n\n <!-- Star Rating (half-star support) -->\n <div class=\"star-rating-container\">\n <label class=\"rating-label\">Your Rating</label>\n <div class=\"star-rating\" (mouseleave)=\"ClearHoverRating()\">\n @for (star of [1, 2, 3, 4, 5]; track star) {\n <span class=\"star-wrapper\">\n <!-- Left half (sets X.5 for previous half) -->\n <span class=\"star-zone star-zone-left\"\n (click)=\"SetRating(star - 0.5)\"\n (mouseenter)=\"SetHoverRating(star - 0.5)\"></span>\n <!-- Right half (sets full star) -->\n <span class=\"star-zone star-zone-right\"\n (click)=\"SetRating(star)\"\n (mouseenter)=\"SetHoverRating(star)\"></span>\n <!-- Star icon -->\n @switch (GetStarState(star)) {\n @case ('full') {\n <i class=\"star fa-solid fa-star\"></i>\n }\n @case ('half') {\n <i class=\"star fa-solid fa-star-half-stroke\"></i>\n }\n @default {\n <i class=\"star fa-regular fa-star\"></i>\n }\n }\n </span>\n }\n </div>\n @if (StarRating === 0) {\n <span class=\"rating-text placeholder\">Click to rate</span>\n }\n </div>\n\n <!-- Comment Input -->\n <div class=\"comment-container\">\n <label class=\"comment-label\">\n Comments\n <span class=\"optional-label\">(optional)</span>\n </label>\n <textarea\n class=\"comment-input\"\n [(ngModel)]=\"FeedbackComments\"\n placeholder=\"Share your thoughts about this component...\"\n rows=\"4\"\n maxlength=\"1000\">\n </textarea>\n @if (FeedbackComments.length > 0) {\n <span class=\"char-count\">{{ FeedbackComments.length }}/1000</span>\n }\n </div>\n\n <!-- Submit Button -->\n <div class=\"submit-container\">\n <button\n class=\"submit-button\"\n [disabled]=\"!CanSubmit()\"\n (click)=\"SubmitFeedback()\">\n @if (IsSubmitting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Submitting...</span>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>Submit Feedback</span>\n }\n </button>\n </div>\n\n <!-- Success/Error Messages -->\n @if (SubmitSuccess) {\n <div class=\"message success-message\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>Feedback submitted successfully!</span>\n </div>\n }\n @if (SubmitError) {\n <div class=\"message error-message\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ SubmitError }}</span>\n </div>\n }\n </div>\n } @else {\n <div class=\"no-selection-message\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n <p>Select a component from the tree to provide feedback</p>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n", styles: ["/* Overlay */\n.feedback-panel-overlay {\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--mj-bg-overlay, rgba(0, 0, 0, 0.4));\n z-index: 9999;\n display: flex;\n justify-content: flex-start;\n animation: fadeIn 0.2s ease-in-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Panel Container */\n.feedback-panel {\n width: 540px;\n height: 100%;\n background-color: var(--mj-bg-surface, #ffffff);\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n display: flex;\n flex-direction: column;\n animation: slideInFromLeft 0.3s ease-out;\n}\n\n@keyframes slideInFromLeft {\n from { transform: translateX(-100%); }\n to { transform: translateX(0); }\n}\n\n/* Header */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default, #e0e0e0);\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary, #333);\n}\n\n.panel-title i {\n color: var(--mj-brand-primary, #3B82F6);\n font-size: 20px;\n}\n\n.close-button {\n min-width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n background: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary, #555);\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-button:hover {\n background-color: var(--mj-bg-surface-hover, #e0e0e0);\n}\n\n/* Content */\n.panel-content {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 20px;\n}\n\n/* Section Headers */\n.section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary, #555);\n margin-bottom: 12px;\n padding-bottom: 8px;\n border-bottom: 2px solid var(--mj-brand-primary, #3B82F6);\n}\n\n.section-header i {\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n/* Component Tree */\n.tree-section {\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 8px;\n padding: 16px;\n}\n\n.component-tree {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.tree-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s ease;\n user-select: none;\n}\n\n.tree-item:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n}\n\n.tree-item.selected {\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n font-weight: 500;\n}\n\n.tree-item.selected .component-icon,\n.tree-item.selected .tree-toggle {\n color: var(--mj-text-inverse, #ffffff);\n}\n\n.tree-item.selected .component-badge {\n background-color: rgba(255, 255, 255, 0.2);\n color: var(--mj-text-inverse, #ffffff);\n border-color: rgba(255, 255, 255, 0.3);\n}\n\n.tree-toggle {\n font-size: 12px;\n color: var(--mj-text-muted, #666);\n cursor: pointer;\n transition: transform 0.2s ease;\n width: 16px;\n text-align: center;\n}\n\n.tree-spacer {\n width: 16px;\n display: inline-block;\n}\n\n.component-icon {\n font-size: 16px;\n color: var(--mj-brand-primary, #3B82F6);\n}\n\n.component-info {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n overflow: hidden;\n}\n\n.component-name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n}\n\n.component-badge {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 10px;\n background-color: color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, var(--mj-bg-surface, #ffffff));\n color: var(--mj-brand-primary, #3B82F6);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 30%, var(--mj-bg-surface, #ffffff));\n white-space: nowrap;\n font-weight: 500;\n}\n\n.empty-state {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: var(--mj-text-disabled, #999);\n font-size: 14px;\n}\n\n/* Feedback Form Section */\n.feedback-section {\n background-color: var(--mj-bg-surface, #ffffff);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default, #e0e0e0);\n padding: 16px;\n min-height: 300px;\n}\n\n.selected-component-info {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.component-description {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n line-height: 1.5;\n margin: 0;\n padding: 12px;\n background-color: var(--mj-bg-surface-card, #f8f9fa);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary, #3B82F6);\n}\n\n/* Star Rating */\n.star-rating-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.rating-label {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n}\n\n.star-rating {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.star-wrapper {\n position: relative;\n display: inline-block;\n cursor: pointer;\n}\n\n.star-wrapper:hover .star {\n transform: scale(1.2);\n filter: brightness(1.1);\n}\n\n.star-zone {\n position: absolute;\n top: 0;\n height: 100%;\n width: 50%;\n z-index: 1;\n}\n\n.star-zone-left {\n left: 0;\n}\n\n.star-zone-right {\n right: 0;\n}\n\n.star {\n font-size: 32px;\n color: #ffd700;\n transition: all 0.2s ease;\n pointer-events: none;\n}\n\n.star.fa-regular {\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.rating-text {\n font-size: 13px;\n color: var(--mj-text-secondary, #666);\n margin-top: 4px;\n}\n\n.rating-text.placeholder {\n color: var(--mj-text-disabled, #999);\n font-style: italic;\n}\n\n/* Comment Input */\n.comment-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.comment-label {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary, #333);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.optional-label {\n font-size: 12px;\n font-weight: normal;\n color: var(--mj-text-disabled, #999);\n}\n\n.comment-input {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--mj-border-default, #d0d0d0);\n border-radius: 6px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n transition: border-color 0.2s ease;\n background-color: var(--mj-bg-surface, #ffffff);\n color: var(--mj-text-primary, #333);\n box-sizing: border-box;\n}\n\n.comment-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary, #3B82F6);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 15%, transparent);\n}\n\n.char-count {\n position: absolute;\n bottom: 8px;\n right: 12px;\n font-size: 11px;\n color: var(--mj-text-disabled, #999);\n background-color: var(--mj-bg-surface, #ffffff);\n padding: 2px 4px;\n}\n\n/* Submit Button */\n.submit-container {\n display: flex;\n justify-content: flex-start;\n}\n\n.submit-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background-color: var(--mj-brand-primary, #3B82F6);\n color: var(--mj-text-inverse, #ffffff);\n transition: background-color 0.2s ease;\n}\n\n.submit-button:hover:not(:disabled) {\n background-color: var(--mj-brand-primary-hover, #2563EB);\n}\n\n.submit-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Messages */\n.message {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border-radius: 6px;\n font-size: 14px;\n animation: slideDown 0.3s ease-out;\n}\n\n@keyframes slideDown {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.success-message {\n background-color: var(--mj-status-success-bg, #d4edda);\n color: var(--mj-status-success-text, #155724);\n border: 1px solid var(--mj-status-success-border, #c3e6cb);\n}\n\n.success-message i {\n color: var(--mj-status-success, #28a745);\n}\n\n.error-message {\n background-color: var(--mj-status-error-bg, #f8d7da);\n color: var(--mj-status-error-text, #721c24);\n border: 1px solid var(--mj-status-error-border, #f5c6cb);\n}\n\n.error-message i {\n color: var(--mj-status-error, #dc3545);\n}\n\n/* No Selection Message */\n.no-selection-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-disabled, #999);\n text-align: center;\n}\n\n.no-selection-message i {\n font-size: 48px;\n color: var(--mj-border-default, #d0d0d0);\n}\n\n.no-selection-message p {\n margin: 0;\n font-size: 14px;\n line-height: 1.5;\n}\n\n/* Scrollbar Styling */\n.panel-content::-webkit-scrollbar {\n width: 8px;\n}\n\n.panel-content::-webkit-scrollbar-track {\n background-color: var(--mj-bg-surface-sunken, #f1f1f1);\n}\n\n.panel-content::-webkit-scrollbar-thumb {\n background-color: var(--mj-border-strong, #c0c0c0);\n border-radius: 4px;\n}\n\n.panel-content::-webkit-scrollbar-thumb:hover {\n background-color: var(--mj-text-disabled, #a0a0a0);\n}\n"] }]
557
573
  }], null, { ComponentSpec: [{
558
574
  type: Input
559
575
  }], ReactContainerElement: [{
@@ -565,5 +581,5 @@ export class ComponentFeedbackPanelComponent {
565
581
  }], Closed: [{
566
582
  type: Output
567
583
  }] }); })();
568
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ComponentFeedbackPanelComponent, { className: "ComponentFeedbackPanelComponent", filePath: "src/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.ts", lineNumber: 28 }); })();
584
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ComponentFeedbackPanelComponent, { className: "ComponentFeedbackPanelComponent", filePath: "src/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.ts", lineNumber: 29 }); })();
569
585
  //# sourceMappingURL=component-feedback-panel.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"component-feedback-panel.component.js","sourceRoot":"","sources":["../../../../../src/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.ts","../../../../../src/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnDestroy, ChangeDetectorRef, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { Metadata } from '@memberjunction/core';\nimport { ComponentSpec } from '@memberjunction/interactive-component-types';\n\n/**\n * Flattened tree item for rendering the component hierarchy\n */\ninterface TreeItem {\n spec: ComponentSpec;\n depth: number;\n hasChildren: boolean;\n}\n\n/**\n * Component feedback panel that displays component hierarchy tree\n * and allows users to select components and provide star ratings with comments.\n * Registry-agnostic: works with any component registry (Skip, MJ Central, etc.)\n */\n@Component({\n selector: 'mj-component-feedback-panel',\n standalone: true,\n imports: [CommonModule, FormsModule],\n templateUrl: './component-feedback-panel.component.html',\n styleUrls: ['./component-feedback-panel.component.css']\n})\nexport class ComponentFeedbackPanelComponent implements OnDestroy {\n @Input() ComponentSpec: ComponentSpec | null = null;\n @Input() ReactContainerElement: HTMLElement | null = null;\n @Input() ConversationId: string | null = null;\n @Input() ConversationDetailId: string | null = null;\n\n @Output() Closed = new EventEmitter<void>();\n\n // Feedback form state\n public SelectedSpec: ComponentSpec | null = null;\n public StarRating = 0;\n public HoverRating = 0;\n public FeedbackComments = '';\n public IsSubmitting = false;\n public SubmitSuccess = false;\n public SubmitError = '';\n\n // Tree state\n public ExpandedNodes = new Set<string>();\n\n // Highlight overlays\n private highlightOverlay: HTMLElement | null = null;\n private hoverOverlay: HTMLElement | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private containerClickHandler: ((e: MouseEvent) => void) | null = null;\n\n private cdr = inject(ChangeDetectorRef);\n\n // --- Tree Methods ---\n\n GetTreeItems(): TreeItem[] {\n if (!this.ComponentSpec) return [];\n if (!this.ExpandedNodes.has(this.ComponentSpec.name)) {\n this.ExpandedNodes.add(this.ComponentSpec.name);\n }\n return this.buildTree(this.ComponentSpec, 0);\n }\n\n private buildTree(spec: ComponentSpec, depth: number): TreeItem[] {\n const items: TreeItem[] = [{\n spec,\n depth,\n hasChildren: !!(spec.dependencies && spec.dependencies.length > 0)\n }];\n if (this.ExpandedNodes.has(spec.name) && spec.dependencies) {\n for (const child of spec.dependencies) {\n items.push(...this.buildTree(child, depth + 1));\n }\n }\n return items;\n }\n\n ToggleNode(spec: ComponentSpec, event: MouseEvent): void {\n event.stopPropagation();\n if (this.ExpandedNodes.has(spec.name)) {\n this.ExpandedNodes.delete(spec.name);\n } else {\n this.ExpandedNodes.add(spec.name);\n }\n }\n\n IsNodeExpanded(spec: ComponentSpec): boolean {\n return this.ExpandedNodes.has(spec.name);\n }\n\n SelectComponent(spec: ComponentSpec): void {\n this.SelectedSpec = spec;\n this.ResetForm();\n this.HighlightComponent(spec.name);\n }\n\n IsSelected(spec: ComponentSpec): boolean {\n return this.SelectedSpec?.name === spec.name;\n }\n\n GetIndentation(depth: number): string {\n return `${depth * 20}px`;\n }\n\n // --- Star Rating ---\n\n SetRating(stars: number): void {\n this.StarRating = stars;\n }\n\n SetHoverRating(stars: number): void {\n this.HoverRating = stars;\n }\n\n ClearHoverRating(): void {\n this.HoverRating = 0;\n }\n\n GetDisplayRating(): number {\n return this.HoverRating || this.StarRating;\n }\n\n IsStarFilled(index: number): boolean {\n return index <= this.GetDisplayRating();\n }\n\n // --- Form ---\n\n ResetForm(): void {\n this.StarRating = 0;\n this.HoverRating = 0;\n this.FeedbackComments = '';\n this.SubmitSuccess = false;\n this.SubmitError = '';\n }\n\n CanSubmit(): boolean {\n return !!this.SelectedSpec && this.StarRating > 0 && !this.IsSubmitting;\n }\n\n async SubmitFeedback(): Promise<void> {\n if (!this.CanSubmit() || !this.SelectedSpec) return;\n\n this.IsSubmitting = true;\n this.SubmitError = '';\n this.SubmitSuccess = false;\n this.cdr.detectChanges();\n\n try {\n // Dynamic import to avoid adding graphql-dataprovider as a package dependency.\n // At runtime in the browser, Metadata.Provider is always a GraphQLDataProvider.\n const { GraphQLComponentRegistryClient } = await import('@memberjunction/graphql-dataprovider');\n const provider = Metadata.Provider;\n const client = new GraphQLComponentRegistryClient(provider as ConstructorParameters<typeof GraphQLComponentRegistryClient>[0]);\n\n const response = await client.SendComponentFeedback({\n componentName: this.SelectedSpec.name,\n componentNamespace: this.SelectedSpec.namespace || this.SelectedSpec.registry || '',\n componentVersion: this.SelectedSpec.version,\n registryName: this.SelectedSpec.registry,\n rating: this.StarRating * 20, // 0-5 -> 0-100\n comments: this.FeedbackComments.trim() || undefined,\n conversationID: this.ConversationId || undefined,\n conversationDetailID: this.ConversationDetailId || undefined\n });\n\n if (response.success) {\n this.SubmitSuccess = true;\n setTimeout(() => {\n this.ResetForm();\n this.cdr.detectChanges();\n }, 2000);\n } else {\n this.SubmitError = response.error || 'Failed to submit feedback.';\n }\n } catch (error) {\n this.SubmitError = 'Failed to submit feedback. Please try again.';\n console.error('Error submitting component feedback:', error);\n } finally {\n this.IsSubmitting = false;\n this.cdr.detectChanges();\n }\n }\n\n // --- Hover Highlight (light preview on tree hover) ---\n\n HoverTreeItem(spec: ComponentSpec): void {\n if (!this.ReactContainerElement || this.IsSelected(spec)) return;\n this.showHoverOverlay(spec.name);\n }\n\n ClearTreeItemHover(): void {\n this.removeHoverOverlay();\n }\n\n private showHoverOverlay(componentName: string): void {\n if (!this.ReactContainerElement) return;\n\n const targetEl = this.ReactContainerElement.querySelector(\n `[data-mj-component=\"${componentName}\"]`\n );\n if (!targetEl) {\n this.removeHoverOverlay();\n return;\n }\n\n this.ensureContainerPositioned();\n\n if (!this.hoverOverlay) {\n this.hoverOverlay = document.createElement('div');\n this.ReactContainerElement.appendChild(this.hoverOverlay);\n }\n\n this.positionOverlay(this.hoverOverlay, targetEl);\n this.hoverOverlay.style.border = '2px dashed var(--mj-brand-primary, #3B82F6)';\n this.hoverOverlay.style.background = 'color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 5%, transparent)';\n }\n\n private removeHoverOverlay(): void {\n if (this.hoverOverlay?.parentNode) {\n this.hoverOverlay.parentNode.removeChild(this.hoverOverlay);\n }\n this.hoverOverlay = null;\n }\n\n // --- Region Highlighting (solid selection) ---\n\n private HighlightComponent(componentName: string): void {\n if (!this.ReactContainerElement) {\n this.ClearHighlight();\n return;\n }\n\n const targetEl = this.ReactContainerElement.querySelector(\n `[data-mj-component=\"${componentName}\"]`\n );\n if (!targetEl) {\n this.ClearHighlight();\n return;\n }\n\n this.ensureContainerPositioned();\n\n if (!this.highlightOverlay) {\n this.highlightOverlay = document.createElement('div');\n this.ReactContainerElement.appendChild(this.highlightOverlay);\n }\n\n this.positionOverlay(this.highlightOverlay, targetEl);\n this.highlightOverlay.style.border = '2px solid var(--mj-brand-primary, #3B82F6)';\n this.highlightOverlay.style.background = 'color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, transparent)';\n\n // Watch for resize/layout changes\n this.resizeObserver?.disconnect();\n this.resizeObserver = new ResizeObserver(() => {\n if (this.highlightOverlay) {\n this.positionOverlay(this.highlightOverlay, targetEl);\n }\n });\n this.resizeObserver.observe(targetEl);\n this.resizeObserver.observe(this.ReactContainerElement);\n\n // Set up bidirectional click selection on container\n this.installContainerClickListener();\n }\n\n private ensureContainerPositioned(): void {\n if (!this.ReactContainerElement) return;\n const containerStyle = getComputedStyle(this.ReactContainerElement);\n if (containerStyle.position === 'static') {\n this.ReactContainerElement.style.position = 'relative';\n }\n }\n\n /**\n * Gets the effective bounding rect for a component marker element.\n * display:contents elements return zero-size rects, so we compute\n * the union bounding box of their children instead.\n */\n private getEffectiveRect(el: Element): DOMRect {\n const rect = el.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) return rect;\n\n // display:contents wrapper — union the bounding rects of all children\n const children = el.children;\n if (children.length === 0) return rect;\n\n let top = Infinity, left = Infinity, bottom = -Infinity, right = -Infinity;\n for (let i = 0; i < children.length; i++) {\n const childRect = children[i].getBoundingClientRect();\n if (childRect.width === 0 && childRect.height === 0) continue;\n top = Math.min(top, childRect.top);\n left = Math.min(left, childRect.left);\n bottom = Math.max(bottom, childRect.bottom);\n right = Math.max(right, childRect.right);\n }\n\n if (top === Infinity) return rect; // no visible children\n return new DOMRect(left, top, right - left, bottom - top);\n }\n\n private positionOverlay(overlay: HTMLElement, targetEl: Element): void {\n if (!this.ReactContainerElement) return;\n\n const targetRect = this.getEffectiveRect(targetEl);\n const containerRect = this.ReactContainerElement.getBoundingClientRect();\n\n overlay.style.position = 'absolute';\n overlay.style.top = `${targetRect.top - containerRect.top + this.ReactContainerElement.scrollTop}px`;\n overlay.style.left = `${targetRect.left - containerRect.left + this.ReactContainerElement.scrollLeft}px`;\n overlay.style.width = `${targetRect.width}px`;\n overlay.style.height = `${targetRect.height}px`;\n overlay.style.pointerEvents = 'none';\n overlay.style.zIndex = '10';\n overlay.style.borderRadius = '4px';\n overlay.style.transition = 'all 0.2s ease';\n }\n\n // --- Bidirectional click: clicking a component region selects it in the tree ---\n\n private installContainerClickListener(): void {\n if (this.containerClickHandler || !this.ReactContainerElement) return;\n\n this.containerClickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n\n // Walk up from click target to find nearest [data-mj-component]\n const componentEl = target.closest('[data-mj-component]');\n if (!componentEl) return;\n\n const componentName = componentEl.getAttribute('data-mj-component');\n if (!componentName) return;\n\n // Find matching spec in the tree\n const matchingSpec = this.findSpecByName(componentName);\n if (matchingSpec && matchingSpec.name !== this.SelectedSpec?.name) {\n this.SelectComponent(matchingSpec);\n this.cdr.detectChanges();\n }\n };\n\n // Use capture phase so we observe the click without interfering with component handlers\n this.ReactContainerElement.addEventListener('click', this.containerClickHandler, true);\n }\n\n private removeContainerClickListener(): void {\n if (this.containerClickHandler && this.ReactContainerElement) {\n this.ReactContainerElement.removeEventListener('click', this.containerClickHandler, true);\n }\n this.containerClickHandler = null;\n }\n\n private findSpecByName(name: string): ComponentSpec | null {\n if (!this.ComponentSpec) return null;\n return this.walkSpecTree(this.ComponentSpec, name);\n }\n\n private walkSpecTree(spec: ComponentSpec, name: string): ComponentSpec | null {\n if (spec.name === name) return spec;\n if (spec.dependencies) {\n for (const child of spec.dependencies) {\n const found = this.walkSpecTree(child, name);\n if (found) return found;\n }\n }\n return null;\n }\n\n private ClearHighlight(): void {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n if (this.highlightOverlay?.parentNode) {\n this.highlightOverlay.parentNode.removeChild(this.highlightOverlay);\n }\n this.highlightOverlay = null;\n this.removeHoverOverlay();\n this.removeContainerClickListener();\n }\n\n ClosePanel(): void {\n this.ClearHighlight();\n this.Closed.emit();\n }\n\n ngOnDestroy(): void {\n this.ClearHighlight();\n }\n}\n","<div class=\"feedback-panel-overlay\" (click)=\"ClosePanel()\">\n <div class=\"feedback-panel\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-comment-dots\"></i>\n <span>Component Feedback</span>\n </div>\n <button class=\"close-button\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"panel-content\">\n <!-- Component Tree Section -->\n <div class=\"tree-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <span>Select Component</span>\n </div>\n\n @if (ComponentSpec) {\n <div class=\"component-tree\">\n @for (item of GetTreeItems(); track item.spec.name) {\n <div\n class=\"tree-item\"\n [class.selected]=\"IsSelected(item.spec)\"\n [style.padding-left]=\"GetIndentation(item.depth)\"\n (click)=\"SelectComponent(item.spec)\"\n (mouseenter)=\"HoverTreeItem(item.spec)\"\n (mouseleave)=\"ClearTreeItemHover()\">\n\n @if (item.hasChildren) {\n <i\n class=\"tree-toggle fa-solid\"\n [class.fa-chevron-right]=\"!IsNodeExpanded(item.spec)\"\n [class.fa-chevron-down]=\"IsNodeExpanded(item.spec)\"\n (click)=\"ToggleNode(item.spec, $event)\">\n </i>\n } @else {\n <span class=\"tree-spacer\"></span>\n }\n\n <i class=\"fa-solid fa-cube component-icon\"></i>\n\n <div class=\"component-info\">\n <span class=\"component-name\">{{ item.spec.title || item.spec.name }}</span>\n @if (item.spec.location === 'registry') {\n <span class=\"component-badge registry\">Registry</span>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No component hierarchy available</span>\n </div>\n }\n </div>\n\n <!-- Feedback Form Section -->\n <div class=\"feedback-section\">\n @if (SelectedSpec) {\n <div class=\"selected-component-info\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-star\"></i>\n <span>Rate: {{ SelectedSpec.title || SelectedSpec.name }}</span>\n </div>\n\n @if (SelectedSpec.description) {\n <p class=\"component-description\">{{ SelectedSpec.description }}</p>\n }\n\n <!-- Star Rating -->\n <div class=\"star-rating-container\">\n <label class=\"rating-label\">Your Rating</label>\n <div class=\"star-rating\">\n @for (star of [1, 2, 3, 4, 5]; track star) {\n <i\n class=\"star\"\n [class.fa-solid]=\"IsStarFilled(star)\"\n [class.fa-regular]=\"!IsStarFilled(star)\"\n [class.fa-star]=\"true\"\n (click)=\"SetRating(star)\"\n (mouseenter)=\"SetHoverRating(star)\"\n (mouseleave)=\"ClearHoverRating()\">\n </i>\n }\n </div>\n @if (StarRating > 0) {\n <span class=\"rating-text\">{{ StarRating }} out of 5 stars</span>\n } @else {\n <span class=\"rating-text placeholder\">Click to rate</span>\n }\n </div>\n\n <!-- Comment Input -->\n <div class=\"comment-container\">\n <label class=\"comment-label\">\n Comments\n <span class=\"optional-label\">(optional)</span>\n </label>\n <textarea\n class=\"comment-input\"\n [(ngModel)]=\"FeedbackComments\"\n placeholder=\"Share your thoughts about this component...\"\n rows=\"4\"\n maxlength=\"1000\">\n </textarea>\n @if (FeedbackComments.length > 0) {\n <span class=\"char-count\">{{ FeedbackComments.length }}/1000</span>\n }\n </div>\n\n <!-- Submit Button -->\n <div class=\"submit-container\">\n <button\n class=\"submit-button\"\n [disabled]=\"!CanSubmit()\"\n (click)=\"SubmitFeedback()\">\n @if (IsSubmitting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Submitting...</span>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>Submit Feedback</span>\n }\n </button>\n </div>\n\n <!-- Success/Error Messages -->\n @if (SubmitSuccess) {\n <div class=\"message success-message\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>Feedback submitted successfully!</span>\n </div>\n }\n @if (SubmitError) {\n <div class=\"message error-message\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ SubmitError }}</span>\n </div>\n }\n </div>\n } @else {\n <div class=\"no-selection-message\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n <p>Select a component from the tree to provide feedback</p>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n"]}
1
+ {"version":3,"file":"component-feedback-panel.component.js","sourceRoot":"","sources":["../../../../../src/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.ts","../../../../../src/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnDestroy, ChangeDetectorRef, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { Metadata } from '@memberjunction/core';\nimport { ComponentSpec } from '@memberjunction/interactive-component-types';\nimport { MarkdownModule } from '@memberjunction/ng-markdown';\n\n/**\n * Flattened tree item for rendering the component hierarchy\n */\ninterface TreeItem {\n spec: ComponentSpec;\n depth: number;\n hasChildren: boolean;\n}\n\n/**\n * Component feedback panel that displays component hierarchy tree\n * and allows users to select components and provide star ratings with comments.\n * Registry-agnostic: works with any component registry (Skip, MJ Central, etc.)\n */\n@Component({\n selector: 'mj-component-feedback-panel',\n standalone: true,\n imports: [CommonModule, FormsModule, MarkdownModule],\n templateUrl: './component-feedback-panel.component.html',\n styleUrls: ['./component-feedback-panel.component.css']\n})\nexport class ComponentFeedbackPanelComponent implements OnDestroy {\n @Input() ComponentSpec: ComponentSpec | null = null;\n @Input() ReactContainerElement: HTMLElement | null = null;\n @Input() ConversationId: string | null = null;\n @Input() ConversationDetailId: string | null = null;\n\n @Output() Closed = new EventEmitter<void>();\n\n // Feedback form state\n public SelectedSpec: ComponentSpec | null = null;\n public StarRating = 0;\n public HoverRating = 0;\n public FeedbackComments = '';\n public IsSubmitting = false;\n public SubmitSuccess = false;\n public SubmitError = '';\n\n // Tree state\n public ExpandedNodes = new Set<string>();\n\n // Highlight overlays\n private highlightOverlay: HTMLElement | null = null;\n private hoverOverlay: HTMLElement | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private containerClickHandler: ((e: MouseEvent) => void) | null = null;\n\n private cdr = inject(ChangeDetectorRef);\n\n // --- Tree Methods ---\n\n GetTreeItems(): TreeItem[] {\n if (!this.ComponentSpec) return [];\n if (!this.ExpandedNodes.has(this.ComponentSpec.name)) {\n this.ExpandedNodes.add(this.ComponentSpec.name);\n }\n return this.buildTree(this.ComponentSpec, 0);\n }\n\n private buildTree(spec: ComponentSpec, depth: number): TreeItem[] {\n const items: TreeItem[] = [{\n spec,\n depth,\n hasChildren: !!(spec.dependencies && spec.dependencies.length > 0)\n }];\n if (this.ExpandedNodes.has(spec.name) && spec.dependencies) {\n for (const child of spec.dependencies) {\n items.push(...this.buildTree(child, depth + 1));\n }\n }\n return items;\n }\n\n ToggleNode(spec: ComponentSpec, event: MouseEvent): void {\n event.stopPropagation();\n if (this.ExpandedNodes.has(spec.name)) {\n this.ExpandedNodes.delete(spec.name);\n } else {\n this.ExpandedNodes.add(spec.name);\n }\n }\n\n IsNodeExpanded(spec: ComponentSpec): boolean {\n return this.ExpandedNodes.has(spec.name);\n }\n\n SelectComponent(spec: ComponentSpec): void {\n this.SelectedSpec = spec;\n this.ResetForm();\n this.HighlightComponent(spec.name);\n }\n\n IsSelected(spec: ComponentSpec): boolean {\n return this.SelectedSpec?.name === spec.name;\n }\n\n GetIndentation(depth: number): string {\n return `${depth * 20}px`;\n }\n\n // --- Star Rating (supports half-star increments) ---\n\n SetRating(value: number): void {\n this.StarRating = value;\n }\n\n SetHoverRating(value: number): void {\n this.HoverRating = value;\n }\n\n ClearHoverRating(): void {\n this.HoverRating = 0;\n }\n\n GetDisplayRating(): number {\n return this.HoverRating || this.StarRating;\n }\n\n /** Returns 'full' | 'half' | 'empty' for the given 1-based star index */\n GetStarState(index: number): 'full' | 'half' | 'empty' {\n const rating = this.GetDisplayRating();\n if (index <= rating) return 'full';\n if (index - 0.5 <= rating) return 'half';\n return 'empty';\n }\n\n IsStarFilled(index: number): boolean {\n return index <= this.GetDisplayRating();\n }\n\n // --- Form ---\n\n ResetForm(): void {\n this.StarRating = 0;\n this.HoverRating = 0;\n this.FeedbackComments = '';\n this.SubmitSuccess = false;\n this.SubmitError = '';\n }\n\n CanSubmit(): boolean {\n return !!this.SelectedSpec && this.StarRating > 0 && !this.IsSubmitting;\n }\n\n async SubmitFeedback(): Promise<void> {\n if (!this.CanSubmit() || !this.SelectedSpec) return;\n\n this.IsSubmitting = true;\n this.SubmitError = '';\n this.SubmitSuccess = false;\n this.cdr.detectChanges();\n\n try {\n // Dynamic import to avoid adding graphql-dataprovider as a package dependency.\n // At runtime in the browser, Metadata.Provider is always a GraphQLDataProvider.\n const { GraphQLComponentRegistryClient } = await import('@memberjunction/graphql-dataprovider');\n const provider = Metadata.Provider;\n const client = new GraphQLComponentRegistryClient(provider as ConstructorParameters<typeof GraphQLComponentRegistryClient>[0]);\n\n const response = await client.SendComponentFeedback({\n componentName: this.SelectedSpec.name,\n componentNamespace: this.SelectedSpec.namespace || this.SelectedSpec.registry || '',\n componentVersion: this.SelectedSpec.version,\n registryName: this.SelectedSpec.registry,\n rating: this.StarRating * 20, // 0-5 -> 0-100\n comments: this.FeedbackComments.trim() || undefined,\n conversationID: this.ConversationId || undefined,\n conversationDetailID: this.ConversationDetailId || undefined\n });\n\n if (response.success) {\n this.SubmitSuccess = true;\n setTimeout(() => {\n this.ResetForm();\n this.cdr.detectChanges();\n }, 2000);\n } else {\n this.SubmitError = response.error || 'Failed to submit feedback.';\n }\n } catch (error) {\n this.SubmitError = 'Failed to submit feedback. Please try again.';\n console.error('Error submitting component feedback:', error);\n } finally {\n this.IsSubmitting = false;\n this.cdr.detectChanges();\n }\n }\n\n // --- Hover Highlight (light preview on tree hover) ---\n\n HoverTreeItem(spec: ComponentSpec): void {\n if (!this.ReactContainerElement || this.IsSelected(spec)) return;\n this.showHoverOverlay(spec.name);\n }\n\n ClearTreeItemHover(): void {\n this.removeHoverOverlay();\n }\n\n private showHoverOverlay(componentName: string): void {\n if (!this.ReactContainerElement) return;\n\n const targetEl = this.ReactContainerElement.querySelector(\n `[data-mj-component=\"${componentName}\"]`\n );\n if (!targetEl) {\n this.removeHoverOverlay();\n return;\n }\n\n this.ensureContainerPositioned();\n\n if (!this.hoverOverlay) {\n this.hoverOverlay = document.createElement('div');\n this.ReactContainerElement.appendChild(this.hoverOverlay);\n }\n\n this.positionOverlay(this.hoverOverlay, targetEl);\n this.hoverOverlay.style.border = '2px dashed var(--mj-brand-primary, #3B82F6)';\n this.hoverOverlay.style.background = 'color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 5%, transparent)';\n }\n\n private removeHoverOverlay(): void {\n if (this.hoverOverlay?.parentNode) {\n this.hoverOverlay.parentNode.removeChild(this.hoverOverlay);\n }\n this.hoverOverlay = null;\n }\n\n // --- Region Highlighting (solid selection) ---\n\n private HighlightComponent(componentName: string): void {\n if (!this.ReactContainerElement) {\n this.ClearHighlight();\n return;\n }\n\n const targetEl = this.ReactContainerElement.querySelector(\n `[data-mj-component=\"${componentName}\"]`\n );\n if (!targetEl) {\n this.ClearHighlight();\n return;\n }\n\n this.ensureContainerPositioned();\n\n if (!this.highlightOverlay) {\n this.highlightOverlay = document.createElement('div');\n this.ReactContainerElement.appendChild(this.highlightOverlay);\n }\n\n this.positionOverlay(this.highlightOverlay, targetEl);\n this.highlightOverlay.style.border = '2px solid var(--mj-brand-primary, #3B82F6)';\n this.highlightOverlay.style.background = 'color-mix(in srgb, var(--mj-brand-primary, #3B82F6) 10%, transparent)';\n\n // Watch for resize/layout changes\n this.resizeObserver?.disconnect();\n this.resizeObserver = new ResizeObserver(() => {\n if (this.highlightOverlay) {\n this.positionOverlay(this.highlightOverlay, targetEl);\n }\n });\n this.resizeObserver.observe(targetEl);\n this.resizeObserver.observe(this.ReactContainerElement);\n\n // Set up bidirectional click selection on container\n this.installContainerClickListener();\n }\n\n private ensureContainerPositioned(): void {\n if (!this.ReactContainerElement) return;\n const containerStyle = getComputedStyle(this.ReactContainerElement);\n if (containerStyle.position === 'static') {\n this.ReactContainerElement.style.position = 'relative';\n }\n }\n\n /**\n * Gets the effective bounding rect for a component marker element.\n * display:contents elements return zero-size rects, so we compute\n * the union bounding box of their children instead.\n */\n private getEffectiveRect(el: Element): DOMRect {\n const rect = el.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) return rect;\n\n // display:contents wrapper — union the bounding rects of all children\n const children = el.children;\n if (children.length === 0) return rect;\n\n let top = Infinity, left = Infinity, bottom = -Infinity, right = -Infinity;\n for (let i = 0; i < children.length; i++) {\n const childRect = children[i].getBoundingClientRect();\n if (childRect.width === 0 && childRect.height === 0) continue;\n top = Math.min(top, childRect.top);\n left = Math.min(left, childRect.left);\n bottom = Math.max(bottom, childRect.bottom);\n right = Math.max(right, childRect.right);\n }\n\n if (top === Infinity) return rect; // no visible children\n return new DOMRect(left, top, right - left, bottom - top);\n }\n\n private positionOverlay(overlay: HTMLElement, targetEl: Element): void {\n if (!this.ReactContainerElement) return;\n\n const targetRect = this.getEffectiveRect(targetEl);\n const containerRect = this.ReactContainerElement.getBoundingClientRect();\n\n overlay.style.position = 'absolute';\n overlay.style.top = `${targetRect.top - containerRect.top + this.ReactContainerElement.scrollTop}px`;\n overlay.style.left = `${targetRect.left - containerRect.left + this.ReactContainerElement.scrollLeft}px`;\n overlay.style.width = `${targetRect.width}px`;\n overlay.style.height = `${targetRect.height}px`;\n overlay.style.pointerEvents = 'none';\n overlay.style.zIndex = '10';\n overlay.style.borderRadius = '4px';\n overlay.style.transition = 'all 0.2s ease';\n }\n\n // --- Bidirectional click: clicking a component region selects it in the tree ---\n\n private installContainerClickListener(): void {\n if (this.containerClickHandler || !this.ReactContainerElement) return;\n\n this.containerClickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n\n // Walk up from click target to find nearest [data-mj-component]\n const componentEl = target.closest('[data-mj-component]');\n if (!componentEl) return;\n\n const componentName = componentEl.getAttribute('data-mj-component');\n if (!componentName) return;\n\n // Find matching spec in the tree\n const matchingSpec = this.findSpecByName(componentName);\n if (matchingSpec && matchingSpec.name !== this.SelectedSpec?.name) {\n this.SelectComponent(matchingSpec);\n this.cdr.detectChanges();\n }\n };\n\n // Use capture phase so we observe the click without interfering with component handlers\n this.ReactContainerElement.addEventListener('click', this.containerClickHandler, true);\n }\n\n private removeContainerClickListener(): void {\n if (this.containerClickHandler && this.ReactContainerElement) {\n this.ReactContainerElement.removeEventListener('click', this.containerClickHandler, true);\n }\n this.containerClickHandler = null;\n }\n\n private findSpecByName(name: string): ComponentSpec | null {\n if (!this.ComponentSpec) return null;\n return this.walkSpecTree(this.ComponentSpec, name);\n }\n\n private walkSpecTree(spec: ComponentSpec, name: string): ComponentSpec | null {\n if (spec.name === name) return spec;\n if (spec.dependencies) {\n for (const child of spec.dependencies) {\n const found = this.walkSpecTree(child, name);\n if (found) return found;\n }\n }\n return null;\n }\n\n private ClearHighlight(): void {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n if (this.highlightOverlay?.parentNode) {\n this.highlightOverlay.parentNode.removeChild(this.highlightOverlay);\n }\n this.highlightOverlay = null;\n this.removeHoverOverlay();\n this.removeContainerClickListener();\n }\n\n ClosePanel(): void {\n this.ClearHighlight();\n this.Closed.emit();\n }\n\n ngOnDestroy(): void {\n this.ClearHighlight();\n }\n}\n","<div class=\"feedback-panel-overlay\" (click)=\"ClosePanel()\">\n <div class=\"feedback-panel\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-title\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span>Inspect & Rate</span>\n </div>\n <button class=\"close-button\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"panel-content\">\n <!-- Component Tree Section -->\n <div class=\"tree-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <span>Select Component</span>\n </div>\n\n @if (ComponentSpec) {\n <div class=\"component-tree\">\n @for (item of GetTreeItems(); track item.spec.name) {\n <div\n class=\"tree-item\"\n [class.selected]=\"IsSelected(item.spec)\"\n [style.padding-left]=\"GetIndentation(item.depth)\"\n (click)=\"SelectComponent(item.spec)\"\n (mouseenter)=\"HoverTreeItem(item.spec)\"\n (mouseleave)=\"ClearTreeItemHover()\">\n\n @if (item.hasChildren) {\n <i\n class=\"tree-toggle fa-solid\"\n [class.fa-chevron-right]=\"!IsNodeExpanded(item.spec)\"\n [class.fa-chevron-down]=\"IsNodeExpanded(item.spec)\"\n (click)=\"ToggleNode(item.spec, $event)\">\n </i>\n } @else {\n <span class=\"tree-spacer\"></span>\n }\n\n <i class=\"fa-solid fa-cube component-icon\"></i>\n\n <div class=\"component-info\">\n <span class=\"component-name\">{{ item.spec.title || item.spec.name }}</span>\n @if (item.spec.location === 'registry') {\n <span class=\"component-badge registry\">Registry</span>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No component hierarchy available</span>\n </div>\n }\n </div>\n\n <!-- Feedback Form Section -->\n <div class=\"feedback-section\">\n @if (SelectedSpec) {\n <div class=\"selected-component-info\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-star\"></i>\n <span>Rate: {{ SelectedSpec.title || SelectedSpec.name }}</span>\n </div>\n\n @if (SelectedSpec.description) {\n <mj-markdown [data]=\"SelectedSpec.description\" class=\"component-description\"></mj-markdown>\n }\n\n <!-- Star Rating (half-star support) -->\n <div class=\"star-rating-container\">\n <label class=\"rating-label\">Your Rating</label>\n <div class=\"star-rating\" (mouseleave)=\"ClearHoverRating()\">\n @for (star of [1, 2, 3, 4, 5]; track star) {\n <span class=\"star-wrapper\">\n <!-- Left half (sets X.5 for previous half) -->\n <span class=\"star-zone star-zone-left\"\n (click)=\"SetRating(star - 0.5)\"\n (mouseenter)=\"SetHoverRating(star - 0.5)\"></span>\n <!-- Right half (sets full star) -->\n <span class=\"star-zone star-zone-right\"\n (click)=\"SetRating(star)\"\n (mouseenter)=\"SetHoverRating(star)\"></span>\n <!-- Star icon -->\n @switch (GetStarState(star)) {\n @case ('full') {\n <i class=\"star fa-solid fa-star\"></i>\n }\n @case ('half') {\n <i class=\"star fa-solid fa-star-half-stroke\"></i>\n }\n @default {\n <i class=\"star fa-regular fa-star\"></i>\n }\n }\n </span>\n }\n </div>\n @if (StarRating === 0) {\n <span class=\"rating-text placeholder\">Click to rate</span>\n }\n </div>\n\n <!-- Comment Input -->\n <div class=\"comment-container\">\n <label class=\"comment-label\">\n Comments\n <span class=\"optional-label\">(optional)</span>\n </label>\n <textarea\n class=\"comment-input\"\n [(ngModel)]=\"FeedbackComments\"\n placeholder=\"Share your thoughts about this component...\"\n rows=\"4\"\n maxlength=\"1000\">\n </textarea>\n @if (FeedbackComments.length > 0) {\n <span class=\"char-count\">{{ FeedbackComments.length }}/1000</span>\n }\n </div>\n\n <!-- Submit Button -->\n <div class=\"submit-container\">\n <button\n class=\"submit-button\"\n [disabled]=\"!CanSubmit()\"\n (click)=\"SubmitFeedback()\">\n @if (IsSubmitting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Submitting...</span>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>Submit Feedback</span>\n }\n </button>\n </div>\n\n <!-- Success/Error Messages -->\n @if (SubmitSuccess) {\n <div class=\"message success-message\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>Feedback submitted successfully!</span>\n </div>\n }\n @if (SubmitError) {\n <div class=\"message error-message\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ SubmitError }}</span>\n </div>\n }\n </div>\n } @else {\n <div class=\"no-selection-message\">\n <i class=\"fa-solid fa-hand-pointer\"></i>\n <p>Select a component from the tree to provide feedback</p>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n"]}