@memberjunction/ng-artifacts 6.1.4 → 6.2.0-edge.1

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 (125) hide show
  1. package/dist/lib/components/artifact-message-card.component.d.ts +60 -8
  2. package/dist/lib/components/artifact-message-card.component.d.ts.map +1 -1
  3. package/dist/lib/components/artifact-message-card.component.js +135 -39
  4. package/dist/lib/components/artifact-message-card.component.js.map +1 -1
  5. package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts +58 -6
  6. package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts.map +1 -1
  7. package/dist/lib/components/artifact-type-plugin-viewer.component.js +113 -35
  8. package/dist/lib/components/artifact-type-plugin-viewer.component.js.map +1 -1
  9. package/dist/lib/components/artifact-version-download.d.ts +5 -3
  10. package/dist/lib/components/artifact-version-download.d.ts.map +1 -1
  11. package/dist/lib/components/artifact-version-download.js +11 -7
  12. package/dist/lib/components/artifact-version-download.js.map +1 -1
  13. package/dist/lib/components/artifact-version-history.component.d.ts +74 -8
  14. package/dist/lib/components/artifact-version-history.component.d.ts.map +1 -1
  15. package/dist/lib/components/artifact-version-history.component.js +152 -34
  16. package/dist/lib/components/artifact-version-history.component.js.map +1 -1
  17. package/dist/lib/components/artifact-viewer-panel.component.d.ts +328 -35
  18. package/dist/lib/components/artifact-viewer-panel.component.d.ts.map +1 -1
  19. package/dist/lib/components/artifact-viewer-panel.component.js +701 -213
  20. package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
  21. package/dist/lib/components/file-artifact-toolbar.component.d.ts +112 -10
  22. package/dist/lib/components/file-artifact-toolbar.component.d.ts.map +1 -1
  23. package/dist/lib/components/file-artifact-toolbar.component.js +197 -23
  24. package/dist/lib/components/file-artifact-toolbar.component.js.map +1 -1
  25. package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts +9 -1
  26. package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts.map +1 -1
  27. package/dist/lib/components/plugins/audio-artifact-viewer.component.js +20 -4
  28. package/dist/lib/components/plugins/audio-artifact-viewer.component.js.map +1 -1
  29. package/dist/lib/components/plugins/code-artifact-viewer.component.d.ts +23 -5
  30. package/dist/lib/components/plugins/code-artifact-viewer.component.d.ts.map +1 -1
  31. package/dist/lib/components/plugins/code-artifact-viewer.component.js +69 -31
  32. package/dist/lib/components/plugins/code-artifact-viewer.component.js.map +1 -1
  33. package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts +136 -18
  34. package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts.map +1 -1
  35. package/dist/lib/components/plugins/component-artifact-viewer.component.js +285 -97
  36. package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
  37. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.d.ts +2 -2
  38. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js +7 -7
  39. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js.map +1 -1
  40. package/dist/lib/components/plugins/component-permission-evaluation.d.ts +2 -0
  41. package/dist/lib/components/plugins/component-permission-evaluation.d.ts.map +1 -1
  42. package/dist/lib/components/plugins/component-permission-evaluation.js +6 -2
  43. package/dist/lib/components/plugins/component-permission-evaluation.js.map +1 -1
  44. package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts +17 -6
  45. package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts.map +1 -1
  46. package/dist/lib/components/plugins/data-artifact-viewer.component.js +32 -22
  47. package/dist/lib/components/plugins/data-artifact-viewer.component.js.map +1 -1
  48. package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.d.ts +56 -4
  49. package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.d.ts.map +1 -1
  50. package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js +142 -36
  51. package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js.map +1 -1
  52. package/dist/lib/components/plugins/docx-artifact-viewer.component.d.ts +14 -2
  53. package/dist/lib/components/plugins/docx-artifact-viewer.component.d.ts.map +1 -1
  54. package/dist/lib/components/plugins/docx-artifact-viewer.component.js +32 -8
  55. package/dist/lib/components/plugins/docx-artifact-viewer.component.js.map +1 -1
  56. package/dist/lib/components/plugins/html-artifact-viewer.component.d.ts +17 -3
  57. package/dist/lib/components/plugins/html-artifact-viewer.component.d.ts.map +1 -1
  58. package/dist/lib/components/plugins/html-artifact-viewer.component.js +36 -8
  59. package/dist/lib/components/plugins/html-artifact-viewer.component.js.map +1 -1
  60. package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts +41 -5
  61. package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts.map +1 -1
  62. package/dist/lib/components/plugins/image-artifact-viewer.component.js +102 -30
  63. package/dist/lib/components/plugins/image-artifact-viewer.component.js.map +1 -1
  64. package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts +33 -5
  65. package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts.map +1 -1
  66. package/dist/lib/components/plugins/json-artifact-viewer.component.js +89 -33
  67. package/dist/lib/components/plugins/json-artifact-viewer.component.js.map +1 -1
  68. package/dist/lib/components/plugins/markdown-artifact-viewer.component.d.ts +12 -2
  69. package/dist/lib/components/plugins/markdown-artifact-viewer.component.d.ts.map +1 -1
  70. package/dist/lib/components/plugins/markdown-artifact-viewer.component.js +28 -8
  71. package/dist/lib/components/plugins/markdown-artifact-viewer.component.js.map +1 -1
  72. package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts +4 -0
  73. package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts.map +1 -1
  74. package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js +14 -6
  75. package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js.map +1 -1
  76. package/dist/lib/components/plugins/pdf-artifact-viewer.component.d.ts +47 -5
  77. package/dist/lib/components/plugins/pdf-artifact-viewer.component.d.ts.map +1 -1
  78. package/dist/lib/components/plugins/pdf-artifact-viewer.component.js +129 -45
  79. package/dist/lib/components/plugins/pdf-artifact-viewer.component.js.map +1 -1
  80. package/dist/lib/components/plugins/save-query-dialog.component.d.ts +5 -1
  81. package/dist/lib/components/plugins/save-query-dialog.component.d.ts.map +1 -1
  82. package/dist/lib/components/plugins/save-query-dialog.component.js +12 -4
  83. package/dist/lib/components/plugins/save-query-dialog.component.js.map +1 -1
  84. package/dist/lib/components/plugins/svg-artifact-viewer.component.d.ts +17 -3
  85. package/dist/lib/components/plugins/svg-artifact-viewer.component.d.ts.map +1 -1
  86. package/dist/lib/components/plugins/svg-artifact-viewer.component.js +36 -8
  87. package/dist/lib/components/plugins/svg-artifact-viewer.component.js.map +1 -1
  88. package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts +9 -1
  89. package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts.map +1 -1
  90. package/dist/lib/components/plugins/video-artifact-viewer.component.js +20 -4
  91. package/dist/lib/components/plugins/video-artifact-viewer.component.js.map +1 -1
  92. package/dist/lib/components/plugins/xlsx-artifact-viewer.component.d.ts +28 -4
  93. package/dist/lib/components/plugins/xlsx-artifact-viewer.component.d.ts.map +1 -1
  94. package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js +64 -16
  95. package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js.map +1 -1
  96. package/dist/lib/components/previews/audio-artifact-preview.component.d.ts +9 -1
  97. package/dist/lib/components/previews/audio-artifact-preview.component.d.ts.map +1 -1
  98. package/dist/lib/components/previews/audio-artifact-preview.component.js +20 -4
  99. package/dist/lib/components/previews/audio-artifact-preview.component.js.map +1 -1
  100. package/dist/lib/components/previews/image-artifact-preview.component.d.ts +16 -2
  101. package/dist/lib/components/previews/image-artifact-preview.component.d.ts.map +1 -1
  102. package/dist/lib/components/previews/image-artifact-preview.component.js +35 -7
  103. package/dist/lib/components/previews/image-artifact-preview.component.js.map +1 -1
  104. package/dist/lib/components/previews/video-artifact-preview.component.d.ts +9 -1
  105. package/dist/lib/components/previews/video-artifact-preview.component.d.ts.map +1 -1
  106. package/dist/lib/components/previews/video-artifact-preview.component.js +20 -4
  107. package/dist/lib/components/previews/video-artifact-preview.component.js.map +1 -1
  108. package/dist/lib/interfaces/artifact-viewer-plugin.interface.js.map +1 -1
  109. package/dist/lib/services/artifact-file.service.d.ts +8 -0
  110. package/dist/lib/services/artifact-file.service.d.ts.map +1 -1
  111. package/dist/lib/services/artifact-file.service.js +22 -6
  112. package/dist/lib/services/artifact-file.service.js.map +1 -1
  113. package/dist/lib/services/artifact-icon.service.d.ts +2 -0
  114. package/dist/lib/services/artifact-icon.service.d.ts.map +1 -1
  115. package/dist/lib/services/artifact-icon.service.js +5 -1
  116. package/dist/lib/services/artifact-icon.service.js.map +1 -1
  117. package/dist/lib/services/artifact-preview-resolver.service.d.ts +2 -0
  118. package/dist/lib/services/artifact-preview-resolver.service.d.ts.map +1 -1
  119. package/dist/lib/services/artifact-preview-resolver.service.js +5 -1
  120. package/dist/lib/services/artifact-preview-resolver.service.js.map +1 -1
  121. package/dist/lib/snapshot-helpers.d.ts +10 -0
  122. package/dist/lib/snapshot-helpers.d.ts.map +1 -1
  123. package/dist/lib/snapshot-helpers.js +25 -5
  124. package/dist/lib/snapshot-helpers.js.map +1 -1
  125. package/package.json +21 -21
@@ -50,13 +50,53 @@ function PdfArtifactViewerComponent_Conditional_5_Template(rf, ctx) { if (rf & 1
50
50
  let PdfArtifactViewerComponent = class PdfArtifactViewerComponent extends BaseArtifactViewerPluginComponent {
51
51
  fileService;
52
52
  cdr;
53
- canvasRef;
53
+ CanvasRef;
54
+ /** @deprecated Use {@link CanvasRef}. */
55
+ get canvasRef() {
56
+ return this.CanvasRef;
57
+ }
58
+ /** @deprecated Use {@link CanvasRef}. */
59
+ set canvasRef(value) {
60
+ this.CanvasRef = value;
61
+ }
54
62
  isLoading = true;
55
- isDownloading = false;
63
+ IsDownloading = false;
64
+ /** @deprecated Use {@link IsDownloading}. */
65
+ get isDownloading() {
66
+ return this.IsDownloading;
67
+ }
68
+ /** @deprecated Use {@link IsDownloading}. */
69
+ set isDownloading(value) {
70
+ this.IsDownloading = value;
71
+ }
56
72
  errorMessage = '';
57
- currentPage = 1;
58
- totalPages = 1;
59
- zoomLevel = 1.0;
73
+ CurrentPage = 1;
74
+ /** @deprecated Use {@link CurrentPage}. */
75
+ get currentPage() {
76
+ return this.CurrentPage;
77
+ }
78
+ /** @deprecated Use {@link CurrentPage}. */
79
+ set currentPage(value) {
80
+ this.CurrentPage = value;
81
+ }
82
+ TotalPages = 1;
83
+ /** @deprecated Use {@link TotalPages}. */
84
+ get totalPages() {
85
+ return this.TotalPages;
86
+ }
87
+ /** @deprecated Use {@link TotalPages}. */
88
+ set totalPages(value) {
89
+ this.TotalPages = value;
90
+ }
91
+ ZoomLevel = 1.0;
92
+ /** @deprecated Use {@link ZoomLevel}. */
93
+ get zoomLevel() {
94
+ return this.ZoomLevel;
95
+ }
96
+ /** @deprecated Use {@link ZoomLevel}. */
97
+ set zoomLevel(value) {
98
+ this.ZoomLevel = value;
99
+ }
60
100
  pdfDoc = null;
61
101
  renderTask = null;
62
102
  downloadUrl = '';
@@ -74,14 +114,26 @@ let PdfArtifactViewerComponent = class PdfArtifactViewerComponent extends BaseAr
74
114
  return true;
75
115
  }
76
116
  /** Current zoom as an integer percentage for toolbar display. */
117
+ get ZoomPercent() {
118
+ return Math.round(this.ZoomLevel * 100);
119
+ }
120
+ /** @deprecated Use {@link ZoomPercent}. */
77
121
  get zoomPercent() {
78
- return Math.round(this.zoomLevel * 100);
122
+ return this.ZoomPercent;
79
123
  }
124
+ get CanZoomIn() {
125
+ return this.ZoomLevel < this.ZOOM_STEPS[this.ZOOM_STEPS.length - 1];
126
+ }
127
+ /** @deprecated Use {@link CanZoomIn}. */
80
128
  get canZoomIn() {
81
- return this.zoomLevel < this.ZOOM_STEPS[this.ZOOM_STEPS.length - 1];
129
+ return this.CanZoomIn;
130
+ }
131
+ get CanZoomOut() {
132
+ return this.ZoomLevel > this.ZOOM_STEPS[0];
82
133
  }
134
+ /** @deprecated Use {@link CanZoomOut}. */
83
135
  get canZoomOut() {
84
- return this.zoomLevel > this.ZOOM_STEPS[0];
136
+ return this.CanZoomOut;
85
137
  }
86
138
  async ngOnInit() {
87
139
  await this.loadPdf();
@@ -92,64 +144,96 @@ let PdfArtifactViewerComponent = class PdfArtifactViewerComponent extends BaseAr
92
144
  this.pdfDoc = null;
93
145
  }
94
146
  // ─── Navigation ─────────────────────────────────────────────────────────────
147
+ async GoToNextPage() {
148
+ await this.OnPageChange(this.CurrentPage + 1);
149
+ }
150
+ /** @deprecated Use {@link GoToNextPage}. */
95
151
  async goToNextPage() {
96
- await this.onPageChange(this.currentPage + 1);
152
+ return this.GoToNextPage();
153
+ }
154
+ async GoToPrevPage() {
155
+ await this.OnPageChange(this.CurrentPage - 1);
97
156
  }
157
+ /** @deprecated Use {@link GoToPrevPage}. */
98
158
  async goToPrevPage() {
99
- await this.onPageChange(this.currentPage - 1);
159
+ return this.GoToPrevPage();
100
160
  }
101
- async onPageChange(page) {
102
- const clamped = Math.max(1, Math.min(page, this.totalPages));
103
- if (clamped !== this.currentPage) {
104
- this.currentPage = clamped;
105
- await this.renderPage(this.currentPage);
161
+ async OnPageChange(page) {
162
+ const clamped = Math.max(1, Math.min(page, this.TotalPages));
163
+ if (clamped !== this.CurrentPage) {
164
+ this.CurrentPage = clamped;
165
+ await this.renderPage(this.CurrentPage);
106
166
  }
107
167
  }
168
+ /** @deprecated Use {@link OnPageChange}. */
169
+ async onPageChange(page) {
170
+ return this.OnPageChange(page);
171
+ }
108
172
  // ─── Zoom ────────────────────────────────────────────────────────────────────
109
- async onZoomIn() {
110
- const next = this.ZOOM_STEPS.find((z) => z > this.zoomLevel);
173
+ async OnZoomIn() {
174
+ const next = this.ZOOM_STEPS.find((z) => z > this.ZoomLevel);
111
175
  if (next !== undefined) {
112
- this.zoomLevel = next;
113
- await this.renderPage(this.currentPage);
176
+ this.ZoomLevel = next;
177
+ await this.renderPage(this.CurrentPage);
114
178
  }
115
179
  }
116
- async onZoomOut() {
180
+ /** @deprecated Use {@link OnZoomIn}. */
181
+ async onZoomIn() {
182
+ return this.OnZoomIn();
183
+ }
184
+ async OnZoomOut() {
117
185
  for (let i = this.ZOOM_STEPS.length - 1; i >= 0; i--) {
118
- if (this.ZOOM_STEPS[i] < this.zoomLevel) {
119
- this.zoomLevel = this.ZOOM_STEPS[i];
120
- await this.renderPage(this.currentPage);
186
+ if (this.ZOOM_STEPS[i] < this.ZoomLevel) {
187
+ this.ZoomLevel = this.ZOOM_STEPS[i];
188
+ await this.renderPage(this.CurrentPage);
121
189
  return;
122
190
  }
123
191
  }
124
192
  }
125
- async onZoomReset() {
126
- if (this.zoomLevel !== 1.0) {
127
- this.zoomLevel = 1.0;
128
- await this.renderPage(this.currentPage);
193
+ /** @deprecated Use {@link OnZoomOut}. */
194
+ async onZoomOut() {
195
+ return this.OnZoomOut();
196
+ }
197
+ async OnZoomReset() {
198
+ if (this.ZoomLevel !== 1.0) {
199
+ this.ZoomLevel = 1.0;
200
+ await this.renderPage(this.CurrentPage);
129
201
  }
130
202
  }
203
+ /** @deprecated Use {@link OnZoomReset}. */
204
+ async onZoomReset() {
205
+ return this.OnZoomReset();
206
+ }
131
207
  // ─── Download / Print ───────────────────────────────────────────────────────
132
- async onDownload() {
133
- if (!this.downloadUrl || this.isDownloading) {
208
+ async OnDownload() {
209
+ if (!this.downloadUrl || this.IsDownloading) {
134
210
  return;
135
211
  }
136
- this.isDownloading = true;
212
+ this.IsDownloading = true;
137
213
  this.cdr.markForCheck();
138
214
  try {
139
215
  await this.triggerBrowserDownload(this.downloadUrl, this.artifactVersion?.FileName || 'document.pdf');
140
216
  }
141
217
  finally {
142
- this.isDownloading = false;
218
+ this.IsDownloading = false;
143
219
  this.cdr.markForCheck();
144
220
  }
145
221
  }
146
- onPrint() {
222
+ /** @deprecated Use {@link OnDownload}. */
223
+ async onDownload() {
224
+ return this.OnDownload();
225
+ }
226
+ OnPrint() {
147
227
  if (!this.downloadUrl) {
148
228
  return;
149
229
  }
150
230
  // Open the PDF in a new tab so the browser's native print dialog handles it
151
231
  window.open(this.downloadUrl, '_blank');
152
232
  }
233
+ /** @deprecated Use {@link OnPrint}. */
234
+ onPrint() {
235
+ return this.OnPrint();
236
+ }
153
237
  // ─── Private helpers ────────────────────────────────────────────────────────
154
238
  async loadPdf() {
155
239
  if (!this.artifactVersion?.ID) {
@@ -177,8 +261,8 @@ let PdfArtifactViewerComponent = class PdfArtifactViewerComponent extends BaseAr
177
261
  this.downloadUrl = this.fileService.dataUrlToObjectUrl(content, this.artifactVersion.MimeType || 'application/pdf');
178
262
  }
179
263
  this.pdfDoc = pdfDoc;
180
- this.totalPages = pdfDoc.numPages;
181
- this.currentPage = 1;
264
+ this.TotalPages = pdfDoc.numPages;
265
+ this.CurrentPage = 1;
182
266
  this.isLoading = false;
183
267
  // detectChanges() forces a synchronous DOM update so the canvas element
184
268
  // exists before renderPage() tries to draw on it.
@@ -196,17 +280,17 @@ let PdfArtifactViewerComponent = class PdfArtifactViewerComponent extends BaseAr
196
280
  * pixel-perfectly. Subsequent +/- presses will snap to the nearest step.
197
281
  */
198
282
  async setFitWidthZoom() {
199
- if (!this.pdfDoc || !this.canvasRef?.nativeElement) {
283
+ if (!this.pdfDoc || !this.CanvasRef?.nativeElement) {
200
284
  return;
201
285
  }
202
286
  const page = (await this.pdfDoc.getPage(1));
203
287
  // naturalViewport.width is the CSS pixel width of the page at zoom = 1.0
204
288
  const naturalViewport = page.getViewport({ scale: this.BASE_SCALE });
205
- const body = this.canvasRef.nativeElement.closest('.pdf-viewer__body');
289
+ const body = this.CanvasRef.nativeElement.closest('.pdf-viewer__body');
206
290
  const availableWidth = (body?.clientWidth ?? 0) - 32; // 16px padding each side
207
291
  if (availableWidth > 0 && naturalViewport.width > 0) {
208
292
  const fitZoom = availableWidth / naturalViewport.width;
209
- this.zoomLevel = Math.max(this.ZOOM_STEPS[0], Math.min(fitZoom, this.ZOOM_STEPS[this.ZOOM_STEPS.length - 1]));
293
+ this.ZoomLevel = Math.max(this.ZOOM_STEPS[0], Math.min(fitZoom, this.ZOOM_STEPS[this.ZOOM_STEPS.length - 1]));
210
294
  }
211
295
  }
212
296
  /** Dynamically import pdfjs-dist and point it at the bundled worker. */
@@ -228,19 +312,19 @@ let PdfArtifactViewerComponent = class PdfArtifactViewerComponent extends BaseAr
228
312
  return loadingTask.promise;
229
313
  }
230
314
  async renderPage(pageNum) {
231
- if (!this.pdfDoc || !this.canvasRef?.nativeElement) {
315
+ if (!this.pdfDoc || !this.CanvasRef?.nativeElement) {
232
316
  return;
233
317
  }
234
318
  this.cancelCurrentRender();
235
319
  const page = (await this.pdfDoc.getPage(pageNum));
236
- const canvas = this.canvasRef.nativeElement;
320
+ const canvas = this.CanvasRef.nativeElement;
237
321
  const ctx = canvas.getContext('2d');
238
322
  if (!ctx) {
239
323
  return;
240
324
  }
241
325
  const pixelRatio = window.devicePixelRatio || 1;
242
326
  // Scale = base * zoom * devicePixelRatio so backing buffer is always HiDPI-sharp.
243
- const viewport = page.getViewport({ scale: this.BASE_SCALE * this.zoomLevel * pixelRatio });
327
+ const viewport = page.getViewport({ scale: this.BASE_SCALE * this.ZoomLevel * pixelRatio });
244
328
  // Backing buffer: full HiDPI resolution.
245
329
  canvas.width = viewport.width;
246
330
  canvas.height = viewport.height;
@@ -273,10 +357,10 @@ let PdfArtifactViewerComponent = class PdfArtifactViewerComponent extends BaseAr
273
357
  GetCurrentStateSnapshot() {
274
358
  const snap = new DataSnapshot();
275
359
  snap.title = this.getDisplayTitle() ?? undefined;
276
- snap.interpretation = `PDF document, ${this.totalPages} page${this.totalPages !== 1 ? 's' : ''}. Currently viewing page ${this.currentPage}.`;
360
+ snap.interpretation = `PDF document, ${this.TotalPages} page${this.TotalPages !== 1 ? 's' : ''}. Currently viewing page ${this.CurrentPage}.`;
277
361
  snap.custom = {
278
- pageCount: this.totalPages,
279
- currentPage: this.currentPage,
362
+ pageCount: this.TotalPages,
363
+ currentPage: this.CurrentPage,
280
364
  fileName: this.artifactVersion.FileName ?? undefined,
281
365
  mimeType: this.artifactVersion.MimeType ?? 'application/pdf',
282
366
  contentMode: this.artifactVersion.ContentMode,
@@ -288,7 +372,7 @@ let PdfArtifactViewerComponent = class PdfArtifactViewerComponent extends BaseAr
288
372
  i0.ɵɵviewQuery(_c0, 5);
289
373
  } if (rf & 2) {
290
374
  let _t;
291
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.canvasRef = _t.first);
375
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.CanvasRef = _t.first);
292
376
  } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 6, vars: 10, consts: [["pdfCanvas", ""], [1, "pdf-viewer"], [3, "download", "print", "prevPage", "nextPage", "pageChange", "zoomIn", "zoomOut", "zoomReset", "fileName", "currentPage", "totalPages", "isDownloading", "showPrint", "showZoom", "zoomPercent", "canZoomIn", "canZoomOut"], [1, "pdf-viewer__body"], [1, "pdf-viewer__state"], [1, "pdf-viewer__state", "pdf-viewer__state--error"], [1, "pdf-viewer__canvas-wrap"], [1, "fas", "fa-spinner", "fa-spin"], [1, "fas", "fa-exclamation-triangle"]], template: function PdfArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
293
377
  i0.ɵɵelementStart(0, "div", 1)(1, "mj-file-artifact-toolbar", 2);
294
378
  i0.ɵɵlistener("download", function PdfArtifactViewerComponent_Template_mj_file_artifact_toolbar_download_1_listener() { return ctx.onDownload(); })("print", function PdfArtifactViewerComponent_Template_mj_file_artifact_toolbar_print_1_listener() { return ctx.onPrint(); })("prevPage", function PdfArtifactViewerComponent_Template_mj_file_artifact_toolbar_prevPage_1_listener() { return ctx.goToPrevPage(); })("nextPage", function PdfArtifactViewerComponent_Template_mj_file_artifact_toolbar_nextPage_1_listener() { return ctx.goToNextPage(); })("pageChange", function PdfArtifactViewerComponent_Template_mj_file_artifact_toolbar_pageChange_1_listener($event) { return ctx.onPageChange($event); })("zoomIn", function PdfArtifactViewerComponent_Template_mj_file_artifact_toolbar_zoomIn_1_listener() { return ctx.onZoomIn(); })("zoomOut", function PdfArtifactViewerComponent_Template_mj_file_artifact_toolbar_zoomOut_1_listener() { return ctx.onZoomOut(); })("zoomReset", function PdfArtifactViewerComponent_Template_mj_file_artifact_toolbar_zoomReset_1_listener() { return ctx.onZoomReset(); });
@@ -351,7 +435,7 @@ export { PdfArtifactViewerComponent };
351
435
  </div>
352
436
  </div>
353
437
  `, styles: ["\n .pdf-viewer {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n }\n\n .pdf-viewer__body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n }\n\n .pdf-viewer__state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n height: 100%;\n color: var(--mj-text-muted);\n font-size: 14px;\n }\n\n .pdf-viewer__state--error {\n color: var(--mj-status-error-text);\n }\n\n .pdf-viewer__canvas-wrap {\n display: flex;\n justify-content: center;\n padding: 16px;\n /* Prevent centered overflow from clipping the left side of zoomed pages.\n min-width: fit-content makes the wrap grow to fit the canvas so the\n parent overflow:auto container can scroll to both edges. */\n min-width: fit-content;\n }\n\n canvas {\n display: block;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n /* Natural size \u2014 do NOT add max-width:100% here.\n renderPage sets width/aspect-ratio/height inline so the canvas renders at\n exactly the zoomed logical size. The scroll area (overflow:auto on the body)\n handles pages wider than the panel, which is the correct UX for zoom. */\n }\n "] }]
354
- }], () => [{ type: i1.ArtifactFileService }, { type: i0.ChangeDetectorRef }], { canvasRef: [{
438
+ }], () => [{ type: i1.ArtifactFileService }, { type: i0.ChangeDetectorRef }], { CanvasRef: [{
355
439
  type: ViewChild,
356
440
  args: ['pdfCanvas']
357
441
  }] }); })();
@@ -1 +1 @@
1
- {"version":3,"file":"pdf-artifact-viewer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/plugins/pdf-artifact-viewer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { DataSnapshot } from '@memberjunction/core';\nimport { BaseArtifactViewerPluginComponent } from '../base-artifact-viewer.component';\nimport { ArtifactFileService } from '../../services/artifact-file.service';\n\n/**\n * Viewer plugin for PDF artifact versions stored in MJStorage (ContentMode = 'File')\n * or as inline base64 content (ContentMode = 'Inline').\n *\n * Renders one page at a time using PDF.js. The toolbar provides page navigation\n * (including a direct page-jump input), zoom in/out, download, and print.\n *\n * Aspect-ratio preservation: the canvas backing buffer is sized at full HiDPI\n * resolution while the CSS size uses `aspect-ratio` + `height: auto` so both\n * dimensions scale proportionally. Pages wider than the panel scroll horizontally\n * inside the body — no max-width clamping, which is required for zoom to work.\n */\n@Component({\n standalone: false,\n selector: 'mj-pdf-artifact-viewer',\n template: `\n <div class=\"pdf-viewer\">\n <mj-file-artifact-toolbar\n [fileName]=\"artifactVersion.FileName || 'document.pdf'\"\n [currentPage]=\"currentPage\"\n [totalPages]=\"totalPages\"\n [isDownloading]=\"isDownloading\"\n [showPrint]=\"true\"\n [showZoom]=\"true\"\n [zoomPercent]=\"zoomPercent\"\n [canZoomIn]=\"canZoomIn\"\n [canZoomOut]=\"canZoomOut\"\n (download)=\"onDownload()\"\n (print)=\"onPrint()\"\n (prevPage)=\"goToPrevPage()\"\n (nextPage)=\"goToNextPage()\"\n (pageChange)=\"onPageChange($event)\"\n (zoomIn)=\"onZoomIn()\"\n (zoomOut)=\"onZoomOut()\"\n (zoomReset)=\"onZoomReset()\"\n >\n </mj-file-artifact-toolbar>\n\n <div class=\"pdf-viewer__body\">\n @if (isLoading) {\n <div class=\"pdf-viewer__state\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading PDF…</span>\n </div>\n } @else if (errorMessage) {\n <div class=\"pdf-viewer__state pdf-viewer__state--error\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <span>{{ errorMessage }}</span>\n </div>\n } @else {\n <div class=\"pdf-viewer__canvas-wrap\">\n <canvas #pdfCanvas></canvas>\n </div>\n }\n </div>\n </div>\n `,\n styles: [\n `\n .pdf-viewer {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n }\n\n .pdf-viewer__body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n }\n\n .pdf-viewer__state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n height: 100%;\n color: var(--mj-text-muted);\n font-size: 14px;\n }\n\n .pdf-viewer__state--error {\n color: var(--mj-status-error-text);\n }\n\n .pdf-viewer__canvas-wrap {\n display: flex;\n justify-content: center;\n padding: 16px;\n /* Prevent centered overflow from clipping the left side of zoomed pages.\n min-width: fit-content makes the wrap grow to fit the canvas so the\n parent overflow:auto container can scroll to both edges. */\n min-width: fit-content;\n }\n\n canvas {\n display: block;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n /* Natural size — do NOT add max-width:100% here.\n renderPage sets width/aspect-ratio/height inline so the canvas renders at\n exactly the zoomed logical size. The scroll area (overflow:auto on the body)\n handles pages wider than the panel, which is the correct UX for zoom. */\n }\n `,\n ],\n})\n@RegisterClass(BaseArtifactViewerPluginComponent, 'PdfArtifactViewerPlugin')\nexport class PdfArtifactViewerComponent extends BaseArtifactViewerPluginComponent implements OnInit, OnDestroy {\n @ViewChild('pdfCanvas') canvasRef?: ElementRef<HTMLCanvasElement>;\n\n public isLoading = true;\n public isDownloading = false;\n public errorMessage = '';\n public currentPage = 1;\n public totalPages = 1;\n public zoomLevel = 1.0;\n\n private pdfDoc: PdfDocumentProxy | null = null;\n private renderTask: PdfRenderTask | null = null;\n private downloadUrl = '';\n private _pdfjsLib: PdfJsLib | null = null;\n\n /** Discrete zoom steps — 50 % to 400 %. */\n private readonly ZOOM_STEPS = [0.5, 0.67, 0.75, 1.0, 1.25, 1.5, 2.0, 3.0, 4.0];\n /** Base render scale (logical pixels per PDF point at zoom 1.0). */\n private readonly BASE_SCALE = 1.5;\n\n constructor(\n private fileService: ArtifactFileService,\n private cdr: ChangeDetectorRef,\n ) {\n super();\n }\n\n public override get hasDisplayContent(): boolean {\n return true;\n }\n\n /** Current zoom as an integer percentage for toolbar display. */\n public get zoomPercent(): number {\n return Math.round(this.zoomLevel * 100);\n }\n\n public get canZoomIn(): boolean {\n return this.zoomLevel < this.ZOOM_STEPS[this.ZOOM_STEPS.length - 1];\n }\n\n public get canZoomOut(): boolean {\n return this.zoomLevel > this.ZOOM_STEPS[0];\n }\n\n async ngOnInit(): Promise<void> {\n await this.loadPdf();\n }\n\n ngOnDestroy(): void {\n this.cancelCurrentRender();\n this.pdfDoc?.destroy();\n this.pdfDoc = null;\n }\n\n // ─── Navigation ─────────────────────────────────────────────────────────────\n\n public async goToNextPage(): Promise<void> {\n await this.onPageChange(this.currentPage + 1);\n }\n\n public async goToPrevPage(): Promise<void> {\n await this.onPageChange(this.currentPage - 1);\n }\n\n public async onPageChange(page: number): Promise<void> {\n const clamped = Math.max(1, Math.min(page, this.totalPages));\n if (clamped !== this.currentPage) {\n this.currentPage = clamped;\n await this.renderPage(this.currentPage);\n }\n }\n\n // ─── Zoom ────────────────────────────────────────────────────────────────────\n\n public async onZoomIn(): Promise<void> {\n const next = this.ZOOM_STEPS.find((z) => z > this.zoomLevel);\n if (next !== undefined) {\n this.zoomLevel = next;\n await this.renderPage(this.currentPage);\n }\n }\n\n public async onZoomOut(): Promise<void> {\n for (let i = this.ZOOM_STEPS.length - 1; i >= 0; i--) {\n if (this.ZOOM_STEPS[i] < this.zoomLevel) {\n this.zoomLevel = this.ZOOM_STEPS[i];\n await this.renderPage(this.currentPage);\n return;\n }\n }\n }\n\n public async onZoomReset(): Promise<void> {\n if (this.zoomLevel !== 1.0) {\n this.zoomLevel = 1.0;\n await this.renderPage(this.currentPage);\n }\n }\n\n // ─── Download / Print ───────────────────────────────────────────────────────\n\n public async onDownload(): Promise<void> {\n if (!this.downloadUrl || this.isDownloading) {\n return;\n }\n this.isDownloading = true;\n this.cdr.markForCheck();\n try {\n await this.triggerBrowserDownload(this.downloadUrl, this.artifactVersion?.FileName || 'document.pdf');\n } finally {\n this.isDownloading = false;\n this.cdr.markForCheck();\n }\n }\n\n public onPrint(): void {\n if (!this.downloadUrl) {\n return;\n }\n // Open the PDF in a new tab so the browser's native print dialog handles it\n window.open(this.downloadUrl, '_blank');\n }\n\n // ─── Private helpers ────────────────────────────────────────────────────────\n\n private async loadPdf(): Promise<void> {\n if (!this.artifactVersion?.ID) {\n this.showError('No artifact version provided.');\n return;\n }\n\n try {\n await this.initPdfJs();\n let pdfDoc: PdfDocumentProxy;\n\n if (this.artifactVersion.ContentMode === 'File') {\n // File-backed: download from storage via pre-auth URL\n this.downloadUrl = await this.fileService.getDownloadUrl(this.artifactVersion.ID);\n pdfDoc = await this.loadPdfDocument(this.downloadUrl);\n } else {\n // Inline: content is a base64 data URL stored in the artifact version\n const content = this.artifactVersion.Content;\n if (!content) {\n this.showError('Artifact has no content.');\n return;\n }\n const arrayBuffer = this.fileService.dataUrlToArrayBuffer(content);\n pdfDoc = await this.loadPdfFromData(new Uint8Array(arrayBuffer));\n // Create an object URL for download/print support\n this.downloadUrl = this.fileService.dataUrlToObjectUrl(content, this.artifactVersion.MimeType || 'application/pdf');\n }\n\n this.pdfDoc = pdfDoc;\n this.totalPages = pdfDoc.numPages;\n this.currentPage = 1;\n this.isLoading = false;\n // detectChanges() forces a synchronous DOM update so the canvas element\n // exists before renderPage() tries to draw on it.\n this.cdr.detectChanges();\n await this.setFitWidthZoom();\n await this.renderPage(1);\n } catch (err) {\n this.showError(`Could not load PDF: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n /**\n * Set the initial zoom so the first page fills the available panel width.\n * Uses the exact ratio rather than snapping to a ZOOM_STEP so the page fits\n * pixel-perfectly. Subsequent +/- presses will snap to the nearest step.\n */\n private async setFitWidthZoom(): Promise<void> {\n if (!this.pdfDoc || !this.canvasRef?.nativeElement) {\n return;\n }\n const page = (await this.pdfDoc.getPage(1)) as PdfPageProxy;\n // naturalViewport.width is the CSS pixel width of the page at zoom = 1.0\n const naturalViewport = page.getViewport({ scale: this.BASE_SCALE });\n const body = this.canvasRef.nativeElement.closest('.pdf-viewer__body') as HTMLElement | null;\n const availableWidth = (body?.clientWidth ?? 0) - 32; // 16px padding each side\n if (availableWidth > 0 && naturalViewport.width > 0) {\n const fitZoom = availableWidth / naturalViewport.width;\n this.zoomLevel = Math.max(this.ZOOM_STEPS[0], Math.min(fitZoom, this.ZOOM_STEPS[this.ZOOM_STEPS.length - 1]));\n }\n }\n\n /** Dynamically import pdfjs-dist and point it at the bundled worker. */\n private async initPdfJs(): Promise<void> {\n const pdfjsLib = (await import('pdfjs-dist')) as unknown as PdfJsLib;\n // pdfjs-dist v4 requires an explicit workerSrc. The worker file is copied to\n // /assets/pdf.worker.min.mjs via the angular.json assets config in MJExplorer.\n pdfjsLib.GlobalWorkerOptions.workerSrc = '/assets/pdf.worker.min.mjs';\n this._pdfjsLib = pdfjsLib;\n }\n\n private async loadPdfDocument(url: string): Promise<PdfDocumentProxy> {\n const pdfjsLib = this._pdfjsLib!;\n const loadingTask = pdfjsLib.getDocument(url);\n return loadingTask.promise;\n }\n\n private async loadPdfFromData(data: Uint8Array): Promise<PdfDocumentProxy> {\n const pdfjsLib = this._pdfjsLib!;\n const loadingTask = pdfjsLib.getDocument({ data });\n return loadingTask.promise;\n }\n\n private async renderPage(pageNum: number): Promise<void> {\n if (!this.pdfDoc || !this.canvasRef?.nativeElement) {\n return;\n }\n\n this.cancelCurrentRender();\n\n const page = (await this.pdfDoc.getPage(pageNum)) as PdfPageProxy;\n const canvas = this.canvasRef.nativeElement;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n return;\n }\n\n const pixelRatio = window.devicePixelRatio || 1;\n // Scale = base * zoom * devicePixelRatio so backing buffer is always HiDPI-sharp.\n const viewport = page.getViewport({ scale: this.BASE_SCALE * this.zoomLevel * pixelRatio });\n\n // Backing buffer: full HiDPI resolution.\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n\n // CSS logical pixel dimensions at the current zoom level.\n const cssWidth = viewport.width / pixelRatio;\n const cssHeight = viewport.height / pixelRatio;\n\n canvas.style.width = `${cssWidth}px`;\n // aspect-ratio + height:auto: when cssWidth is set explicitly and the page\n // renders at its natural size, the browser derives height proportionally.\n // Pages wider than the panel scroll horizontally — the body handles overflow.\n canvas.style.aspectRatio = `${cssWidth} / ${cssHeight}`;\n canvas.style.height = 'auto';\n\n const renderContext = { canvasContext: ctx, viewport };\n this.renderTask = page.render(renderContext) as PdfRenderTask;\n await this.renderTask.promise;\n this.renderTask = null;\n this.cdr.markForCheck();\n }\n\n private cancelCurrentRender(): void {\n if (this.renderTask) {\n this.renderTask.cancel();\n this.renderTask = null;\n }\n }\n\n private showError(message: string): void {\n this.isLoading = false;\n this.errorMessage = message;\n this.cdr.markForCheck();\n }\n\n public override GetCurrentStateSnapshot(): DataSnapshot | null {\n const snap = new DataSnapshot();\n snap.title = this.getDisplayTitle() ?? undefined;\n snap.interpretation = `PDF document, ${this.totalPages} page${this.totalPages !== 1 ? 's' : ''}. Currently viewing page ${this.currentPage}.`;\n snap.custom = {\n pageCount: this.totalPages,\n currentPage: this.currentPage,\n fileName: this.artifactVersion.FileName ?? undefined,\n mimeType: this.artifactVersion.MimeType ?? 'application/pdf',\n contentMode: this.artifactVersion.ContentMode,\n };\n return snap;\n }\n}\n\n// ─── Minimal type shims for pdfjs-dist dynamic import ─────────────────────────\n// We avoid a hard build-time dependency on pdfjs-dist types by declaring only\n// the surface we actually use.\n\ninterface PdfDocumentProxy {\n numPages: number;\n getPage(pageNumber: number): Promise<PdfPageProxy>;\n destroy(): void;\n}\n\ninterface PdfPageProxy {\n getViewport(params: { scale: number }): { width: number; height: number };\n render(renderContext: { canvasContext: CanvasRenderingContext2D; viewport: { width: number; height: number } }): PdfRenderTask;\n}\n\ninterface PdfRenderTask {\n promise: Promise<void>;\n cancel(): void;\n}\n\ninterface PdfJsLib {\n GlobalWorkerOptions: { workerSrc: string };\n getDocument(source: string | { data: Uint8Array }): { promise: Promise<PdfDocumentProxy> };\n}\n"]}
1
+ {"version":3,"file":"pdf-artifact-viewer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/plugins/pdf-artifact-viewer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { DataSnapshot } from '@memberjunction/core';\nimport { BaseArtifactViewerPluginComponent } from '../base-artifact-viewer.component';\nimport { ArtifactFileService } from '../../services/artifact-file.service';\n\n/**\n * Viewer plugin for PDF artifact versions stored in MJStorage (ContentMode = 'File')\n * or as inline base64 content (ContentMode = 'Inline').\n *\n * Renders one page at a time using PDF.js. The toolbar provides page navigation\n * (including a direct page-jump input), zoom in/out, download, and print.\n *\n * Aspect-ratio preservation: the canvas backing buffer is sized at full HiDPI\n * resolution while the CSS size uses `aspect-ratio` + `height: auto` so both\n * dimensions scale proportionally. Pages wider than the panel scroll horizontally\n * inside the body — no max-width clamping, which is required for zoom to work.\n */\n@Component({\n standalone: false,\n selector: 'mj-pdf-artifact-viewer',\n template: `\n <div class=\"pdf-viewer\">\n <mj-file-artifact-toolbar\n [fileName]=\"artifactVersion.FileName || 'document.pdf'\"\n [currentPage]=\"currentPage\"\n [totalPages]=\"totalPages\"\n [isDownloading]=\"isDownloading\"\n [showPrint]=\"true\"\n [showZoom]=\"true\"\n [zoomPercent]=\"zoomPercent\"\n [canZoomIn]=\"canZoomIn\"\n [canZoomOut]=\"canZoomOut\"\n (download)=\"onDownload()\"\n (print)=\"onPrint()\"\n (prevPage)=\"goToPrevPage()\"\n (nextPage)=\"goToNextPage()\"\n (pageChange)=\"onPageChange($event)\"\n (zoomIn)=\"onZoomIn()\"\n (zoomOut)=\"onZoomOut()\"\n (zoomReset)=\"onZoomReset()\"\n >\n </mj-file-artifact-toolbar>\n\n <div class=\"pdf-viewer__body\">\n @if (isLoading) {\n <div class=\"pdf-viewer__state\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading PDF…</span>\n </div>\n } @else if (errorMessage) {\n <div class=\"pdf-viewer__state pdf-viewer__state--error\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <span>{{ errorMessage }}</span>\n </div>\n } @else {\n <div class=\"pdf-viewer__canvas-wrap\">\n <canvas #pdfCanvas></canvas>\n </div>\n }\n </div>\n </div>\n `,\n styles: [\n `\n .pdf-viewer {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n }\n\n .pdf-viewer__body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n }\n\n .pdf-viewer__state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n height: 100%;\n color: var(--mj-text-muted);\n font-size: 14px;\n }\n\n .pdf-viewer__state--error {\n color: var(--mj-status-error-text);\n }\n\n .pdf-viewer__canvas-wrap {\n display: flex;\n justify-content: center;\n padding: 16px;\n /* Prevent centered overflow from clipping the left side of zoomed pages.\n min-width: fit-content makes the wrap grow to fit the canvas so the\n parent overflow:auto container can scroll to both edges. */\n min-width: fit-content;\n }\n\n canvas {\n display: block;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n /* Natural size — do NOT add max-width:100% here.\n renderPage sets width/aspect-ratio/height inline so the canvas renders at\n exactly the zoomed logical size. The scroll area (overflow:auto on the body)\n handles pages wider than the panel, which is the correct UX for zoom. */\n }\n `,\n ],\n})\n@RegisterClass(BaseArtifactViewerPluginComponent, 'PdfArtifactViewerPlugin')\nexport class PdfArtifactViewerComponent extends BaseArtifactViewerPluginComponent implements OnInit, OnDestroy {\n @ViewChild('pdfCanvas') CanvasRef?: ElementRef<HTMLCanvasElement>;\n\n /** @deprecated Use {@link CanvasRef}. */\n get canvasRef(): ElementRef<HTMLCanvasElement> | undefined {\n return this.CanvasRef;\n }\n /** @deprecated Use {@link CanvasRef}. */\n set canvasRef(value: ElementRef<HTMLCanvasElement> | undefined) {\n this.CanvasRef = value;\n }\n\n public isLoading = true;\n public IsDownloading = false;\n\n /** @deprecated Use {@link IsDownloading}. */\n public get isDownloading() {\n return this.IsDownloading;\n }\n /** @deprecated Use {@link IsDownloading}. */\n public set isDownloading(value) {\n this.IsDownloading = value;\n }\n public errorMessage = '';\n public CurrentPage = 1;\n\n /** @deprecated Use {@link CurrentPage}. */\n public get currentPage() {\n return this.CurrentPage;\n }\n /** @deprecated Use {@link CurrentPage}. */\n public set currentPage(value) {\n this.CurrentPage = value;\n }\n public TotalPages = 1;\n\n /** @deprecated Use {@link TotalPages}. */\n public get totalPages() {\n return this.TotalPages;\n }\n /** @deprecated Use {@link TotalPages}. */\n public set totalPages(value) {\n this.TotalPages = value;\n }\n public ZoomLevel = 1.0;\n\n /** @deprecated Use {@link ZoomLevel}. */\n public get zoomLevel() {\n return this.ZoomLevel;\n }\n /** @deprecated Use {@link ZoomLevel}. */\n public set zoomLevel(value) {\n this.ZoomLevel = value;\n }\n\n private pdfDoc: PdfDocumentProxy | null = null;\n private renderTask: PdfRenderTask | null = null;\n private downloadUrl = '';\n private _pdfjsLib: PdfJsLib | null = null;\n\n /** Discrete zoom steps — 50 % to 400 %. */\n private readonly ZOOM_STEPS = [0.5, 0.67, 0.75, 1.0, 1.25, 1.5, 2.0, 3.0, 4.0];\n /** Base render scale (logical pixels per PDF point at zoom 1.0). */\n private readonly BASE_SCALE = 1.5;\n\n constructor(\n private fileService: ArtifactFileService,\n private cdr: ChangeDetectorRef,\n ) {\n super();\n }\n\n public override get hasDisplayContent(): boolean {\n return true;\n }\n\n /** Current zoom as an integer percentage for toolbar display. */\n public get ZoomPercent(): number {\n return Math.round(this.ZoomLevel * 100);\n }\n\n /** @deprecated Use {@link ZoomPercent}. */\n public get zoomPercent(): number {\n return this.ZoomPercent;\n }\n\n public get CanZoomIn(): boolean {\n return this.ZoomLevel < this.ZOOM_STEPS[this.ZOOM_STEPS.length - 1];\n }\n\n /** @deprecated Use {@link CanZoomIn}. */\n public get canZoomIn(): boolean {\n return this.CanZoomIn;\n }\n\n public get CanZoomOut(): boolean {\n return this.ZoomLevel > this.ZOOM_STEPS[0];\n }\n\n /** @deprecated Use {@link CanZoomOut}. */\n public get canZoomOut(): boolean {\n return this.CanZoomOut;\n }\n\n async ngOnInit(): Promise<void> {\n await this.loadPdf();\n }\n\n ngOnDestroy(): void {\n this.cancelCurrentRender();\n this.pdfDoc?.destroy();\n this.pdfDoc = null;\n }\n\n // ─── Navigation ─────────────────────────────────────────────────────────────\n\n public async GoToNextPage(): Promise<void> {\n await this.OnPageChange(this.CurrentPage + 1);\n }\n\n /** @deprecated Use {@link GoToNextPage}. */\n public async goToNextPage(): Promise<void> {\n return this.GoToNextPage();\n }\n\n public async GoToPrevPage(): Promise<void> {\n await this.OnPageChange(this.CurrentPage - 1);\n }\n\n /** @deprecated Use {@link GoToPrevPage}. */\n public async goToPrevPage(): Promise<void> {\n return this.GoToPrevPage();\n }\n\n public async OnPageChange(page: number): Promise<void> {\n const clamped = Math.max(1, Math.min(page, this.TotalPages));\n if (clamped !== this.CurrentPage) {\n this.CurrentPage = clamped;\n await this.renderPage(this.CurrentPage);\n }\n }\n\n /** @deprecated Use {@link OnPageChange}. */\n public async onPageChange(page: number): Promise<void> {\n return this.OnPageChange(page);\n }\n\n // ─── Zoom ────────────────────────────────────────────────────────────────────\n\n public async OnZoomIn(): Promise<void> {\n const next = this.ZOOM_STEPS.find((z) => z > this.ZoomLevel);\n if (next !== undefined) {\n this.ZoomLevel = next;\n await this.renderPage(this.CurrentPage);\n }\n }\n\n /** @deprecated Use {@link OnZoomIn}. */\n public async onZoomIn(): Promise<void> {\n return this.OnZoomIn();\n }\n\n public async OnZoomOut(): Promise<void> {\n for (let i = this.ZOOM_STEPS.length - 1; i >= 0; i--) {\n if (this.ZOOM_STEPS[i] < this.ZoomLevel) {\n this.ZoomLevel = this.ZOOM_STEPS[i];\n await this.renderPage(this.CurrentPage);\n return;\n }\n }\n }\n\n /** @deprecated Use {@link OnZoomOut}. */\n public async onZoomOut(): Promise<void> {\n return this.OnZoomOut();\n }\n\n public async OnZoomReset(): Promise<void> {\n if (this.ZoomLevel !== 1.0) {\n this.ZoomLevel = 1.0;\n await this.renderPage(this.CurrentPage);\n }\n }\n\n /** @deprecated Use {@link OnZoomReset}. */\n public async onZoomReset(): Promise<void> {\n return this.OnZoomReset();\n }\n\n // ─── Download / Print ───────────────────────────────────────────────────────\n\n public async OnDownload(): Promise<void> {\n if (!this.downloadUrl || this.IsDownloading) {\n return;\n }\n this.IsDownloading = true;\n this.cdr.markForCheck();\n try {\n await this.triggerBrowserDownload(this.downloadUrl, this.artifactVersion?.FileName || 'document.pdf');\n } finally {\n this.IsDownloading = false;\n this.cdr.markForCheck();\n }\n }\n\n /** @deprecated Use {@link OnDownload}. */\n public async onDownload(): Promise<void> {\n return this.OnDownload();\n }\n\n public OnPrint(): void {\n if (!this.downloadUrl) {\n return;\n }\n // Open the PDF in a new tab so the browser's native print dialog handles it\n window.open(this.downloadUrl, '_blank');\n }\n\n /** @deprecated Use {@link OnPrint}. */\n public onPrint(): void {\n return this.OnPrint();\n }\n\n // ─── Private helpers ────────────────────────────────────────────────────────\n\n private async loadPdf(): Promise<void> {\n if (!this.artifactVersion?.ID) {\n this.showError('No artifact version provided.');\n return;\n }\n\n try {\n await this.initPdfJs();\n let pdfDoc: PdfDocumentProxy;\n\n if (this.artifactVersion.ContentMode === 'File') {\n // File-backed: download from storage via pre-auth URL\n this.downloadUrl = await this.fileService.getDownloadUrl(this.artifactVersion.ID);\n pdfDoc = await this.loadPdfDocument(this.downloadUrl);\n } else {\n // Inline: content is a base64 data URL stored in the artifact version\n const content = this.artifactVersion.Content;\n if (!content) {\n this.showError('Artifact has no content.');\n return;\n }\n const arrayBuffer = this.fileService.dataUrlToArrayBuffer(content);\n pdfDoc = await this.loadPdfFromData(new Uint8Array(arrayBuffer));\n // Create an object URL for download/print support\n this.downloadUrl = this.fileService.dataUrlToObjectUrl(content, this.artifactVersion.MimeType || 'application/pdf');\n }\n\n this.pdfDoc = pdfDoc;\n this.TotalPages = pdfDoc.numPages;\n this.CurrentPage = 1;\n this.isLoading = false;\n // detectChanges() forces a synchronous DOM update so the canvas element\n // exists before renderPage() tries to draw on it.\n this.cdr.detectChanges();\n await this.setFitWidthZoom();\n await this.renderPage(1);\n } catch (err) {\n this.showError(`Could not load PDF: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n /**\n * Set the initial zoom so the first page fills the available panel width.\n * Uses the exact ratio rather than snapping to a ZOOM_STEP so the page fits\n * pixel-perfectly. Subsequent +/- presses will snap to the nearest step.\n */\n private async setFitWidthZoom(): Promise<void> {\n if (!this.pdfDoc || !this.CanvasRef?.nativeElement) {\n return;\n }\n const page = (await this.pdfDoc.getPage(1)) as PdfPageProxy;\n // naturalViewport.width is the CSS pixel width of the page at zoom = 1.0\n const naturalViewport = page.getViewport({ scale: this.BASE_SCALE });\n const body = this.CanvasRef.nativeElement.closest('.pdf-viewer__body') as HTMLElement | null;\n const availableWidth = (body?.clientWidth ?? 0) - 32; // 16px padding each side\n if (availableWidth > 0 && naturalViewport.width > 0) {\n const fitZoom = availableWidth / naturalViewport.width;\n this.ZoomLevel = Math.max(this.ZOOM_STEPS[0], Math.min(fitZoom, this.ZOOM_STEPS[this.ZOOM_STEPS.length - 1]));\n }\n }\n\n /** Dynamically import pdfjs-dist and point it at the bundled worker. */\n private async initPdfJs(): Promise<void> {\n const pdfjsLib = (await import('pdfjs-dist')) as unknown as PdfJsLib;\n // pdfjs-dist v4 requires an explicit workerSrc. The worker file is copied to\n // /assets/pdf.worker.min.mjs via the angular.json assets config in MJExplorer.\n pdfjsLib.GlobalWorkerOptions.workerSrc = '/assets/pdf.worker.min.mjs';\n this._pdfjsLib = pdfjsLib;\n }\n\n private async loadPdfDocument(url: string): Promise<PdfDocumentProxy> {\n const pdfjsLib = this._pdfjsLib!;\n const loadingTask = pdfjsLib.getDocument(url);\n return loadingTask.promise;\n }\n\n private async loadPdfFromData(data: Uint8Array): Promise<PdfDocumentProxy> {\n const pdfjsLib = this._pdfjsLib!;\n const loadingTask = pdfjsLib.getDocument({ data });\n return loadingTask.promise;\n }\n\n private async renderPage(pageNum: number): Promise<void> {\n if (!this.pdfDoc || !this.CanvasRef?.nativeElement) {\n return;\n }\n\n this.cancelCurrentRender();\n\n const page = (await this.pdfDoc.getPage(pageNum)) as PdfPageProxy;\n const canvas = this.CanvasRef.nativeElement;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n return;\n }\n\n const pixelRatio = window.devicePixelRatio || 1;\n // Scale = base * zoom * devicePixelRatio so backing buffer is always HiDPI-sharp.\n const viewport = page.getViewport({ scale: this.BASE_SCALE * this.ZoomLevel * pixelRatio });\n\n // Backing buffer: full HiDPI resolution.\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n\n // CSS logical pixel dimensions at the current zoom level.\n const cssWidth = viewport.width / pixelRatio;\n const cssHeight = viewport.height / pixelRatio;\n\n canvas.style.width = `${cssWidth}px`;\n // aspect-ratio + height:auto: when cssWidth is set explicitly and the page\n // renders at its natural size, the browser derives height proportionally.\n // Pages wider than the panel scroll horizontally — the body handles overflow.\n canvas.style.aspectRatio = `${cssWidth} / ${cssHeight}`;\n canvas.style.height = 'auto';\n\n const renderContext = { canvasContext: ctx, viewport };\n this.renderTask = page.render(renderContext) as PdfRenderTask;\n await this.renderTask.promise;\n this.renderTask = null;\n this.cdr.markForCheck();\n }\n\n private cancelCurrentRender(): void {\n if (this.renderTask) {\n this.renderTask.cancel();\n this.renderTask = null;\n }\n }\n\n private showError(message: string): void {\n this.isLoading = false;\n this.errorMessage = message;\n this.cdr.markForCheck();\n }\n\n public override GetCurrentStateSnapshot(): DataSnapshot | null {\n const snap = new DataSnapshot();\n snap.title = this.getDisplayTitle() ?? undefined;\n snap.interpretation = `PDF document, ${this.TotalPages} page${this.TotalPages !== 1 ? 's' : ''}. Currently viewing page ${this.CurrentPage}.`;\n snap.custom = {\n pageCount: this.TotalPages,\n currentPage: this.CurrentPage,\n fileName: this.artifactVersion.FileName ?? undefined,\n mimeType: this.artifactVersion.MimeType ?? 'application/pdf',\n contentMode: this.artifactVersion.ContentMode,\n };\n return snap;\n }\n}\n\n// ─── Minimal type shims for pdfjs-dist dynamic import ─────────────────────────\n// We avoid a hard build-time dependency on pdfjs-dist types by declaring only\n// the surface we actually use.\n\ninterface PdfDocumentProxy {\n numPages: number;\n getPage(pageNumber: number): Promise<PdfPageProxy>;\n destroy(): void;\n}\n\ninterface PdfPageProxy {\n getViewport(params: { scale: number }): { width: number; height: number };\n render(renderContext: { canvasContext: CanvasRenderingContext2D; viewport: { width: number; height: number } }): PdfRenderTask;\n}\n\ninterface PdfRenderTask {\n promise: Promise<void>;\n cancel(): void;\n}\n\ninterface PdfJsLib {\n GlobalWorkerOptions: { workerSrc: string };\n getDocument(source: string | { data: Uint8Array }): { promise: Promise<PdfDocumentProxy> };\n}\n"]}
@@ -26,7 +26,11 @@ export declare class SaveQueryPanelComponent extends BaseAngularComponent {
26
26
  Plan: string;
27
27
  Saved: EventEmitter<SaveQueryResult>;
28
28
  Cancelled: EventEmitter<void>;
29
- categoryTree: TreeDropdownComponent;
29
+ CategoryTree: TreeDropdownComponent;
30
+ /** @deprecated Use {@link CategoryTree}. */
31
+ get categoryTree(): TreeDropdownComponent;
32
+ /** @deprecated Use {@link CategoryTree}. */
33
+ set categoryTree(value: TreeDropdownComponent);
30
34
  Name: string;
31
35
  Description: string;
32
36
  IsSaving: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"save-query-dialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/plugins/save-query-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAsC,iBAAiB,EAAgB,MAAM,eAAe,CAAC;AAC5I,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAY,YAAY,EAA4B,MAAM,sBAAsB,CAAC;AAGxF,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;;AAEjE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,qBAwca,uBAAwB,SAAQ,oBAAoB;IAuCnD,OAAO,CAAC,GAAG;IAtCd,SAAS,SAAM;IACf,gBAAgB,SAAM;IACtB,GAAG,SAAM;IACT,IAAI,SAAM;IAET,KAAK,gCAAuC;IAC5C,SAAS,qBAA4B;IAEpB,YAAY,EAAG,qBAAqB,CAAC;IAGzD,IAAI,SAAM;IACV,WAAW,SAAM;IACjB,QAAQ,UAAS;IACjB,YAAY,SAAM;IAClB,SAAS,UAAS;IAGzB,OAAO,CAAC,kBAAkB,CAAuB;IAC1C,mBAAmB,EAAE,YAAY,GAAG,IAAI,CAAQ;IAGhD,kBAAkB,UAAS;IAC3B,wBAAwB,UAAS;IACjC,eAAe,SAAM;IACrB,mBAAmB,SAAM;IAChC,OAAO,CAAC,mBAAmB,CAAuB;IAElD,+CAA+C;IACxC,oBAAoB,EAAE,gBAAgB,CAO3C;gBAEkB,GAAG,EAAE,iBAAiB;IAG1C,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED,QAAQ,IAAI,IAAI;IAaT,WAAW,IAAI,IAAI;IAYnB,iBAAiB,CAAC,SAAS,EAAE,QAAQ,GAAG,QAAQ,EAAE,GAAG,IAAI,GAAG,IAAI;IAchE,mBAAmB,IAAI,IAAI;IAQ3B,oBAAoB,IAAI,IAAI;IAQ5B,0BAA0B,CAAC,SAAS,EAAE,QAAQ,GAAG,QAAQ,EAAE,GAAG,IAAI,GAAG,IAAI;IAUnE,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IA0D/B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAuD7B,QAAQ,IAAI,IAAI;IAWvB,OAAO,CAAC,qBAAqB;yCA3OlB,uBAAuB;2CAAvB,uBAAuB;CAkPnC"}
1
+ {"version":3,"file":"save-query-dialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/plugins/save-query-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAsC,iBAAiB,EAAgB,MAAM,eAAe,CAAC;AAC5I,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAY,YAAY,EAA4B,MAAM,sBAAsB,CAAC;AAGxF,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;;AAEjE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,qBAwca,uBAAwB,SAAQ,oBAAoB;IAgDnD,OAAO,CAAC,GAAG;IA/Cd,SAAS,SAAM;IACf,gBAAgB,SAAM;IACtB,GAAG,SAAM;IACT,IAAI,SAAM;IAET,KAAK,gCAAuC;IAC5C,SAAS,qBAA4B;IAEpB,YAAY,EAAG,qBAAqB,CAAC;IAEhE,4CAA4C;IAC5C,IAAI,YAAY,IAAI,qBAAqB,CAExC;IACD,4CAA4C;IAC5C,IAAI,YAAY,CAAC,KAAK,EAAE,qBAAqB,EAE5C;IAGM,IAAI,SAAM;IACV,WAAW,SAAM;IACjB,QAAQ,UAAS;IACjB,YAAY,SAAM;IAClB,SAAS,UAAS;IAGzB,OAAO,CAAC,kBAAkB,CAAuB;IAC1C,mBAAmB,EAAE,YAAY,GAAG,IAAI,CAAQ;IAGhD,kBAAkB,UAAS;IAC3B,wBAAwB,UAAS;IACjC,eAAe,SAAM;IACrB,mBAAmB,SAAM;IAChC,OAAO,CAAC,mBAAmB,CAAuB;IAElD,+CAA+C;IACxC,oBAAoB,EAAE,gBAAgB,CAO3C;gBAEkB,GAAG,EAAE,iBAAiB;IAG1C,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED,QAAQ,IAAI,IAAI;IAaT,WAAW,IAAI,IAAI;IAYnB,iBAAiB,CAAC,SAAS,EAAE,QAAQ,GAAG,QAAQ,EAAE,GAAG,IAAI,GAAG,IAAI;IAchE,mBAAmB,IAAI,IAAI;IAQ3B,oBAAoB,IAAI,IAAI;IAQ5B,0BAA0B,CAAC,SAAS,EAAE,QAAQ,GAAG,QAAQ,EAAE,GAAG,IAAI,GAAG,IAAI;IAUnE,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IA0D/B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAuD7B,QAAQ,IAAI,IAAI;IAWvB,OAAO,CAAC,qBAAqB;yCApPlB,uBAAuB;2CAAvB,uBAAuB;CA2PnC"}
@@ -107,7 +107,15 @@ export class SaveQueryPanelComponent extends BaseAngularComponent {
107
107
  Plan = '';
108
108
  Saved = new EventEmitter();
109
109
  Cancelled = new EventEmitter();
110
- categoryTree;
110
+ CategoryTree;
111
+ /** @deprecated Use {@link CategoryTree}. */
112
+ get categoryTree() {
113
+ return this.CategoryTree;
114
+ }
115
+ /** @deprecated Use {@link CategoryTree}. */
116
+ set categoryTree(value) {
117
+ this.CategoryTree = value;
118
+ }
111
119
  // Form state
112
120
  Name = '';
113
121
  Description = '';
@@ -218,7 +226,7 @@ export class SaveQueryPanelComponent extends BaseAngularComponent {
218
226
  if (saved) {
219
227
  MJNotificationService.Instance.CreateSimpleNotification(`Category "${name}" created`, 'success', 2500);
220
228
  // Refresh tree to pick up the new category
221
- await this.categoryTree.Refresh();
229
+ await this.CategoryTree.Refresh();
222
230
  // Auto-select the newly created category.
223
231
  // Must use detectChanges() (not markForCheck) to immediately propagate
224
232
  // the new Value input to the tree dropdown, since this panel uses OnPush.
@@ -326,7 +334,7 @@ export class SaveQueryPanelComponent extends BaseAngularComponent {
326
334
  i0.ɵɵviewQuery(_c0, 5);
327
335
  } if (rf & 2) {
328
336
  let _t;
329
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.categoryTree = _t.first);
337
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.CategoryTree = _t.first);
330
338
  } }, hostBindings: function SaveQueryPanelComponent_HostBindings(rf, ctx) { if (rf & 1) {
331
339
  i0.ɵɵlistener("keydown.escape", function SaveQueryPanelComponent_keydown_escape_HostBindingHandler() { return ctx.OnEscapeKey(); }, i0.ɵɵresolveDocument);
332
340
  } }, inputs: { QueryName: "QueryName", QueryDescription: "QueryDescription", SQL: "SQL", Plan: "Plan" }, outputs: { Saved: "Saved", Cancelled: "Cancelled" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 36, vars: 17, consts: [["categoryTree", ""], [1, "sqp-backdrop", 3, "click"], [1, "sqp-panel"], [1, "sqp-header"], [1, "sqp-title-group"], [1, "fa-solid", "fa-save", "sqp-title-icon"], [1, "sqp-title"], [1, "sqp-close-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "sqp-body"], [1, "sqp-field"], [1, "sqp-label"], [1, "sqp-required"], ["type", "text", "placeholder", "Query name", 1, "sqp-input", 3, "ngModelChange", "keydown.enter", "ngModel"], [1, "sqp-label-row"], ["title", "Create new category", 1, "sqp-add-btn"], [3, "SelectionChange", "BranchConfig", "SelectionMode", "SelectableTypes", "Placeholder", "Value"], [1, "sqp-create-category"], ["placeholder", "Optional description", "rows", "3", 1, "sqp-textarea", 3, "ngModelChange", "ngModel"], [1, "sqp-error"], [1, "sqp-footer"], [1, "sqp-btn", "sqp-btn-save", 3, "click", "disabled"], [1, "sqp-btn", "sqp-btn-cancel", 3, "click", "disabled"], ["title", "Create new category", 1, "sqp-add-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "sqp-create-header"], [1, "fa-solid", "fa-folder-plus"], [1, "sqp-create-fields"], ["type", "text", "placeholder", "Category name", 1, "sqp-input", 3, "ngModelChange", "keydown.enter", "keydown.escape", "ngModel"], [1, "sqp-create-parent"], [1, "sqp-sublabel"], [3, "SelectionChange", "BranchConfig", "SelectionMode", "SelectableTypes", "Placeholder"], [1, "sqp-create-actions"], [1, "sqp-btn", "sqp-btn-create", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-check"], [1, "sqp-btn", "sqp-btn-cancel-create", 3, "click", "disabled"], [1, "sqp-inline-error"], [1, "fa-solid", "fa-exclamation-circle"], [1, "fa-solid", "fa-save"]], template: function SaveQueryPanelComponent_Template(rf, ctx) { if (rf & 1) {
@@ -558,7 +566,7 @@ export class SaveQueryPanelComponent extends BaseAngularComponent {
558
566
  type: Output
559
567
  }], Cancelled: [{
560
568
  type: Output
561
- }], categoryTree: [{
569
+ }], CategoryTree: [{
562
570
  type: ViewChild,
563
571
  args: ['categoryTree']
564
572
  }], OnEscapeKey: [{