@memberjunction/ng-skip-chat 2.47.0 → 2.49.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 (43) hide show
  1. package/README.md +1 -1
  2. package/dist/lib/artifacts/skip-artifact-viewer.component.js +254 -270
  3. package/dist/lib/artifacts/skip-artifact-viewer.component.js.map +1 -1
  4. package/dist/lib/artifacts/skip-artifacts-counter.component.js +82 -90
  5. package/dist/lib/artifacts/skip-artifacts-counter.component.js.map +1 -1
  6. package/dist/lib/drill-down-info.js +4 -3
  7. package/dist/lib/drill-down-info.js.map +1 -1
  8. package/dist/lib/dynamic-report/base-report.js +147 -164
  9. package/dist/lib/dynamic-report/base-report.js.map +1 -1
  10. package/dist/lib/dynamic-report/dynamic-chart.js +77 -86
  11. package/dist/lib/dynamic-report/dynamic-chart.js.map +1 -1
  12. package/dist/lib/dynamic-report/dynamic-grid.js +80 -93
  13. package/dist/lib/dynamic-report/dynamic-grid.js.map +1 -1
  14. package/dist/lib/dynamic-report/{dynamic-html-report.d.ts → dynamic-ui-component.d.ts} +64 -8
  15. package/dist/lib/dynamic-report/dynamic-ui-component.d.ts.map +1 -0
  16. package/dist/lib/dynamic-report/dynamic-ui-component.js +1756 -0
  17. package/dist/lib/dynamic-report/dynamic-ui-component.js.map +1 -0
  18. package/dist/lib/dynamic-report/linear-report.js +21 -31
  19. package/dist/lib/dynamic-report/linear-report.js.map +1 -1
  20. package/dist/lib/dynamic-report/skip-dynamic-report-wrapper.js +28 -28
  21. package/dist/lib/dynamic-report/skip-dynamic-report-wrapper.js.map +1 -1
  22. package/dist/lib/dynamic-report/skip-react-component-host.js +203 -212
  23. package/dist/lib/dynamic-report/skip-react-component-host.js.map +1 -1
  24. package/dist/lib/module.d.ts +4 -3
  25. package/dist/lib/module.d.ts.map +1 -1
  26. package/dist/lib/module.js +31 -27
  27. package/dist/lib/module.js.map +1 -1
  28. package/dist/lib/report-cache.js +2 -5
  29. package/dist/lib/report-cache.js.map +1 -1
  30. package/dist/lib/skip-chat/skip-chat.component.js +1052 -1087
  31. package/dist/lib/skip-chat/skip-chat.component.js.map +1 -1
  32. package/dist/lib/skip-single-message/skip-single-message.component.js +251 -259
  33. package/dist/lib/skip-single-message/skip-single-message.component.js.map +1 -1
  34. package/dist/lib/split-panel/skip-split-panel.component.js +52 -51
  35. package/dist/lib/split-panel/skip-split-panel.component.js.map +1 -1
  36. package/dist/public-api.d.ts +1 -1
  37. package/dist/public-api.d.ts.map +1 -1
  38. package/dist/public-api.js +1 -1
  39. package/dist/public-api.js.map +1 -1
  40. package/package.json +14 -12
  41. package/dist/lib/dynamic-report/dynamic-html-report.d.ts.map +0 -1
  42. package/dist/lib/dynamic-report/dynamic-html-report.js +0 -1104
  43. package/dist/lib/dynamic-report/dynamic-html-report.js.map +0 -1
@@ -1,1104 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { Component, EventEmitter, Input, Output, ViewChildren } from '@angular/core';
11
- import { CompositeKey, LogError, Metadata, RunQuery, RunView } from '@memberjunction/core';
12
- import { SkipReactComponentHost } from './skip-react-component-host';
13
- import { MapEntityInfoToSkipEntityInfo, BuildSkipComponentCompleteCode } from '@memberjunction/skip-types';
14
- import { DrillDownInfo } from '../drill-down-info';
15
- import * as i0 from "@angular/core";
16
- import * as i1 from "@angular/common";
17
- import * as i2 from "@progress/kendo-angular-layout";
18
- import * as i3 from "@progress/kendo-angular-buttons";
19
- const _c0 = ["htmlContainer"];
20
- function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
21
- i0.ɵɵelement(0, "i", 7);
22
- } }
23
- function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_1_Template(rf, ctx) { if (rf & 1) {
24
- i0.ɵɵtemplate(0, SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_1_Conditional_0_Template, 1, 0, "i", 7);
25
- i0.ɵɵtext(1);
26
- } if (rf & 2) {
27
- const ɵ$index_4_r3 = i0.ɵɵnextContext().$index;
28
- const ctx_r1 = i0.ɵɵnextContext(2);
29
- i0.ɵɵconditional(ctx_r1.isTopRanked(ɵ$index_4_r3) ? 0 : -1);
30
- i0.ɵɵadvance();
31
- i0.ɵɵtextInterpolate1(" ", ctx_r1.getTabTitle(ɵ$index_4_r3), " ");
32
- } }
33
- function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_button_4_Template(rf, ctx) { if (rf & 1) {
34
- const _r4 = i0.ɵɵgetCurrentView();
35
- i0.ɵɵelementStart(0, "button", 15);
36
- i0.ɵɵlistener("click", function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_button_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ɵ$index_4_r3 = i0.ɵɵnextContext(2).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.createReportForOption(ɵ$index_4_r3)); });
37
- i0.ɵɵelement(1, "i", 16);
38
- i0.ɵɵelementStart(2, "span");
39
- i0.ɵɵtext(3, "Create Report");
40
- i0.ɵɵelementEnd()();
41
- } if (rf & 2) {
42
- const ctx_r1 = i0.ɵɵnextContext(4);
43
- i0.ɵɵproperty("disabled", ctx_r1.isCreatingReport);
44
- } }
45
- function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_button_5_Template(rf, ctx) { if (rf & 1) {
46
- const _r5 = i0.ɵɵgetCurrentView();
47
- i0.ɵɵelementStart(0, "button", 17);
48
- i0.ɵɵlistener("click", function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_button_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.PrintReport()); });
49
- i0.ɵɵelement(1, "i", 18);
50
- i0.ɵɵelementStart(2, "span");
51
- i0.ɵɵtext(3, "Print Report");
52
- i0.ɵɵelementEnd()();
53
- } }
54
- function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_Conditional_8_Conditional_19_Template(rf, ctx) { if (rf & 1) {
55
- i0.ɵɵelementStart(0, "details", 27)(1, "summary", 33);
56
- i0.ɵɵtext(2, "Technical Details (click to expand)");
57
- i0.ɵɵelementEnd();
58
- i0.ɵɵelementStart(3, "pre", 34);
59
- i0.ɵɵtext(4);
60
- i0.ɵɵelementEnd()();
61
- } if (rf & 2) {
62
- const ctx_r1 = i0.ɵɵnextContext(5);
63
- i0.ɵɵadvance(4);
64
- i0.ɵɵtextInterpolate(ctx_r1.currentError.technicalDetails);
65
- } }
66
- function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
67
- const _r6 = i0.ɵɵgetCurrentView();
68
- i0.ɵɵelementStart(0, "div", 14)(1, "div", 19)(2, "div", 20)(3, "button", 21);
69
- i0.ɵɵlistener("click", function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_Conditional_8_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.copyErrorToClipboard()); });
70
- i0.ɵɵelement(4, "span", 22);
71
- i0.ɵɵtext(5, " Copy Error Details ");
72
- i0.ɵɵelementEnd();
73
- i0.ɵɵelementStart(6, "h3", 23);
74
- i0.ɵɵelement(7, "span", 24);
75
- i0.ɵɵtext(8, " Component Rendering Error ");
76
- i0.ɵɵelementEnd()();
77
- i0.ɵɵelementStart(9, "p", 25);
78
- i0.ɵɵtext(10, " The selected component option could not be rendered due to the following error: ");
79
- i0.ɵɵelementEnd();
80
- i0.ɵɵelementStart(11, "div", 26)(12, "strong");
81
- i0.ɵɵtext(13, "Error Type:");
82
- i0.ɵɵelementEnd();
83
- i0.ɵɵtext(14);
84
- i0.ɵɵelement(15, "br");
85
- i0.ɵɵelementStart(16, "strong");
86
- i0.ɵɵtext(17, "Details:");
87
- i0.ɵɵelementEnd();
88
- i0.ɵɵtext(18);
89
- i0.ɵɵtemplate(19, SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_Conditional_8_Conditional_19_Template, 5, 1, "details", 27);
90
- i0.ɵɵelementEnd();
91
- i0.ɵɵelementStart(20, "div", 28)(21, "strong", 29);
92
- i0.ɵɵtext(22, "What to do:");
93
- i0.ɵɵelementEnd();
94
- i0.ɵɵelementStart(23, "ol", 30)(24, "li");
95
- i0.ɵɵtext(25, "Try selecting a different report option from the tabs above");
96
- i0.ɵɵelementEnd();
97
- i0.ɵɵelementStart(26, "li");
98
- i0.ɵɵtext(27, "Copy the error details and send them back to Skip in the chat to get a corrected version");
99
- i0.ɵɵelementEnd();
100
- i0.ɵɵelementStart(28, "li");
101
- i0.ɵɵtext(29, "Contact your IT department if the issue persists");
102
- i0.ɵɵelementEnd()()();
103
- i0.ɵɵelementStart(30, "button", 31);
104
- i0.ɵɵlistener("click", function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_Conditional_8_Template_button_click_30_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.retryCurrentOption()); });
105
- i0.ɵɵelement(31, "span", 32);
106
- i0.ɵɵtext(32, " Retry ");
107
- i0.ɵɵelementEnd()()();
108
- } if (rf & 2) {
109
- const ctx_r1 = i0.ɵɵnextContext(4);
110
- i0.ɵɵadvance(14);
111
- i0.ɵɵtextInterpolate1(" ", ctx_r1.currentError.type, "");
112
- i0.ɵɵadvance(4);
113
- i0.ɵɵtextInterpolate1(" ", ctx_r1.currentError.message, " ");
114
- i0.ɵɵadvance();
115
- i0.ɵɵconditional(ctx_r1.currentError.technicalDetails ? 19 : -1);
116
- } }
117
- function SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_Template(rf, ctx) { if (rf & 1) {
118
- i0.ɵɵelementStart(0, "div", 2)(1, "div", 8);
119
- i0.ɵɵelement(2, "div", 9);
120
- i0.ɵɵelementStart(3, "div", 10);
121
- i0.ɵɵtemplate(4, SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_button_4_Template, 4, 1, "button", 11)(5, SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_button_5_Template, 4, 0, "button", 12);
122
- i0.ɵɵelementEnd()();
123
- i0.ɵɵelementStart(6, "div", 13, 0);
124
- i0.ɵɵtemplate(8, SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_Conditional_8_Template, 33, 3, "div", 14);
125
- i0.ɵɵelementEnd()();
126
- } if (rf & 2) {
127
- const ɵ$index_4_r3 = i0.ɵɵnextContext().$index;
128
- const ctx_r1 = i0.ɵɵnextContext(2);
129
- i0.ɵɵadvance(4);
130
- i0.ɵɵproperty("ngIf", ctx_r1.ShowCreateReportButton && !ctx_r1.matchingReportID);
131
- i0.ɵɵadvance();
132
- i0.ɵɵproperty("ngIf", ctx_r1.ShowPrintReport);
133
- i0.ɵɵadvance();
134
- i0.ɵɵattribute("data-tab-index", ɵ$index_4_r3);
135
- i0.ɵɵadvance(2);
136
- i0.ɵɵconditional(ctx_r1.currentError && ctx_r1.selectedReportOptionIndex === ɵ$index_4_r3 ? 8 : -1);
137
- } }
138
- function SkipDynamicHTMLReportComponent_Conditional_0_For_2_Template(rf, ctx) { if (rf & 1) {
139
- i0.ɵɵelementStart(0, "kendo-tabstrip-tab", 4);
140
- i0.ɵɵtemplate(1, SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_1_Template, 2, 2, "ng-template", 5)(2, SkipDynamicHTMLReportComponent_Conditional_0_For_2_ng_template_2_Template, 9, 4, "ng-template", 6);
141
- i0.ɵɵelementEnd();
142
- } if (rf & 2) {
143
- const ɵ$index_4_r3 = ctx.$index;
144
- const ctx_r1 = i0.ɵɵnextContext(2);
145
- i0.ɵɵproperty("selected", ɵ$index_4_r3 === ctx_r1.selectedReportOptionIndex);
146
- } }
147
- function SkipDynamicHTMLReportComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
148
- const _r1 = i0.ɵɵgetCurrentView();
149
- i0.ɵɵelementStart(0, "kendo-tabstrip", 3);
150
- i0.ɵɵlistener("tabSelect", function SkipDynamicHTMLReportComponent_Conditional_0_Template_kendo_tabstrip_tabSelect_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onTabSelect($event)); });
151
- i0.ɵɵrepeaterCreate(1, SkipDynamicHTMLReportComponent_Conditional_0_For_2_Template, 3, 1, "kendo-tabstrip-tab", 4, i0.ɵɵrepeaterTrackByIdentity);
152
- i0.ɵɵelementEnd();
153
- } if (rf & 2) {
154
- const ctx_r1 = i0.ɵɵnextContext();
155
- i0.ɵɵproperty("keepTabContent", true);
156
- i0.ɵɵadvance();
157
- i0.ɵɵrepeater(ctx_r1.reportOptions);
158
- } }
159
- function SkipDynamicHTMLReportComponent_Conditional_1_button_4_Template(rf, ctx) { if (rf & 1) {
160
- const _r7 = i0.ɵɵgetCurrentView();
161
- i0.ɵɵelementStart(0, "button", 15);
162
- i0.ɵɵlistener("click", function SkipDynamicHTMLReportComponent_Conditional_1_button_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.createReportForOption(0)); });
163
- i0.ɵɵelement(1, "i", 16);
164
- i0.ɵɵelementStart(2, "span");
165
- i0.ɵɵtext(3, "Create Report");
166
- i0.ɵɵelementEnd()();
167
- } if (rf & 2) {
168
- const ctx_r1 = i0.ɵɵnextContext(2);
169
- i0.ɵɵproperty("disabled", ctx_r1.isCreatingReport);
170
- } }
171
- function SkipDynamicHTMLReportComponent_Conditional_1_button_5_Template(rf, ctx) { if (rf & 1) {
172
- const _r8 = i0.ɵɵgetCurrentView();
173
- i0.ɵɵelementStart(0, "button", 17);
174
- i0.ɵɵlistener("click", function SkipDynamicHTMLReportComponent_Conditional_1_button_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.PrintReport()); });
175
- i0.ɵɵelement(1, "i", 18);
176
- i0.ɵɵelementStart(2, "span");
177
- i0.ɵɵtext(3, "Print Report");
178
- i0.ɵɵelementEnd()();
179
- } }
180
- function SkipDynamicHTMLReportComponent_Conditional_1_Conditional_8_Conditional_19_Template(rf, ctx) { if (rf & 1) {
181
- i0.ɵɵelementStart(0, "details", 27)(1, "summary", 33);
182
- i0.ɵɵtext(2, "Technical Details (click to expand)");
183
- i0.ɵɵelementEnd();
184
- i0.ɵɵelementStart(3, "pre", 34);
185
- i0.ɵɵtext(4);
186
- i0.ɵɵelementEnd()();
187
- } if (rf & 2) {
188
- const ctx_r1 = i0.ɵɵnextContext(3);
189
- i0.ɵɵadvance(4);
190
- i0.ɵɵtextInterpolate(ctx_r1.currentError.technicalDetails);
191
- } }
192
- function SkipDynamicHTMLReportComponent_Conditional_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
193
- const _r9 = i0.ɵɵgetCurrentView();
194
- i0.ɵɵelementStart(0, "div", 35)(1, "div", 19)(2, "div", 20)(3, "button", 21);
195
- i0.ɵɵlistener("click", function SkipDynamicHTMLReportComponent_Conditional_1_Conditional_8_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.copyErrorToClipboard()); });
196
- i0.ɵɵelement(4, "span", 22);
197
- i0.ɵɵtext(5, " Copy Error Details ");
198
- i0.ɵɵelementEnd();
199
- i0.ɵɵelementStart(6, "h3", 23);
200
- i0.ɵɵelement(7, "span", 24);
201
- i0.ɵɵtext(8, " Component Rendering Error ");
202
- i0.ɵɵelementEnd()();
203
- i0.ɵɵelementStart(9, "p", 25);
204
- i0.ɵɵtext(10, " The selected component option could not be rendered due to the following error: ");
205
- i0.ɵɵelementEnd();
206
- i0.ɵɵelementStart(11, "div", 26)(12, "strong");
207
- i0.ɵɵtext(13, "Error Type:");
208
- i0.ɵɵelementEnd();
209
- i0.ɵɵtext(14);
210
- i0.ɵɵelement(15, "br");
211
- i0.ɵɵelementStart(16, "strong");
212
- i0.ɵɵtext(17, "Details:");
213
- i0.ɵɵelementEnd();
214
- i0.ɵɵtext(18);
215
- i0.ɵɵtemplate(19, SkipDynamicHTMLReportComponent_Conditional_1_Conditional_8_Conditional_19_Template, 5, 1, "details", 27);
216
- i0.ɵɵelementEnd();
217
- i0.ɵɵelementStart(20, "div", 28)(21, "strong", 29);
218
- i0.ɵɵtext(22, "What to do:");
219
- i0.ɵɵelementEnd();
220
- i0.ɵɵelementStart(23, "ol", 30)(24, "li");
221
- i0.ɵɵtext(25, "Copy the error details and send them back to Skip in the chat to get a corrected version");
222
- i0.ɵɵelementEnd();
223
- i0.ɵɵelementStart(26, "li");
224
- i0.ɵɵtext(27, "Contact your IT department if the issue persists");
225
- i0.ɵɵelementEnd()()();
226
- i0.ɵɵelementStart(28, "button", 31);
227
- i0.ɵɵlistener("click", function SkipDynamicHTMLReportComponent_Conditional_1_Conditional_8_Template_button_click_28_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.retryCurrentOption()); });
228
- i0.ɵɵelement(29, "span", 32);
229
- i0.ɵɵtext(30, " Retry ");
230
- i0.ɵɵelementEnd()()();
231
- } if (rf & 2) {
232
- const ctx_r1 = i0.ɵɵnextContext(2);
233
- i0.ɵɵadvance(14);
234
- i0.ɵɵtextInterpolate1(" ", ctx_r1.currentError.type, "");
235
- i0.ɵɵadvance(4);
236
- i0.ɵɵtextInterpolate1(" ", ctx_r1.currentError.message, " ");
237
- i0.ɵɵadvance();
238
- i0.ɵɵconditional(ctx_r1.currentError.technicalDetails ? 19 : -1);
239
- } }
240
- function SkipDynamicHTMLReportComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
241
- i0.ɵɵelementStart(0, "div", 2)(1, "div", 8);
242
- i0.ɵɵelement(2, "div", 9);
243
- i0.ɵɵelementStart(3, "div", 10);
244
- i0.ɵɵtemplate(4, SkipDynamicHTMLReportComponent_Conditional_1_button_4_Template, 4, 1, "button", 11)(5, SkipDynamicHTMLReportComponent_Conditional_1_button_5_Template, 4, 0, "button", 12);
245
- i0.ɵɵelementEnd()();
246
- i0.ɵɵelementStart(6, "div", 13, 0);
247
- i0.ɵɵtemplate(8, SkipDynamicHTMLReportComponent_Conditional_1_Conditional_8_Template, 31, 3, "div", 35);
248
- i0.ɵɵelementEnd()();
249
- } if (rf & 2) {
250
- const ctx_r1 = i0.ɵɵnextContext();
251
- i0.ɵɵadvance(4);
252
- i0.ɵɵproperty("ngIf", ctx_r1.ShowCreateReportButton && !ctx_r1.matchingReportID);
253
- i0.ɵɵadvance();
254
- i0.ɵɵproperty("ngIf", ctx_r1.ShowPrintReport);
255
- i0.ɵɵadvance(3);
256
- i0.ɵɵconditional(ctx_r1.currentError ? 8 : -1);
257
- } }
258
- export class SkipDynamicHTMLReportComponent {
259
- constructor() {
260
- this.HTMLReport = null;
261
- this.ComponentObjectName = null;
262
- this.ShowPrintReport = true;
263
- this.ShowReportOptionsToggle = true;
264
- this.ShowCreateReportButton = false;
265
- this.matchingReportID = null;
266
- this.DrillDownEvent = new EventEmitter();
267
- this.CreateReportRequested = new EventEmitter();
268
- // Properties for handling multiple report options
269
- this.reportOptions = [];
270
- this.selectedReportOptionIndex = 0;
271
- this.currentError = null;
272
- this.isCreatingReport = false;
273
- // Cache for React component hosts - lazy loaded per option
274
- this.reactHostCache = new Map();
275
- this.currentHostIndex = null;
276
- this.callbacks = {
277
- RefreshData: () => this.handleRefreshData(),
278
- OpenEntityRecord: (entityName, key) => this.handleOpenEntityRecord(entityName, key),
279
- UpdateUserState: (userState) => this.handleUpdateUserState(userState),
280
- NotifyEvent: (eventName, eventData) => this.handleNotifyEvent(eventName, eventData)
281
- };
282
- }
283
- /**
284
- * Gets the currently selected report option
285
- */
286
- get selectedReportOption() {
287
- return this.reportOptions.length > this.selectedReportOptionIndex
288
- ? this.reportOptions[this.selectedReportOptionIndex]
289
- : null;
290
- }
291
- /**
292
- * Get tab title for a specific option index
293
- */
294
- getTabTitle(index) {
295
- const option = this.reportOptions[index];
296
- if (!option)
297
- return `report ${index + 1}`;
298
- const componentType = option.option.componentType || 'report';
299
- return `${componentType} ${index + 1}`;
300
- }
301
- /**
302
- * Check if this option is the AI's top recommendation
303
- */
304
- isTopRanked(index) {
305
- const option = this.reportOptions[index];
306
- return (option === null || option === void 0 ? void 0 : option.AIRank) === 1;
307
- }
308
- /**
309
- * Handles when the user selects a tab
310
- */
311
- onTabSelect(event) {
312
- const selectedIndex = event.index;
313
- this.onReportOptionChange(selectedIndex);
314
- }
315
- /**
316
- * Handles when the user changes the selected report option
317
- */
318
- onReportOptionChange(selectedIndex) {
319
- if (selectedIndex >= 0 && selectedIndex < this.reportOptions.length) {
320
- this.selectedReportOptionIndex = selectedIndex;
321
- this.updateCurrentReport();
322
- }
323
- }
324
- /**
325
- * Updates the current report display based on the selected option
326
- */
327
- updateCurrentReport() {
328
- const selectedOption = this.selectedReportOption;
329
- if (!selectedOption)
330
- return;
331
- // Clear any previous error
332
- this.currentError = null;
333
- try {
334
- // Update the component info - this can fail if placeholders are missing
335
- this.HTMLReport = BuildSkipComponentCompleteCode(selectedOption.option);
336
- this.ComponentObjectName = selectedOption.option.componentName;
337
- // Simply create or reuse the React host for this option
338
- // The tab component handles visibility automatically
339
- if (!this.reactHostCache.has(this.selectedReportOptionIndex)) {
340
- // Create a new host for this option
341
- this.createReactHostForOption(this.selectedReportOptionIndex);
342
- }
343
- this.currentHostIndex = this.selectedReportOptionIndex;
344
- }
345
- catch (error) {
346
- console.error('Failed to build component code:', error);
347
- this.currentError = {
348
- type: 'Component Assembly Error',
349
- message: 'Failed to assemble the component code. This usually happens when sub-components are missing or placeholders cannot be resolved.',
350
- technicalDetails: (error === null || error === void 0 ? void 0 : error.toString()) || 'Unknown error during component assembly'
351
- };
352
- // Clear the HTML report to prevent partial rendering
353
- this.HTMLReport = null;
354
- this.ComponentObjectName = null;
355
- }
356
- }
357
- PrintReport() {
358
- return __awaiter(this, void 0, void 0, function* () {
359
- const currentHost = this.getCurrentReactHost();
360
- if (currentHost) {
361
- currentHost.print();
362
- }
363
- else {
364
- window.print();
365
- }
366
- });
367
- }
368
- /**
369
- * Copy error details to clipboard for user to send back to Skip
370
- */
371
- copyErrorToClipboard() {
372
- if (!this.currentError)
373
- return;
374
- const errorText = `Skip Component Error:
375
- Type: ${this.currentError.type}
376
- Message: ${this.currentError.message}
377
- ${this.currentError.technicalDetails ? `\nTechnical Details:\n${this.currentError.technicalDetails}` : ''}
378
-
379
- Component Option: ${this.selectedReportOptionIndex + 1}
380
- Component Name: ${this.ComponentObjectName || 'Unknown'}`;
381
- navigator.clipboard.writeText(errorText).then(() => {
382
- alert('Error details copied to clipboard. You can paste this in the Skip chat to get help.');
383
- }).catch(err => {
384
- console.error('Failed to copy to clipboard:', err);
385
- });
386
- }
387
- /**
388
- * Get the container element for a specific option index
389
- */
390
- getContainerForOption(optionIndex) {
391
- var _a;
392
- if (!this.htmlContainers || this.htmlContainers.length === 0) {
393
- return null;
394
- }
395
- if (this.reportOptions.length === 1) {
396
- // Single option - use the only container
397
- return ((_a = this.htmlContainers.first) === null || _a === void 0 ? void 0 : _a.nativeElement) || null;
398
- }
399
- else {
400
- // Multiple options - find container by data-tab-index
401
- const container = this.htmlContainers.find(ref => ref.nativeElement.getAttribute('data-tab-index') === optionIndex.toString());
402
- return (container === null || container === void 0 ? void 0 : container.nativeElement) || null;
403
- }
404
- }
405
- /**
406
- * Retry loading the current option
407
- */
408
- retryCurrentOption() {
409
- // Clear the error
410
- this.currentError = null;
411
- // Remove the cached host for this option to force recreation
412
- if (this.reactHostCache.has(this.selectedReportOptionIndex)) {
413
- const host = this.reactHostCache.get(this.selectedReportOptionIndex);
414
- if (host) {
415
- host.destroy();
416
- }
417
- this.reactHostCache.delete(this.selectedReportOptionIndex);
418
- }
419
- // Try creating it again
420
- this.createReactHostForOption(this.selectedReportOptionIndex);
421
- }
422
- /**
423
- * Handle create report request for a specific option
424
- */
425
- createReportForOption(optionIndex) {
426
- this.isCreatingReport = true;
427
- // Emit the event with the option index so the parent can handle it
428
- this.CreateReportRequested.emit(optionIndex);
429
- }
430
- ngAfterViewInit() {
431
- if (this.SkipData) {
432
- this.setupReportOptions(this.SkipData);
433
- }
434
- // Wait for ViewChildren to be available
435
- setTimeout(() => {
436
- if (this.HTMLReport && this.ComponentObjectName && this.SkipData) {
437
- // Create the initial React host for the first option
438
- this.createReactHostForOption(this.selectedReportOptionIndex);
439
- }
440
- });
441
- }
442
- ngOnDestroy() {
443
- // Clean up all cached React hosts
444
- this.reactHostCache.forEach(host => {
445
- try {
446
- host.destroy();
447
- }
448
- catch (e) {
449
- console.error('Error destroying React host:', e);
450
- }
451
- });
452
- this.reactHostCache.clear();
453
- }
454
- ngOnChanges(changes) {
455
- if (changes['SkipData'] && !changes['SkipData'].firstChange) {
456
- // Update all cached React components with new data
457
- const newData = this.getFlattenedDataContext();
458
- this.reactHostCache.forEach(host => {
459
- try {
460
- host.updateState('data', newData);
461
- }
462
- catch (e) {
463
- console.error('Error updating React host data:', e);
464
- }
465
- });
466
- }
467
- }
468
- /**
469
- * Get the currently active React host
470
- */
471
- getCurrentReactHost() {
472
- if (this.currentHostIndex !== null && this.reactHostCache.has(this.currentHostIndex)) {
473
- return this.reactHostCache.get(this.currentHostIndex) || null;
474
- }
475
- return null;
476
- }
477
- get SkipData() {
478
- return this._skipData ? this._skipData : undefined;
479
- }
480
- set SkipData(d) {
481
- const hadData = this._skipData ? true : false;
482
- this._skipData = d;
483
- if (d) {
484
- // For backward compatibility, check if we have component options
485
- if (d.componentOptions && d.componentOptions.length > 0) {
486
- // Use the first component option (or the highest ranked one)
487
- const component = d.componentOptions[0];
488
- this.HTMLReport = BuildSkipComponentCompleteCode(component.option);
489
- this.ComponentObjectName = component.option.componentName;
490
- }
491
- else {
492
- // Fallback for old format
493
- this.HTMLReport = d.htmlReport;
494
- this.ComponentObjectName = d.htmlReportObjectName;
495
- }
496
- }
497
- if (d && hadData) {
498
- // Update the current display with new data
499
- this.updateCurrentReport();
500
- }
501
- }
502
- /**
503
- * Sets up the report options from the SkipData, prioritizing the new htmlReportOptions array
504
- * but falling back to the deprecated htmlReport/htmlReportObjectName for backward compatibility
505
- */
506
- setupReportOptions(data) {
507
- // Check if we have the new htmlReportOptions array
508
- if (data.componentOptions && data.componentOptions.length > 0) {
509
- // Sort by AIRank (lower numbers = better ranking)
510
- this.reportOptions = [...data.componentOptions].sort((a, b) => {
511
- var _a, _b;
512
- const rankA = (_a = a.AIRank) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER;
513
- const rankB = (_b = b.AIRank) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER;
514
- return rankA - rankB;
515
- });
516
- // Select the best option (first in sorted array)
517
- this.selectedReportOptionIndex = 0;
518
- const bestOption = this.reportOptions[0];
519
- this.HTMLReport = BuildSkipComponentCompleteCode(bestOption.option);
520
- this.ComponentObjectName = bestOption.option.componentName;
521
- }
522
- }
523
- /**
524
- * Create a React host for a specific option index
525
- */
526
- createReactHostForOption(optionIndex) {
527
- return __awaiter(this, void 0, void 0, function* () {
528
- var _a, _b, _c;
529
- const option = this.reportOptions[optionIndex];
530
- if (!option)
531
- return;
532
- const container = this.getContainerForOption(optionIndex);
533
- if (!container)
534
- return;
535
- try {
536
- const componentCode = BuildSkipComponentCompleteCode(option.option);
537
- // Check for unresolved placeholders in the code
538
- if (componentCode.includes('<<') && componentCode.includes('>>')) {
539
- const placeholderMatch = componentCode.match(/<<([^>]+)>>/);
540
- const placeholderName = placeholderMatch ? placeholderMatch[1] : 'Unknown';
541
- this.currentError = {
542
- type: 'Incomplete Component',
543
- message: `This component option contains unresolved placeholders (${placeholderName}). The component generation was not completed successfully.`,
544
- technicalDetails: `The component code contains placeholder tokens that should have been replaced with actual implementations. This typically happens when the AI generation process was interrupted or encountered an error.\n\nPlaceholder found: <<${placeholderName}>>`
545
- };
546
- return;
547
- }
548
- const md = new Metadata();
549
- const data = this.getFlattenedDataContext();
550
- // Create the React component host directly in the tab container
551
- const reactHost = new SkipReactComponentHost({
552
- componentCode: componentCode,
553
- container: container,
554
- callbacks: this.callbacks,
555
- data: data,
556
- utilities: this.SetupUtilities(md),
557
- styles: this.SetupStyles()
558
- });
559
- // Initialize and render the React component
560
- yield reactHost.initialize();
561
- // Cache the host
562
- this.reactHostCache.set(optionIndex, reactHost);
563
- // Update current index if this is the selected option
564
- if (optionIndex === this.selectedReportOptionIndex) {
565
- this.currentHostIndex = optionIndex;
566
- }
567
- }
568
- catch (e) {
569
- console.error('Error creating React host:', e);
570
- // Determine the type of error and create a user-friendly message
571
- let errorType = 'Component Initialization Error';
572
- let errorMessage = 'Failed to initialize the React component.';
573
- let technicalDetails = e.toString();
574
- if ((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes('JSX transpilation failed')) {
575
- errorType = 'Code Compilation Error';
576
- errorMessage = 'The component code could not be compiled. This usually indicates a syntax error in the generated code.';
577
- technicalDetails = e.message;
578
- }
579
- else if ((_b = e.message) === null || _b === void 0 ? void 0 : _b.includes('is not defined')) {
580
- errorType = 'Missing Dependency';
581
- errorMessage = 'The component is trying to use a feature or library that is not available.';
582
- }
583
- else if ((_c = e.message) === null || _c === void 0 ? void 0 : _c.includes('Cannot read properties')) {
584
- errorType = 'Property Access Error';
585
- errorMessage = 'The component is trying to access data that doesn\'t exist. This often happens when property names don\'t match the data structure.';
586
- }
587
- this.currentError = {
588
- type: errorType,
589
- message: errorMessage,
590
- technicalDetails: technicalDetails + '\n\nComponent Option: ' + (optionIndex + 1) + '\nComponent Name: ' + option.option.componentName
591
- };
592
- LogError(e);
593
- }
594
- });
595
- }
596
- getFlattenedDataContext() {
597
- var _a;
598
- const flattenedDataContext = {};
599
- if ((_a = this.SkipData) === null || _a === void 0 ? void 0 : _a.dataContext) {
600
- const loadedItems = this.SkipData.dataContext.Items.filter((i) => { var _a; return i.DataLoaded && ((_a = i._Data) === null || _a === void 0 ? void 0 : _a.length) > 0; });
601
- for (let i = 0; i < loadedItems.length; i++) {
602
- flattenedDataContext["data_item_" + i] = loadedItems[i]._Data;
603
- }
604
- }
605
- return flattenedDataContext;
606
- }
607
- // Event handler implementations
608
- handleRefreshData() {
609
- console.log('Component requested data refresh');
610
- // Emit an event or call parent component method to refresh data
611
- }
612
- handleOpenEntityRecord(entityName, key) {
613
- if (entityName) {
614
- // bubble this up to our parent component as we don't directly open records in this component
615
- const md = new Metadata();
616
- const entityMatch = md.EntityByName(entityName);
617
- if (!entityMatch) {
618
- // couldn't find it, but sometimes the AI uses a table name or a view name, let's check for that
619
- const altMatch = md.Entities.filter(e => e.BaseTable.toLowerCase() === entityName.toLowerCase() ||
620
- e.BaseView.toLowerCase() === entityName.toLowerCase() ||
621
- e.SchemaName.toLowerCase() + '.' + e.BaseTable.toLowerCase() === entityName.toLowerCase() ||
622
- e.SchemaName.toLowerCase() + '.' + e.BaseView.toLowerCase() === entityName.toLowerCase());
623
- if (altMatch && altMatch.length === 1) {
624
- entityName = altMatch[0].Name;
625
- }
626
- }
627
- const cKey = new CompositeKey(key);
628
- this.DrillDownEvent.emit(new DrillDownInfo(entityName, cKey.ToWhereClause()));
629
- }
630
- }
631
- handleUpdateUserState(userState) {
632
- console.log('Component updated user state:', userState);
633
- // TODO: Implement user state persistence if needed
634
- }
635
- handleNotifyEvent(eventName, eventData) {
636
- var _a;
637
- console.log(`Component raised event: ${eventName} notified with data:`, eventData);
638
- // Handle component errors from React host
639
- if (eventName === 'componentError') {
640
- this.currentError = {
641
- type: eventData.source || 'React Component Error',
642
- message: eventData.error || 'An unknown error occurred in the React component',
643
- technicalDetails: eventData.stackTrace || ((_a = eventData.errorInfo) === null || _a === void 0 ? void 0 : _a.componentStack) || ''
644
- };
645
- }
646
- // TODO: Handle other custom events as needed
647
- }
648
- SetupUtilities(md) {
649
- const rv = new RunView();
650
- const rq = new RunQuery();
651
- const u = {
652
- md: this.CreateSimpleMetadata(md),
653
- rv: this.CreateSimpleRunView(rv),
654
- rq: this.CreateSimpleRunQuery(rq)
655
- };
656
- return u;
657
- }
658
- CreateSimpleMetadata(md) {
659
- return {
660
- entities: md.Entities.map(e => MapEntityInfoToSkipEntityInfo(e))
661
- };
662
- }
663
- SetupStyles() {
664
- // Return modern, contemporary styles for generated components
665
- return {
666
- colors: {
667
- // Primary colors - modern purple/blue gradient feel
668
- primary: '#5B4FE9',
669
- primaryHover: '#4940D4',
670
- primaryLight: '#E8E6FF',
671
- // Secondary colors - sophisticated gray
672
- secondary: '#64748B',
673
- secondaryHover: '#475569',
674
- // Status colors
675
- success: '#10B981',
676
- successLight: '#D1FAE5',
677
- warning: '#F59E0B',
678
- warningLight: '#FEF3C7',
679
- error: '#EF4444',
680
- errorLight: '#FEE2E2',
681
- info: '#3B82F6',
682
- infoLight: '#DBEAFE',
683
- // Base colors
684
- background: '#FFFFFF',
685
- surface: '#F8FAFC',
686
- surfaceHover: '#F1F5F9',
687
- // Text colors with better contrast
688
- text: '#1E293B',
689
- textSecondary: '#64748B',
690
- textTertiary: '#94A3B8',
691
- textInverse: '#FFFFFF',
692
- // Border colors
693
- border: '#E2E8F0',
694
- borderLight: '#F1F5F9',
695
- borderFocus: '#5B4FE9',
696
- // Shadows (as color strings for easy use)
697
- shadow: 'rgba(0, 0, 0, 0.05)',
698
- shadowMedium: 'rgba(0, 0, 0, 0.1)',
699
- shadowLarge: 'rgba(0, 0, 0, 0.15)',
700
- },
701
- spacing: {
702
- xs: '4px',
703
- sm: '8px',
704
- md: '16px',
705
- lg: '24px',
706
- xl: '32px',
707
- xxl: '48px',
708
- xxxl: '64px',
709
- },
710
- typography: {
711
- fontFamily: '-apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif',
712
- fontSize: {
713
- xs: '11px',
714
- sm: '12px',
715
- md: '14px',
716
- lg: '16px',
717
- xl: '20px',
718
- xxl: '24px',
719
- xxxl: '32px',
720
- },
721
- fontWeight: {
722
- light: '300',
723
- regular: '400',
724
- medium: '500',
725
- semibold: '600',
726
- bold: '700',
727
- },
728
- lineHeight: {
729
- tight: '1.25',
730
- normal: '1.5',
731
- relaxed: '1.75',
732
- },
733
- },
734
- borders: {
735
- radius: {
736
- sm: '6px',
737
- md: '8px',
738
- lg: '12px',
739
- xl: '16px',
740
- full: '9999px',
741
- },
742
- width: {
743
- thin: '1px',
744
- medium: '2px',
745
- thick: '3px',
746
- },
747
- },
748
- shadows: {
749
- sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
750
- md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
751
- lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
752
- xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
753
- inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
754
- },
755
- transitions: {
756
- fast: '150ms ease-in-out',
757
- normal: '250ms ease-in-out',
758
- slow: '350ms ease-in-out',
759
- },
760
- overflow: 'auto' // Default overflow style
761
- };
762
- }
763
- CreateSimpleRunQuery(rq) {
764
- return {
765
- runQuery: (params) => __awaiter(this, void 0, void 0, function* () {
766
- // Run a single query and return the results
767
- try {
768
- const result = yield rq.RunQuery(params);
769
- return result;
770
- }
771
- catch (error) {
772
- LogError(error);
773
- throw error; // Re-throw to handle it in the caller
774
- }
775
- })
776
- };
777
- }
778
- CreateSimpleRunView(rv) {
779
- return {
780
- runView: (params) => __awaiter(this, void 0, void 0, function* () {
781
- // Run a single view and return the results
782
- try {
783
- const result = yield rv.RunView(params);
784
- return result;
785
- }
786
- catch (error) {
787
- LogError(error);
788
- throw error; // Re-throw to handle it in the caller
789
- }
790
- }),
791
- runViews: (params) => __awaiter(this, void 0, void 0, function* () {
792
- // Runs multiple views and returns the results
793
- try {
794
- const results = yield rv.RunViews(params);
795
- return results;
796
- }
797
- catch (error) {
798
- LogError(error);
799
- throw error; // Re-throw to handle it in the caller
800
- }
801
- })
802
- };
803
- }
804
- SetupCallbacks() {
805
- const cb = {
806
- RefreshData: () => {
807
- // this is a callback function that can be called from the component to refresh data
808
- console.log('Component requested data refresh');
809
- // need to implement this
810
- },
811
- OpenEntityRecord: (entityName, key) => {
812
- // this is a callback function that can be called from the component to open an entity record
813
- if (entityName) {
814
- // bubble this up to our parent component as we don't directly open records in this component
815
- const md = new Metadata();
816
- const entityMatch = md.EntityByName(entityName);
817
- if (!entityMatch) {
818
- // couldn't find it, but sometimes the AI uses a table name or a view name, let's check for that
819
- const altMatch = md.Entities.filter(e => e.BaseTable.toLowerCase() === entityName.toLowerCase() ||
820
- e.BaseView.toLowerCase() === entityName.toLowerCase() ||
821
- e.SchemaName.toLowerCase() + '.' + e.BaseTable.toLowerCase() === entityName.toLowerCase() ||
822
- e.SchemaName.toLowerCase() + '.' + e.BaseView.toLowerCase() === entityName.toLowerCase());
823
- if (altMatch && altMatch.length === 1) {
824
- entityName = altMatch[0].Name;
825
- }
826
- }
827
- const cKey = new CompositeKey(key);
828
- this.DrillDownEvent.emit(new DrillDownInfo(entityName, cKey.ToWhereClause()));
829
- }
830
- },
831
- UpdateUserState: (userState) => {
832
- // this is a callback function that can be called from the component to update user state
833
- console.log('Component updated user state:', userState);
834
- // need to implement this
835
- },
836
- NotifyEvent: (eventName, eventData) => {
837
- // this is a callback function that can be called from the component to notify an event
838
- console.log(`Component raised event: ${eventName} notified with data:`, eventData);
839
- }
840
- };
841
- return cb;
842
- }
843
- refreshReport(data) {
844
- return __awaiter(this, void 0, void 0, function* () {
845
- const currentHost = this.getCurrentReactHost();
846
- if (currentHost) {
847
- currentHost.refresh(data);
848
- }
849
- else {
850
- // If no React host is available, create one for the current option
851
- this.createReactHostForOption(this.selectedReportOptionIndex);
852
- }
853
- });
854
- }
855
- }
856
- SkipDynamicHTMLReportComponent.ɵfac = function SkipDynamicHTMLReportComponent_Factory(t) { return new (t || SkipDynamicHTMLReportComponent)(); };
857
- SkipDynamicHTMLReportComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SkipDynamicHTMLReportComponent, selectors: [["skip-dynamic-html-report"]], viewQuery: function SkipDynamicHTMLReportComponent_Query(rf, ctx) { if (rf & 1) {
858
- i0.ɵɵviewQuery(_c0, 5);
859
- } if (rf & 2) {
860
- let _t;
861
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.htmlContainers = _t);
862
- } }, inputs: { HTMLReport: "HTMLReport", ComponentObjectName: "ComponentObjectName", ShowPrintReport: "ShowPrintReport", ShowReportOptionsToggle: "ShowReportOptionsToggle", ShowCreateReportButton: "ShowCreateReportButton", matchingReportID: "matchingReportID", SkipData: "SkipData" }, outputs: { DrillDownEvent: "DrillDownEvent", CreateReportRequested: "CreateReportRequested" }, features: [i0.ɵɵNgOnChangesFeature], decls: 2, vars: 1, consts: [["htmlContainer", ""], [2, "height", "100%", "display", "flex", "flex-direction", "column", 3, "keepTabContent"], [2, "height", "100%", "display", "flex", "flex-direction", "column"], [2, "height", "100%", "display", "flex", "flex-direction", "column", 3, "tabSelect", "keepTabContent"], [3, "selected"], ["kendoTabTitle", ""], ["kendoTabContent", ""], [1, "fa-solid", "fa-star", "star-icon"], [1, "tab-action-bar"], [1, "tab-actions-left"], [1, "tab-actions-right"], ["class", "tab-action-button create-button", 3, "disabled", "click", 4, "ngIf"], ["class", "tab-action-button print-button", "title", "Print Report", 3, "click", 4, "ngIf"], [2, "flex", "1", "position", "relative", "min-height", "0"], [2, "top", "0", "left", "0", "right", "0", "bottom", "0", "display", "flex", "align-items", "flex-start", "justify-content", "center", "padding-top", "20px", "background", "rgba(255, 255, 255, 0.95)", "z-index", "10"], [1, "tab-action-button", "create-button", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"], ["title", "Print Report", 1, "tab-action-button", "print-button", 3, "click"], [1, "fa-solid", "fa-print"], [2, "width", "90%", "max-width", "600px", "height", "500px", "background-color", "#f8f9fa", "border", "2px solid #dc3545", "border-radius", "8px", "padding", "20px", "overflow-y", "auto", "box-shadow", "0 4px 6px rgba(0, 0, 0, 0.1)"], [2, "position", "relative"], ["kendoButton", "", 2, "position", "absolute", "top", "0", "right", "0", "font-size", "12px", 3, "click"], [1, "fa-solid", "fa-copy"], [2, "color", "#dc3545", "margin-top", "0", "margin-right", "150px", "font-size", "18px"], [1, "fa-solid", "fa-exclamation-triangle"], [2, "margin-bottom", "10px", "font-size", "14px"], [2, "background-color", "#fff", "border", "1px solid #dee2e6", "border-radius", "4px", "padding", "12px", "margin-bottom", "12px", "font-family", "'Courier New', monospace", "font-size", "12px"], [2, "margin-top", "8px"], [2, "background-color", "#e7f3ff", "border", "1px solid #b3d9ff", "border-radius", "4px", "padding", "12px", "margin-bottom", "12px"], [2, "font-size", "14px"], [2, "margin", "8px 0 0 20px", "padding", "0", "font-size", "13px"], ["kendoButton", "", 2, "font-size", "13px", 3, "click"], [1, "fa-solid", "fa-rotate"], [2, "cursor", "pointer", "color", "#0056b3"], [2, "margin-top", "8px", "white-space", "pre-wrap", "word-break", "break-word", "font-size", "11px"], [2, "position", "absolute", "top", "0", "left", "0", "right", "0", "bottom", "0", "display", "flex", "align-items", "flex-start", "justify-content", "center", "padding-top", "20px", "background", "rgba(255, 255, 255, 0.95)", "z-index", "10"]], template: function SkipDynamicHTMLReportComponent_Template(rf, ctx) { if (rf & 1) {
863
- i0.ɵɵtemplate(0, SkipDynamicHTMLReportComponent_Conditional_0_Template, 3, 1, "kendo-tabstrip", 1)(1, SkipDynamicHTMLReportComponent_Conditional_1_Template, 9, 3, "div", 2);
864
- } if (rf & 2) {
865
- i0.ɵɵconditional(ctx.reportOptions.length > 1 ? 0 : 1);
866
- } }, dependencies: [i1.NgIf, i2.TabStripComponent, i2.TabStripTabComponent, i2.TabContentDirective, i2.TabTitleDirective, i3.ButtonComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n position: relative;\n }\n \n \n\n .tab-action-bar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n background-color: #fafafa;\n border-bottom: 1px solid #e0e0e0;\n }\n \n .tab-actions-left[_ngcontent-%COMP%], \n .tab-actions-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n \n \n\n .tab-action-button[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n background-color: transparent;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n transition: all 0.15s ease;\n white-space: nowrap;\n }\n \n .tab-action-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: #f5f5f5;\n border-color: #d0d0d0;\n }\n \n .tab-action-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n \n .tab-action-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n \n \n\n .tab-action-button.create-button[_ngcontent-%COMP%], \n .tab-action-button.print-button[_ngcontent-%COMP%] {\n background-color: white;\n color: #333;\n border-color: #e0e0e0;\n }\n \n .tab-action-button.create-button[_ngcontent-%COMP%]:hover:not(:disabled), \n .tab-action-button.print-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: #f5f5f5;\n border-color: #d0d0d0;\n }\n \n \n\n .k-tabstrip {\n border: none;\n height: 100%;\n display: flex;\n flex-direction: column;\n margin: 10px 5px 5px 5px;\n }\n \n .k-tabstrip-items {\n background: #f8f9fa;\n border: none;\n border-radius: 8px 8px 0 0;\n flex: 0 0 auto;\n padding: 8px 12px 0 12px;\n gap: 4px;\n display: flex;\n }\n \n .k-tabstrip-items-wrapper {\n height: 100%;\n }\n \n .k-content {\n flex: 1;\n overflow: hidden;\n padding: 0;\n background: white;\n border: 1px solid #e0e0e0;\n border-top: none;\n border-radius: 0 0 8px 8px;\n }\n \n .k-tabstrip .k-item {\n margin-right: 2px;\n border: none;\n background: transparent;\n border-radius: 6px 6px 0 0;\n padding: 2px;\n transition: all 0.2s ease;\n }\n \n .k-tabstrip .k-item.k-selected {\n background: white;\n border: 1px solid #e0e0e0;\n border-bottom: 1px solid white;\n margin-bottom: -1px;\n z-index: 1;\n }\n \n .k-tabstrip .k-link {\n padding: 8px 16px;\n font-weight: 500;\n font-size: 13px;\n color: #666;\n transition: all 0.15s ease;\n border-radius: 4px 4px 0 0;\n background: transparent;\n border: none;\n text-transform: lowercase;\n }\n \n .k-tabstrip .k-link:first-letter {\n text-transform: uppercase;\n }\n \n .k-tabstrip .k-item:hover:not(.k-selected) .k-link {\n color: #333;\n background: rgba(0, 0, 0, 0.04);\n }\n \n .k-tabstrip .k-item.k-selected .k-link {\n color: #1976d2;\n font-weight: 600;\n background: white;\n }\n \n \n\n .k-tabstrip .k-link .star-icon {\n display: inline-block;\n margin-right: 4px;\n color: #ffd700;\n font-size: 12px;\n vertical-align: middle;\n }\n \n \n\n .k-tabstrip-items::before, \n .k-tabstrip-items::after {\n display: none;\n }\n \n .k-tabstrip .k-item::before, \n .k-tabstrip .k-item::after {\n display: none;\n }\n \n \n\n .k-tabstrip .k-link:focus {\n outline: none;\n box-shadow: none;\n }\n \n \n\n .k-tabstrip .k-content.k-state-active {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n \n \n\n .react-host-container[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n }"] });
867
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SkipDynamicHTMLReportComponent, [{
868
- type: Component,
869
- args: [{ selector: 'skip-dynamic-html-report', template: `
870
- @if (reportOptions.length > 1) {
871
- <!-- Multiple options: show tabs -->
872
- <kendo-tabstrip
873
- (tabSelect)="onTabSelect($event)"
874
- [keepTabContent]="true"
875
- style="height: 100%; display: flex; flex-direction: column;">
876
- @for (option of reportOptions; track option; let i = $index) {
877
- <kendo-tabstrip-tab [selected]="i === selectedReportOptionIndex">
878
- <ng-template kendoTabTitle>
879
- @if (isTopRanked(i)) {
880
- <i class="fa-solid fa-star star-icon"></i>
881
- }
882
- {{ getTabTitle(i) }}
883
- </ng-template>
884
- <ng-template kendoTabContent>
885
- <div style="height: 100%; display: flex; flex-direction: column;">
886
- <!-- Tab Action Bar -->
887
- <div class="tab-action-bar">
888
- <div class="tab-actions-left">
889
- <!-- Space for future left-aligned actions -->
890
- </div>
891
- <div class="tab-actions-right">
892
- <button class="tab-action-button create-button"
893
- *ngIf="ShowCreateReportButton && !matchingReportID"
894
- (click)="createReportForOption(i)"
895
- [disabled]="isCreatingReport">
896
- <i class="fa-solid fa-plus"></i>
897
- <span>Create Report</span>
898
- </button>
899
- <button class="tab-action-button print-button"
900
- *ngIf="ShowPrintReport"
901
- (click)="PrintReport()"
902
- title="Print Report">
903
- <i class="fa-solid fa-print"></i>
904
- <span>Print Report</span>
905
- </button>
906
- </div>
907
- </div>
908
-
909
- <!-- React component container -->
910
- <div #htmlContainer [attr.data-tab-index]="i"
911
- style="flex: 1; position: relative; min-height: 0;">
912
- <!-- Content will be rendered here by React host -->
913
-
914
- <!-- Error overlay for this tab (shown on top of content when needed) -->
915
- @if (currentError && selectedReportOptionIndex === i) {
916
- <div style="top: 0;
917
- left: 0;
918
- right: 0;
919
- bottom: 0;
920
- display: flex;
921
- align-items: flex-start;
922
- justify-content: center;
923
- padding-top: 20px;
924
- background: rgba(255, 255, 255, 0.95);
925
- z-index: 10;">
926
- <div style="width: 90%;
927
- max-width: 600px;
928
- height: 500px;
929
- background-color: #f8f9fa;
930
- border: 2px solid #dc3545;
931
- border-radius: 8px;
932
- padding: 20px;
933
- overflow-y: auto;
934
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);">
935
- <div style="position: relative;">
936
- <button kendoButton (click)="copyErrorToClipboard()"
937
- style="position: absolute; top: 0; right: 0; font-size: 12px;">
938
- <span class="fa-solid fa-copy"></span>
939
- Copy Error Details
940
- </button>
941
- <h3 style="color: #dc3545; margin-top: 0; margin-right: 150px; font-size: 18px;">
942
- <span class="fa-solid fa-exclamation-triangle"></span>
943
- Component Rendering Error
944
- </h3>
945
- </div>
946
- <p style="margin-bottom: 10px; font-size: 14px;">
947
- The selected component option could not be rendered due to the following error:
948
- </p>
949
- <div style="background-color: #fff; border: 1px solid #dee2e6;
950
- border-radius: 4px; padding: 12px; margin-bottom: 12px;
951
- font-family: 'Courier New', monospace; font-size: 12px;">
952
- <strong>Error Type:</strong> {{ currentError.type }}<br>
953
- <strong>Details:</strong> {{ currentError.message }}
954
- @if (currentError.technicalDetails) {
955
- <details style="margin-top: 8px;">
956
- <summary style="cursor: pointer; color: #0056b3;">Technical Details (click to expand)</summary>
957
- <pre style="margin-top: 8px; white-space: pre-wrap; word-break: break-word; font-size: 11px;">{{ currentError.technicalDetails }}</pre>
958
- </details>
959
- }
960
- </div>
961
- <div style="background-color: #e7f3ff; border: 1px solid #b3d9ff;
962
- border-radius: 4px; padding: 12px; margin-bottom: 12px;">
963
- <strong style="font-size: 14px;">What to do:</strong>
964
- <ol style="margin: 8px 0 0 20px; padding: 0; font-size: 13px;">
965
- <li>Try selecting a different report option from the tabs above</li>
966
- <li>Copy the error details and send them back to Skip in the chat to get a corrected version</li>
967
- <li>Contact your IT department if the issue persists</li>
968
- </ol>
969
- </div>
970
- <button kendoButton (click)="retryCurrentOption()" style="font-size: 13px;">
971
- <span class="fa-solid fa-rotate"></span>
972
- Retry
973
- </button>
974
- </div>
975
- </div>
976
- }
977
- </div>
978
- </div>
979
- </ng-template>
980
- </kendo-tabstrip-tab>
981
- }
982
- </kendo-tabstrip>
983
- } @else {
984
- <!-- Single option: no tabs needed -->
985
- <div style="height: 100%; display: flex; flex-direction: column;">
986
- <!-- Tab Action Bar -->
987
- <div class="tab-action-bar">
988
- <div class="tab-actions-left">
989
- <!-- Space for future left-aligned actions -->
990
- </div>
991
- <div class="tab-actions-right">
992
- <button class="tab-action-button create-button"
993
- *ngIf="ShowCreateReportButton && !matchingReportID"
994
- (click)="createReportForOption(0)"
995
- [disabled]="isCreatingReport">
996
- <i class="fa-solid fa-plus"></i>
997
- <span>Create Report</span>
998
- </button>
999
- <button class="tab-action-button print-button"
1000
- *ngIf="ShowPrintReport"
1001
- (click)="PrintReport()"
1002
- title="Print Report">
1003
- <i class="fa-solid fa-print"></i>
1004
- <span>Print Report</span>
1005
- </button>
1006
- </div>
1007
- </div>
1008
-
1009
- <!-- React component container -->
1010
- <div #htmlContainer style="flex: 1; position: relative; min-height: 0;">
1011
- <!-- Content will be rendered here by React host -->
1012
-
1013
- <!-- Error overlay (shown on top of content when needed) -->
1014
- @if (currentError) {
1015
- <div style="position: absolute;
1016
- top: 0;
1017
- left: 0;
1018
- right: 0;
1019
- bottom: 0;
1020
- display: flex;
1021
- align-items: flex-start;
1022
- justify-content: center;
1023
- padding-top: 20px;
1024
- background: rgba(255, 255, 255, 0.95);
1025
- z-index: 10;">
1026
- <div style="width: 90%;
1027
- max-width: 600px;
1028
- height: 500px;
1029
- background-color: #f8f9fa;
1030
- border: 2px solid #dc3545;
1031
- border-radius: 8px;
1032
- padding: 20px;
1033
- overflow-y: auto;
1034
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);">
1035
- <div style="position: relative;">
1036
- <button kendoButton (click)="copyErrorToClipboard()"
1037
- style="position: absolute; top: 0; right: 0; font-size: 12px;">
1038
- <span class="fa-solid fa-copy"></span>
1039
- Copy Error Details
1040
- </button>
1041
- <h3 style="color: #dc3545; margin-top: 0; margin-right: 150px; font-size: 18px;">
1042
- <span class="fa-solid fa-exclamation-triangle"></span>
1043
- Component Rendering Error
1044
- </h3>
1045
- </div>
1046
- <p style="margin-bottom: 10px; font-size: 14px;">
1047
- The selected component option could not be rendered due to the following error:
1048
- </p>
1049
- <div style="background-color: #fff; border: 1px solid #dee2e6;
1050
- border-radius: 4px; padding: 12px; margin-bottom: 12px;
1051
- font-family: 'Courier New', monospace; font-size: 12px;">
1052
- <strong>Error Type:</strong> {{ currentError.type }}<br>
1053
- <strong>Details:</strong> {{ currentError.message }}
1054
- @if (currentError.technicalDetails) {
1055
- <details style="margin-top: 8px;">
1056
- <summary style="cursor: pointer; color: #0056b3;">Technical Details (click to expand)</summary>
1057
- <pre style="margin-top: 8px; white-space: pre-wrap; word-break: break-word; font-size: 11px;">{{ currentError.technicalDetails }}</pre>
1058
- </details>
1059
- }
1060
- </div>
1061
- <div style="background-color: #e7f3ff; border: 1px solid #b3d9ff;
1062
- border-radius: 4px; padding: 12px; margin-bottom: 12px;">
1063
- <strong style="font-size: 14px;">What to do:</strong>
1064
- <ol style="margin: 8px 0 0 20px; padding: 0; font-size: 13px;">
1065
- <li>Copy the error details and send them back to Skip in the chat to get a corrected version</li>
1066
- <li>Contact your IT department if the issue persists</li>
1067
- </ol>
1068
- </div>
1069
- <button kendoButton (click)="retryCurrentOption()" style="font-size: 13px;">
1070
- <span class="fa-solid fa-rotate"></span>
1071
- Retry
1072
- </button>
1073
- </div>
1074
- </div>
1075
- }
1076
- </div>
1077
- </div>
1078
- }
1079
-
1080
- `, styles: ["\n :host {\n display: block;\n height: 100%;\n position: relative;\n }\n \n /* Tab Action Bar */\n .tab-action-bar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n background-color: #fafafa;\n border-bottom: 1px solid #e0e0e0;\n }\n \n .tab-actions-left,\n .tab-actions-right {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n \n /* Tab Action Buttons */\n .tab-action-button {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n background-color: transparent;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n transition: all 0.15s ease;\n white-space: nowrap;\n }\n \n .tab-action-button:hover:not(:disabled) {\n background-color: #f5f5f5;\n border-color: #d0d0d0;\n }\n \n .tab-action-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n \n .tab-action-button i {\n font-size: 12px;\n }\n \n /* Both buttons use the same white/secondary style */\n .tab-action-button.create-button,\n .tab-action-button.print-button {\n background-color: white;\n color: #333;\n border-color: #e0e0e0;\n }\n \n .tab-action-button.create-button:hover:not(:disabled),\n .tab-action-button.print-button:hover:not(:disabled) {\n background-color: #f5f5f5;\n border-color: #d0d0d0;\n }\n \n /* Tab styling */\n ::ng-deep .k-tabstrip {\n border: none;\n height: 100%;\n display: flex;\n flex-direction: column;\n margin: 10px 5px 5px 5px;\n }\n \n ::ng-deep .k-tabstrip-items {\n background: #f8f9fa;\n border: none;\n border-radius: 8px 8px 0 0;\n flex: 0 0 auto;\n padding: 8px 12px 0 12px;\n gap: 4px;\n display: flex;\n }\n \n ::ng-deep .k-tabstrip-items-wrapper {\n height: 100%;\n }\n \n ::ng-deep .k-content {\n flex: 1;\n overflow: hidden;\n padding: 0;\n background: white;\n border: 1px solid #e0e0e0;\n border-top: none;\n border-radius: 0 0 8px 8px;\n }\n \n ::ng-deep .k-tabstrip .k-item {\n margin-right: 2px;\n border: none;\n background: transparent;\n border-radius: 6px 6px 0 0;\n padding: 2px;\n transition: all 0.2s ease;\n }\n \n ::ng-deep .k-tabstrip .k-item.k-selected {\n background: white;\n border: 1px solid #e0e0e0;\n border-bottom: 1px solid white;\n margin-bottom: -1px;\n z-index: 1;\n }\n \n ::ng-deep .k-tabstrip .k-link {\n padding: 8px 16px;\n font-weight: 500;\n font-size: 13px;\n color: #666;\n transition: all 0.15s ease;\n border-radius: 4px 4px 0 0;\n background: transparent;\n border: none;\n text-transform: lowercase;\n }\n \n ::ng-deep .k-tabstrip .k-link:first-letter {\n text-transform: uppercase;\n }\n \n ::ng-deep .k-tabstrip .k-item:hover:not(.k-selected) .k-link {\n color: #333;\n background: rgba(0, 0, 0, 0.04);\n }\n \n ::ng-deep .k-tabstrip .k-item.k-selected .k-link {\n color: #1976d2;\n font-weight: 600;\n background: white;\n }\n \n /* Star icon styling */\n ::ng-deep .k-tabstrip .k-link .star-icon {\n display: inline-block;\n margin-right: 4px;\n color: #ffd700;\n font-size: 12px;\n vertical-align: middle;\n }\n \n /* Hide default Kendo tab styling */\n ::ng-deep .k-tabstrip-items::before,\n ::ng-deep .k-tabstrip-items::after {\n display: none;\n }\n \n ::ng-deep .k-tabstrip .k-item::before,\n ::ng-deep .k-tabstrip .k-item::after {\n display: none;\n }\n \n /* Remove focus outline */\n ::ng-deep .k-tabstrip .k-link:focus {\n outline: none;\n box-shadow: none;\n }\n \n /* Make sure tab content fills available space */\n ::ng-deep .k-tabstrip .k-content.k-state-active {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n \n /* React host container */\n .react-host-container {\n width: 100%;\n height: 100%;\n }\n "] }]
1081
- }], () => [], { HTMLReport: [{
1082
- type: Input
1083
- }], ComponentObjectName: [{
1084
- type: Input
1085
- }], ShowPrintReport: [{
1086
- type: Input
1087
- }], ShowReportOptionsToggle: [{
1088
- type: Input
1089
- }], ShowCreateReportButton: [{
1090
- type: Input
1091
- }], matchingReportID: [{
1092
- type: Input
1093
- }], DrillDownEvent: [{
1094
- type: Output
1095
- }], CreateReportRequested: [{
1096
- type: Output
1097
- }], htmlContainers: [{
1098
- type: ViewChildren,
1099
- args: ['htmlContainer']
1100
- }], SkipData: [{
1101
- type: Input
1102
- }] }); })();
1103
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SkipDynamicHTMLReportComponent, { className: "SkipDynamicHTMLReportComponent", filePath: "src/lib/dynamic-report/dynamic-html-report.ts", lineNumber: 407 }); })();
1104
- //# sourceMappingURL=dynamic-html-report.js.map