@memberjunction/ng-artifacts 6.2.0-edge.0 → 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.
- package/dist/lib/components/artifact-message-card.component.d.ts +60 -8
- package/dist/lib/components/artifact-message-card.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-message-card.component.js +135 -39
- package/dist/lib/components/artifact-message-card.component.js.map +1 -1
- package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts +58 -6
- package/dist/lib/components/artifact-type-plugin-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-type-plugin-viewer.component.js +107 -29
- package/dist/lib/components/artifact-type-plugin-viewer.component.js.map +1 -1
- package/dist/lib/components/artifact-version-download.d.ts +5 -3
- package/dist/lib/components/artifact-version-download.d.ts.map +1 -1
- package/dist/lib/components/artifact-version-download.js +11 -7
- package/dist/lib/components/artifact-version-download.js.map +1 -1
- package/dist/lib/components/artifact-version-history.component.d.ts +74 -8
- package/dist/lib/components/artifact-version-history.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-version-history.component.js +152 -34
- package/dist/lib/components/artifact-version-history.component.js.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.d.ts +328 -35
- package/dist/lib/components/artifact-viewer-panel.component.d.ts.map +1 -1
- package/dist/lib/components/artifact-viewer-panel.component.js +701 -213
- package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
- package/dist/lib/components/file-artifact-toolbar.component.d.ts +112 -10
- package/dist/lib/components/file-artifact-toolbar.component.d.ts.map +1 -1
- package/dist/lib/components/file-artifact-toolbar.component.js +197 -23
- package/dist/lib/components/file-artifact-toolbar.component.js.map +1 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts +9 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/audio-artifact-viewer.component.js +20 -4
- package/dist/lib/components/plugins/audio-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/code-artifact-viewer.component.d.ts +23 -5
- package/dist/lib/components/plugins/code-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/code-artifact-viewer.component.js +69 -31
- package/dist/lib/components/plugins/code-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts +136 -18
- package/dist/lib/components/plugins/component-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/component-artifact-viewer.component.js +285 -97
- package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.d.ts +2 -2
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js +7 -7
- package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js.map +1 -1
- package/dist/lib/components/plugins/component-permission-evaluation.d.ts +2 -0
- package/dist/lib/components/plugins/component-permission-evaluation.d.ts.map +1 -1
- package/dist/lib/components/plugins/component-permission-evaluation.js +6 -2
- package/dist/lib/components/plugins/component-permission-evaluation.js.map +1 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts +17 -6
- package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/data-artifact-viewer.component.js +32 -22
- package/dist/lib/components/plugins/data-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.d.ts +56 -4
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js +142 -36
- package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/docx-artifact-viewer.component.d.ts +14 -2
- package/dist/lib/components/plugins/docx-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/docx-artifact-viewer.component.js +32 -8
- package/dist/lib/components/plugins/docx-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/html-artifact-viewer.component.d.ts +17 -3
- package/dist/lib/components/plugins/html-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/html-artifact-viewer.component.js +36 -8
- package/dist/lib/components/plugins/html-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts +41 -5
- package/dist/lib/components/plugins/image-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/image-artifact-viewer.component.js +102 -30
- package/dist/lib/components/plugins/image-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts +33 -5
- package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/json-artifact-viewer.component.js +89 -33
- package/dist/lib/components/plugins/json-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.d.ts +12 -2
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.js +28 -8
- package/dist/lib/components/plugins/markdown-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts +4 -0
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js +14 -6
- package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.d.ts +47 -5
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.js +129 -45
- package/dist/lib/components/plugins/pdf-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/save-query-dialog.component.d.ts +5 -1
- package/dist/lib/components/plugins/save-query-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/save-query-dialog.component.js +12 -4
- package/dist/lib/components/plugins/save-query-dialog.component.js.map +1 -1
- package/dist/lib/components/plugins/svg-artifact-viewer.component.d.ts +17 -3
- package/dist/lib/components/plugins/svg-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/svg-artifact-viewer.component.js +36 -8
- package/dist/lib/components/plugins/svg-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts +9 -1
- package/dist/lib/components/plugins/video-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/video-artifact-viewer.component.js +20 -4
- package/dist/lib/components/plugins/video-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.d.ts +28 -4
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js +64 -16
- package/dist/lib/components/plugins/xlsx-artifact-viewer.component.js.map +1 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.d.ts +9 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/audio-artifact-preview.component.js +20 -4
- package/dist/lib/components/previews/audio-artifact-preview.component.js.map +1 -1
- package/dist/lib/components/previews/image-artifact-preview.component.d.ts +16 -2
- package/dist/lib/components/previews/image-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/image-artifact-preview.component.js +35 -7
- package/dist/lib/components/previews/image-artifact-preview.component.js.map +1 -1
- package/dist/lib/components/previews/video-artifact-preview.component.d.ts +9 -1
- package/dist/lib/components/previews/video-artifact-preview.component.d.ts.map +1 -1
- package/dist/lib/components/previews/video-artifact-preview.component.js +20 -4
- package/dist/lib/components/previews/video-artifact-preview.component.js.map +1 -1
- package/dist/lib/interfaces/artifact-viewer-plugin.interface.js.map +1 -1
- package/dist/lib/services/artifact-file.service.d.ts +8 -0
- package/dist/lib/services/artifact-file.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-file.service.js +22 -6
- package/dist/lib/services/artifact-file.service.js.map +1 -1
- package/dist/lib/services/artifact-icon.service.d.ts +2 -0
- package/dist/lib/services/artifact-icon.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-icon.service.js +5 -1
- package/dist/lib/services/artifact-icon.service.js.map +1 -1
- package/dist/lib/services/artifact-preview-resolver.service.d.ts +2 -0
- package/dist/lib/services/artifact-preview-resolver.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-preview-resolver.service.js +5 -1
- package/dist/lib/services/artifact-preview-resolver.service.js.map +1 -1
- package/dist/lib/snapshot-helpers.d.ts +10 -0
- package/dist/lib/snapshot-helpers.d.ts.map +1 -1
- package/dist/lib/snapshot-helpers.js +25 -5
- package/dist/lib/snapshot-helpers.js.map +1 -1
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
159
|
+
return this.GoToPrevPage();
|
|
100
160
|
}
|
|
101
|
-
async
|
|
102
|
-
const clamped = Math.max(1, Math.min(page, this.
|
|
103
|
-
if (clamped !== this.
|
|
104
|
-
this.
|
|
105
|
-
await this.renderPage(this.
|
|
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
|
|
110
|
-
const next = this.ZOOM_STEPS.find((z) => z > this.
|
|
173
|
+
async OnZoomIn() {
|
|
174
|
+
const next = this.ZOOM_STEPS.find((z) => z > this.ZoomLevel);
|
|
111
175
|
if (next !== undefined) {
|
|
112
|
-
this.
|
|
113
|
-
await this.renderPage(this.
|
|
176
|
+
this.ZoomLevel = next;
|
|
177
|
+
await this.renderPage(this.CurrentPage);
|
|
114
178
|
}
|
|
115
179
|
}
|
|
116
|
-
|
|
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.
|
|
119
|
-
this.
|
|
120
|
-
await this.renderPage(this.
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
|
133
|
-
if (!this.downloadUrl || this.
|
|
208
|
+
async OnDownload() {
|
|
209
|
+
if (!this.downloadUrl || this.IsDownloading) {
|
|
134
210
|
return;
|
|
135
211
|
}
|
|
136
|
-
this.
|
|
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.
|
|
218
|
+
this.IsDownloading = false;
|
|
143
219
|
this.cdr.markForCheck();
|
|
144
220
|
}
|
|
145
221
|
}
|
|
146
|
-
|
|
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.
|
|
181
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
360
|
+
snap.interpretation = `PDF document, ${this.TotalPages} page${this.TotalPages !== 1 ? 's' : ''}. Currently viewing page ${this.CurrentPage}.`;
|
|
277
361
|
snap.custom = {
|
|
278
|
-
pageCount: this.
|
|
279
|
-
currentPage: this.
|
|
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.
|
|
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 }], {
|
|
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
|
-
|
|
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;
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
}],
|
|
569
|
+
}], CategoryTree: [{
|
|
562
570
|
type: ViewChild,
|
|
563
571
|
args: ['categoryTree']
|
|
564
572
|
}], OnEscapeKey: [{
|