@xpert-ai/plugin-live-dashboard 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/.xpertai-plugin/plugin.json +1 -1
  2. package/README.md +4 -0
  3. package/dist/lib/agent.schema.d.ts +179 -25
  4. package/dist/lib/agent.schema.js +10 -9
  5. package/dist/lib/archive.service.d.ts +145 -0
  6. package/dist/lib/archive.service.js +133 -0
  7. package/dist/lib/content.provider.d.ts +1 -1
  8. package/dist/lib/dashboard-archive.d.ts +70 -0
  9. package/dist/lib/dashboard-archive.js +118 -0
  10. package/dist/lib/dashboard-sources.d.ts +69 -0
  11. package/dist/lib/dashboard-sources.js +37 -0
  12. package/dist/lib/dashboard-view.schema.d.ts +503 -88
  13. package/dist/lib/dashboard-view.schema.js +2 -1
  14. package/dist/lib/dashboard.schema.d.ts +379 -58
  15. package/dist/lib/dashboard.schema.js +18 -1
  16. package/dist/lib/dashboard.service.d.ts +72 -17
  17. package/dist/lib/dashboard.service.js +21 -3
  18. package/dist/lib/document-package.d.ts +19 -4
  19. package/dist/lib/editing-patch.d.ts +3 -0
  20. package/dist/lib/editing-patch.js +2 -1
  21. package/dist/lib/editing-session.d.ts +4 -4
  22. package/dist/lib/editing.d.ts +202 -19
  23. package/dist/lib/editing.js +5 -2
  24. package/dist/lib/html-validation-feedback.d.ts +7 -0
  25. package/dist/lib/html-validation-feedback.js +19 -0
  26. package/dist/lib/html-validation.js +2 -1
  27. package/dist/lib/inspection-host.d.ts +7 -0
  28. package/dist/lib/inspection-host.js +48 -0
  29. package/dist/lib/inspection-runtime.d.ts +2 -0
  30. package/dist/lib/inspection-runtime.js +77 -0
  31. package/dist/lib/json-input.d.ts +4 -0
  32. package/dist/lib/json-input.js +21 -0
  33. package/dist/lib/middleware.js +3 -2
  34. package/dist/lib/plugin.js +2 -1
  35. package/dist/lib/presentation.provider.d.ts +24 -9
  36. package/dist/lib/presentation.provider.js +2 -1
  37. package/dist/lib/projects.schema.d.ts +14 -0
  38. package/dist/lib/projects.schema.js +2 -1
  39. package/dist/lib/projects.service.d.ts +2 -0
  40. package/dist/lib/projects.service.js +10 -0
  41. package/dist/lib/source-executions.d.ts +196 -0
  42. package/dist/lib/source-executions.js +25 -0
  43. package/dist/lib/source-validation.d.ts +2 -0
  44. package/dist/lib/source-validation.js +21 -0
  45. package/dist/lib/view.provider.d.ts +211 -12
  46. package/dist/lib/view.provider.js +43 -9
  47. package/dist/remote/app.css +1 -1
  48. package/dist/remote/app.js +99 -26
  49. package/dist/remote/build-manifest.json +42 -27
  50. package/docs/docs.json +3 -1
  51. package/docs/sources-inspect-portability-acceptance.mdx +67 -0
  52. package/docs/sources-inspect-portability.mdx +115 -0
  53. package/package.json +6 -5
  54. package/skills/live-dashboard/SKILL.md +5 -4
  55. package/skills/live-dashboard/references/source-inspection.md +17 -0
@@ -1,8 +1,9 @@
1
1
  import { DashboardProjectsService } from './projects.service';
2
- import type { XpertExtensionViewManifest, XpertResolvedViewHostContext, XpertViewActionRequest, XpertViewQuery } from '@xpert-ai/contracts';
3
- import { type IXpertViewExtensionProvider } from '@xpert-ai/plugin-sdk';
2
+ import type { XpertExtensionViewManifest, XpertResolvedViewHostContext, XpertViewActionRequest, XpertViewQuery, XpertViewFileAccessRequest } from '@xpert-ai/contracts';
3
+ import { type IXpertViewExtensionProvider, type XpertViewFileActionFile } from '@xpert-ai/plugin-sdk';
4
4
  import { DashboardService } from './dashboard.service';
5
5
  import { DashboardSharingService } from './sharing.service';
6
+ import { DashboardArchiveService } from './archive.service';
6
7
  export declare const VIEW_KEY = "live-dashboard";
7
8
  export declare const VIEW_PROVIDER = "live-dashboard";
8
9
  export declare const FEATURE = "live_dashboard";
@@ -10,7 +11,8 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
10
11
  private readonly service;
11
12
  private readonly sharing;
12
13
  private readonly projects;
13
- constructor(service: DashboardService, sharing: DashboardSharingService, projects: DashboardProjectsService);
14
+ private readonly archives;
15
+ constructor(service: DashboardService, sharing: DashboardSharingService, projects: DashboardProjectsService, archives: DashboardArchiveService);
14
16
  supports(context: XpertResolvedViewHostContext): boolean;
15
17
  getViewManifests(context: XpertResolvedViewHostContext, slot: string): XpertExtensionViewManifest[];
16
18
  getRemoteComponentEntry(): Promise<{
@@ -33,12 +35,21 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
33
35
  dashboards: {
34
36
  title: string | null | undefined;
35
37
  draftRevision?: number | undefined;
38
+ updatedAt: string | Date | undefined;
36
39
  canDelete: boolean;
37
40
  artifactId: string;
38
41
  versionId: string | null | undefined;
39
42
  versionNumber: number | undefined;
40
- updatedAt: string | Date | undefined;
41
43
  }[];
44
+ selectedDashboard: {
45
+ title: string | null | undefined;
46
+ draftRevision?: number | undefined;
47
+ updatedAt: string | Date | undefined;
48
+ canDelete: boolean;
49
+ artifactId: string;
50
+ versionId: string | null | undefined;
51
+ versionNumber: number | undefined;
52
+ } | undefined;
42
53
  pagination: {
43
54
  page: number;
44
55
  pageSize: number;
@@ -48,9 +59,9 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
48
59
  } | {
49
60
  saved: {
50
61
  manifest: {
51
- schema: "xpert.live-dashboard";
52
- id: string;
53
62
  title: string;
63
+ id: string;
64
+ schema: "xpert.live-dashboard";
54
65
  bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
55
66
  controls: {
56
67
  type: "string" | "number" | "boolean" | "date";
@@ -60,20 +71,35 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
60
71
  allowedValues?: (string | number | boolean | null)[] | undefined;
61
72
  }[];
62
73
  charts: {
74
+ title: string;
63
75
  type: "bar" | "line" | "area" | "pie" | "scatter";
64
76
  id: string;
65
- title: string;
66
77
  datasetId: string;
67
78
  x: string;
68
79
  y: string;
69
80
  color?: string | undefined;
70
81
  }[];
71
82
  tables: {
72
- id: string;
73
83
  title: string;
84
+ id: string;
74
85
  datasetId: string;
75
86
  fields: string[];
76
87
  }[];
88
+ sourceMetadata?: {
89
+ bindingId: string;
90
+ title: string;
91
+ description?: string | undefined;
92
+ }[] | undefined;
93
+ components?: {
94
+ title: string;
95
+ id: string;
96
+ elementId: string;
97
+ kind: "filter" | "metric" | "chart" | "table" | "text";
98
+ sources: {
99
+ bindingId: string;
100
+ fieldIds?: string[] | undefined;
101
+ }[];
102
+ }[] | undefined;
77
103
  presentation?: {
78
104
  type: "html";
79
105
  html: string;
@@ -91,7 +117,7 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
91
117
  artifactId: string;
92
118
  versionId: string | null | undefined;
93
119
  versionNumber: number | undefined;
94
- };
120
+ } | undefined;
95
121
  versions: {
96
122
  current: boolean;
97
123
  artifactId: string;
@@ -113,12 +139,21 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
113
139
  dashboards: {
114
140
  title: string | null | undefined;
115
141
  draftRevision?: number | undefined;
142
+ updatedAt: string | Date | undefined;
116
143
  canDelete: boolean;
117
144
  artifactId: string;
118
145
  versionId: string | null | undefined;
119
146
  versionNumber: number | undefined;
120
- updatedAt: string | Date | undefined;
121
147
  }[];
148
+ selectedDashboard: {
149
+ title: string | null | undefined;
150
+ draftRevision?: number | undefined;
151
+ updatedAt: string | Date | undefined;
152
+ canDelete: boolean;
153
+ artifactId: string;
154
+ versionId: string | null | undefined;
155
+ versionNumber: number | undefined;
156
+ } | undefined;
122
157
  pagination: {
123
158
  page: number;
124
159
  pageSize: number;
@@ -139,12 +174,21 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
139
174
  dashboards: {
140
175
  title: string | null | undefined;
141
176
  draftRevision?: number | undefined;
177
+ updatedAt: string | Date | undefined;
142
178
  canDelete: boolean;
143
179
  artifactId: string;
144
180
  versionId: string | null | undefined;
145
181
  versionNumber: number | undefined;
146
- updatedAt: string | Date | undefined;
147
182
  }[];
183
+ selectedDashboard: {
184
+ title: string | null | undefined;
185
+ draftRevision?: number | undefined;
186
+ updatedAt: string | Date | undefined;
187
+ canDelete: boolean;
188
+ artifactId: string;
189
+ versionId: string | null | undefined;
190
+ versionNumber: number | undefined;
191
+ } | undefined;
148
192
  pagination: {
149
193
  page: number;
150
194
  pageSize: number;
@@ -154,16 +198,28 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
154
198
  };
155
199
  }>;
156
200
  executeViewAction(context: XpertResolvedViewHostContext, viewKey: string, action: string, request: XpertViewActionRequest): Promise<{
201
+ success: boolean;
202
+ data: import("@xpert-ai/contracts").AnalyticsDiscoveryResult;
203
+ refresh: boolean;
204
+ } | {
157
205
  success: boolean;
158
206
  data: {
207
+ discarded: boolean;
208
+ };
209
+ refresh: boolean;
210
+ } | {
211
+ success: boolean;
212
+ data: {
213
+ canEdit: boolean;
214
+ mode: string;
159
215
  items: {
160
216
  title: string | null | undefined;
161
217
  draftRevision?: number | undefined;
218
+ updatedAt: string | Date | undefined;
162
219
  canDelete: boolean;
163
220
  artifactId: string;
164
221
  versionId: string | null | undefined;
165
222
  versionNumber: number | undefined;
166
- updatedAt: string | Date | undefined;
167
223
  }[];
168
224
  page: number;
169
225
  hasMore: boolean;
@@ -210,9 +266,152 @@ export declare class DashboardViewProvider implements IXpertViewExtensionProvide
210
266
  artifactId: string;
211
267
  };
212
268
  refresh: boolean;
269
+ } | {
270
+ success: boolean;
271
+ data: {
272
+ payload?: {
273
+ ok: boolean;
274
+ widget_type: string;
275
+ surface: string;
276
+ sources: never[];
277
+ manifest: {
278
+ version: number;
279
+ surface: string;
280
+ title: string;
281
+ cards: never[];
282
+ filters: never[];
283
+ sources: never[];
284
+ charts: {
285
+ id: string;
286
+ title: string;
287
+ type: "bar" | "line" | "area" | "pie" | "scatter";
288
+ dataset: string;
289
+ encodings: {
290
+ color?: {
291
+ field: string;
292
+ } | undefined;
293
+ x: {
294
+ field: string;
295
+ };
296
+ y: {
297
+ field: string;
298
+ };
299
+ };
300
+ }[];
301
+ tables: {
302
+ id: string;
303
+ title: string;
304
+ dataset: string;
305
+ columns: {
306
+ field: string;
307
+ label: string;
308
+ }[];
309
+ }[];
310
+ blocks: ({
311
+ id: string;
312
+ type: string;
313
+ chartId: string;
314
+ } | {
315
+ id: string;
316
+ type: string;
317
+ tableId: string;
318
+ })[];
319
+ };
320
+ snapshot: {
321
+ version: number;
322
+ generatedAt: string;
323
+ status: string;
324
+ datasets: any;
325
+ };
326
+ } | undefined;
327
+ datasets: import("@xpert-ai/contracts").AnalyticalDataset[];
328
+ failures: {
329
+ bindingId: string;
330
+ datasetId: string;
331
+ reason: "unavailable";
332
+ }[];
333
+ };
334
+ refresh: boolean;
213
335
  } | {
214
336
  success: boolean;
215
337
  data: import("@xpert-ai/contracts").AnalyticalDataset;
216
338
  refresh: boolean;
217
339
  }>;
340
+ executeViewFileAction(context: XpertResolvedViewHostContext, viewKey: string, action: string, _request: XpertViewActionRequest, file: XpertViewFileActionFile): Promise<{
341
+ success: boolean;
342
+ data: {
343
+ importId: `${string}-${string}-${string}-${string}-${string}`;
344
+ manifest: {
345
+ title: string;
346
+ id: string;
347
+ schema: "xpert.live-dashboard";
348
+ bindings: import("@xpert-ai/contracts").AnalyticsBinding[];
349
+ controls: {
350
+ type: "string" | "number" | "boolean" | "date";
351
+ controlId: string;
352
+ label: string;
353
+ defaultValue?: string | number | boolean | null | undefined;
354
+ allowedValues?: (string | number | boolean | null)[] | undefined;
355
+ }[];
356
+ charts: {
357
+ title: string;
358
+ type: "bar" | "line" | "area" | "pie" | "scatter";
359
+ id: string;
360
+ datasetId: string;
361
+ x: string;
362
+ y: string;
363
+ color?: string | undefined;
364
+ }[];
365
+ tables: {
366
+ title: string;
367
+ id: string;
368
+ datasetId: string;
369
+ fields: string[];
370
+ }[];
371
+ sourceMetadata?: {
372
+ bindingId: string;
373
+ title: string;
374
+ description?: string | undefined;
375
+ }[] | undefined;
376
+ components?: {
377
+ title: string;
378
+ id: string;
379
+ elementId: string;
380
+ kind: "filter" | "metric" | "chart" | "table" | "text";
381
+ sources: {
382
+ bindingId: string;
383
+ fieldIds?: string[] | undefined;
384
+ }[];
385
+ }[] | undefined;
386
+ presentation?: {
387
+ type: "html";
388
+ html: string;
389
+ dependencies?: import("@xpert-ai/plugin-sdk/artifact-document").ArtifactDocumentDependencyLock[] | undefined;
390
+ } | undefined;
391
+ };
392
+ requirements: {
393
+ schema: string;
394
+ version: number;
395
+ bindings: {
396
+ id: string;
397
+ providerId: string;
398
+ operation: string;
399
+ contractVersion: number;
400
+ source: import("@xpert-ai/contracts").AnalyticsSourceRef;
401
+ }[];
402
+ externalResources: string[];
403
+ dynamicResourcesMayExist: boolean;
404
+ includesQueryResults: boolean;
405
+ requiresAuthorizedHost: boolean;
406
+ };
407
+ sources: import("@xpert-ai/contracts").AnalyticsSourceSummary[];
408
+ };
409
+ refresh: boolean;
410
+ }>;
411
+ resolveViewFile(context: XpertResolvedViewHostContext, viewKey: string, request: XpertViewFileAccessRequest): Promise<{
412
+ reference: import("@xpert-ai/plugin-sdk").WorkspacePortableFileReference;
413
+ fileName: string;
414
+ mimeType: string;
415
+ size: number;
416
+ }>;
218
417
  }
@@ -11,6 +11,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.DashboardViewProvider = exports.FEATURE = exports.VIEW_PROVIDER = exports.VIEW_KEY = void 0;
13
13
  const projects_service_1 = require("./projects.service");
14
+ const projects_schema_1 = require("./projects.schema");
14
15
  const common_1 = require("@nestjs/common");
15
16
  const v3_1 = require("zod/v3");
16
17
  const contracts_1 = require("@xpert-ai/contracts");
@@ -23,15 +24,18 @@ const dashboard_receipt_1 = require("./dashboard-receipt");
23
24
  const dashboard_navigation_1 = require("./dashboard-navigation");
24
25
  const project_1 = require("./project");
25
26
  const dashboard_icon_1 = require("./dashboard-icon");
27
+ const dashboard_sources_1 = require("./dashboard-sources");
28
+ const archive_service_1 = require("./archive.service");
26
29
  exports.VIEW_KEY = 'live-dashboard';
27
30
  exports.VIEW_PROVIDER = 'live-dashboard';
28
31
  exports.FEATURE = 'live_dashboard';
29
32
  const text = (en_US, zh_Hans) => ({ en_US, zh_Hans });
30
33
  let DashboardViewProvider = class DashboardViewProvider {
31
- constructor(service, sharing, projects) {
34
+ constructor(service, sharing, projects, archives) {
32
35
  this.service = service;
33
36
  this.sharing = sharing;
34
37
  this.projects = projects;
38
+ this.archives = archives;
35
39
  }
36
40
  supports(context) { return context.hostType === 'agent'; }
37
41
  getViewManifests(context, slot) {
@@ -43,6 +47,7 @@ let DashboardViewProvider = class DashboardViewProvider {
43
47
  workbench: { projectType: project_1.DASHBOARD_PROJECT_TYPE, fixed: true, openMode: 'on-demand', menu: { enabled: true, label: text('Live dashboards', '实时看板'), icon: dashboard_icon_1.dashboardIcon, order: 35 } },
44
48
  view: { type: 'remote_component', runtime: 'react', protocolVersion: 1, component: { isolation: 'iframe', entry: exports.VIEW_KEY }, dataSource: { mode: 'platform' } },
45
49
  dataSource: { mode: 'platform', querySchema: { supportsSelection: true, supportsParameters: true, supportsPagination: true, defaultPageSize: 50 }, cache: { enabled: false } },
50
+ fileAccess: { purposes: ['download'] },
46
51
  clientCommands: [{ key: 'workbench.content.status' }, { key: 'workbench.content.resolve' }, { key: contracts_1.ASSISTANT_CONTEXT_SET_COMMAND, label: text('Select dashboard for Assistant', '设置助理当前看板') },
47
52
  { key: contracts_1.ASSISTANT_CHAT_SEND_MESSAGE_COMMAND, label: text('Create with Assistant', '交给助理制作') },
48
53
  { key: contracts_1.ARTIFACT_PRESENTATION_OPEN_COMMAND, label: text('Open shared page', '打开独立页面') },
@@ -50,6 +55,8 @@ let DashboardViewProvider = class DashboardViewProvider {
50
55
  hostEvents: { subscriptions: [{ key: 'dashboard-created', event: 'assistant.tool.completed',
51
56
  filter: { toolNames: dashboard_receipt_1.DASHBOARD_MUTATION_TOOLS }, action: { type: 'forward', debounceMs: 0 } }] },
52
57
  actions: [
58
+ { key: 'import-preview', label: text('Import dashboard file', '导入看板文件'), actionType: 'invoke', transport: 'file' },
59
+ ...['import-commit', 'import-discard', 'import-browse'].map(key => ({ key, label: text('Import dashboard', '导入看板'), actionType: 'invoke' })),
53
60
  ...[
54
61
  { key: 'dashboards', label: text('Select dashboard', '选择看板') },
55
62
  { key: 'projects', label: text('Select project', '选择项目') },
@@ -74,22 +81,35 @@ let DashboardViewProvider = class DashboardViewProvider {
74
81
  if (mode === 'draft' && !access.canReadDraft)
75
82
  throw new common_1.ForbiddenException('DASHBOARD_DRAFT_ACCESS_DENIED');
76
83
  const page = await this.service.listPage(context, params.page, params.pageSize);
84
+ const selectedDashboard = params.artifactId
85
+ ? page.items.find(item => item.artifactId === params.artifactId) ?? await this.service.selectedSummary(context, params.artifactId)
86
+ : undefined;
77
87
  const versions = params.artifactId ? await this.service.history(context, params.artifactId) : undefined;
78
88
  const unavailable = params.artifactId && mode === 'published' && !params.versionId && !versions?.some(version => version.current);
89
+ const saved = !unavailable && params.artifactId ? await this.service.openDocument(context, params.artifactId, params.versionId, params.draftRevision, mode) : undefined;
79
90
  return { meta: { navigationTarget: (0, dashboard_navigation_1.dashboardNavigationTarget)(context), access, mode, currentProject,
80
- dashboards: page.items, pagination: { page: page.page, pageSize: page.pageSize, hasMore: page.hasMore },
91
+ dashboards: page.items, selectedDashboard, pagination: { page: page.page, pageSize: page.pageSize, hasMore: page.hasMore },
81
92
  sources: access.canEdit ? await this.service.sources(context) : [],
82
93
  ...(unavailable ? { notice: 'not_published' } : params.artifactId ? {
83
- saved: await this.service.openDocument(context, params.artifactId, params.versionId, params.draftRevision, mode), versions
94
+ saved: saved && { ...saved, manifest: access.canEdit ? saved.manifest : (0, dashboard_sources_1.publicDashboardManifest)(saved.manifest) }, versions
84
95
  } : {}) } };
85
96
  }
86
97
  async executeViewAction(context, viewKey, action, request) {
87
98
  assertView(viewKey);
99
+ if (action === 'import-commit')
100
+ return { success: true, data: await this.archives.commit(context, archive_service_1.importInputSchema.parse(request.input)), refresh: false };
101
+ if (action === 'import-browse')
102
+ return { success: true, data: await this.archives.browse(context, archive_service_1.importBrowseSchema.parse(request.input)), refresh: false };
103
+ if (action === 'import-discard')
104
+ return { success: true, data: await this.archives.discard(context, v3_1.z.object({ importId: v3_1.z.string().uuid() }).strict().parse(request.input).importId), refresh: false };
88
105
  if (action === 'dashboards') {
89
- const parsed = projects_service_1.projectSearchSchema.safeParse(request.input);
106
+ const parsed = projects_schema_1.dashboardSearchSchema.safeParse(request.input);
90
107
  if (!parsed.success)
91
108
  throw new common_1.BadRequestException('DASHBOARD_INVALID_PICKER_QUERY');
92
- return { success: true, data: await this.service.searchPage(context, parsed.data), refresh: false };
109
+ const target = parsed.data.projectId ? await this.projects.pickerContext(context, parsed.data.projectId) : context;
110
+ const page = await this.service.searchPage(target, parsed.data);
111
+ const access = await this.service.access(target);
112
+ return { success: true, data: { ...page, canEdit: access.canEdit, mode: access.canReadDraft ? 'draft' : 'published' }, refresh: false };
93
113
  }
94
114
  if (action === 'projects')
95
115
  return { success: true, data: await this.projects.list(context, projects_service_1.projectSearchSchema.parse(request.input)), refresh: false };
@@ -100,11 +120,12 @@ let DashboardViewProvider = class DashboardViewProvider {
100
120
  return { success: true, data: action === 'share-status' ? await this.sharing.inspect(context, input.artifactId, input.versionId) : await this.sharing.revoke(context, input.artifactId), refresh: false };
101
121
  }
102
122
  if (action === 'delete') {
103
- const parsed = v3_1.z.object({ artifactId: v3_1.z.string().uuid(), expectedRevision: v3_1.z.number().int().positive(), confirmed: v3_1.z.literal(true) }).strict().safeParse(request.input);
123
+ const parsed = v3_1.z.object({ artifactId: v3_1.z.string().uuid(), expectedRevision: v3_1.z.number().int().positive(), confirmed: v3_1.z.literal(true), projectId: v3_1.z.string().uuid().optional() }).strict().safeParse(request.input);
104
124
  if (!parsed.success)
105
125
  throw new common_1.BadRequestException('DASHBOARD_DELETION_CONFIRMATION_REQUIRED');
106
126
  const input = parsed.data;
107
- return { success: true, data: await this.service.trash(context, input.artifactId, input.expectedRevision), refresh: false };
127
+ const target = input.projectId ? await this.projects.pickerContext(context, input.projectId) : context;
128
+ return { success: true, data: await this.service.trash(target, input.artifactId, input.expectedRevision), refresh: false };
108
129
  }
109
130
  if (action === 'publish') {
110
131
  const parsed = v3_1.z.object({ artifactId: v3_1.z.string().uuid(), expectedRevision: v3_1.z.number().int().positive(),
@@ -120,7 +141,8 @@ let DashboardViewProvider = class DashboardViewProvider {
120
141
  }
121
142
  if (action === 'query') {
122
143
  const input = dashboard_schema_1.querySchema.parse(request.input);
123
- return { success: true, data: await this.service.query(context, input.artifactId, input.versionId, input.controls, input.draftRevision), refresh: false };
144
+ const result = await this.service.query(context, input.artifactId, input.versionId, input.controls, input.draftRevision);
145
+ return { success: true, data: { datasets: result.datasets, failures: result.failures, ...('payload' in result ? { payload: result.payload } : {}) }, refresh: false };
124
146
  }
125
147
  if (action === 'query-binding') {
126
148
  const parsed = dashboard_schema_1.queryBindingSchema.safeParse(request.input);
@@ -131,11 +153,23 @@ let DashboardViewProvider = class DashboardViewProvider {
131
153
  }
132
154
  throw new common_1.BadRequestException('DASHBOARD_ACTION_UNSUPPORTED');
133
155
  }
156
+ async executeViewFileAction(context, viewKey, action, _request, file) {
157
+ assertView(viewKey);
158
+ if (action !== 'import-preview')
159
+ throw new common_1.BadRequestException('DASHBOARD_ACTION_UNSUPPORTED');
160
+ return { success: true, data: await this.archives.prepare(context, file.buffer), refresh: false };
161
+ }
162
+ async resolveViewFile(context, viewKey, request) {
163
+ assertView(viewKey);
164
+ if (request.purpose !== 'download')
165
+ throw new common_1.ForbiddenException('DASHBOARD_ACTION_UNSUPPORTED');
166
+ return this.archives.exportFile(context, request.fileKey);
167
+ }
134
168
  };
135
169
  exports.DashboardViewProvider = DashboardViewProvider;
136
170
  exports.DashboardViewProvider = DashboardViewProvider = __decorate([
137
171
  (0, plugin_sdk_1.ViewExtensionProvider)(exports.VIEW_PROVIDER),
138
- __metadata("design:paramtypes", [dashboard_service_1.DashboardService, sharing_service_1.DashboardSharingService, projects_service_1.DashboardProjectsService])
172
+ __metadata("design:paramtypes", [dashboard_service_1.DashboardService, sharing_service_1.DashboardSharingService, projects_service_1.DashboardProjectsService, archive_service_1.DashboardArchiveService])
139
173
  ], DashboardViewProvider);
140
174
  function assertView(key) { if (key !== exports.VIEW_KEY)
141
175
  throw new common_1.BadRequestException('DASHBOARD_VIEW_UNSUPPORTED'); }