@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-permission-evaluation.js","sourceRoot":"","sources":["../../../../src/lib/components/plugins/component-permission-evaluation.ts"],"names":[],"mappings":"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","sourcesContent":["import { IMetadataProvider, Metadata, UserInfo } from '@memberjunction/core';\nimport { ComponentSpec } from '@memberjunction/interactive-component-types';\nimport { QueryEngine } from '@memberjunction/core-entities';\n\n/**\n * Result of evaluating a user's permissions against a component's data requirements.\n */\nexport interface PermissionEvaluationResult {\n /** Whether the user can run all data operations the component requires */\n canRun: boolean
|
|
1
|
+
{"version":3,"file":"component-permission-evaluation.js","sourceRoot":"","sources":["../../../../src/lib/components/plugins/component-permission-evaluation.ts"],"names":[],"mappings":"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","sourcesContent":["import { IMetadataProvider, Metadata, UserInfo } from '@memberjunction/core';\nimport { ComponentSpec } from '@memberjunction/interactive-component-types';\nimport { QueryEngine } from '@memberjunction/core-entities';\n\n/**\n * Result of evaluating a user's permissions against a component's data requirements.\n */\nexport interface PermissionEvaluationResult {\n /** Whether the user can run all data operations the component requires */\n canRun: boolean; // case-violation-ok-legacy-back-compat: the type is named in an exported signature, so consumers build object literals against it; an interface has no runtime carrier for a stub\n /** Entity names the user lacks read permission for */\n missingEntities: string[]; // case-violation-ok-legacy-back-compat: the type is named in an exported signature, so consumers build object literals against it; an interface has no runtime carrier for a stub\n /** Query names the user lacks permission to execute */\n missingQueries: string[]; // case-violation-ok-legacy-back-compat: the type is named in an exported signature, so consumers build object literals against it; an interface has no runtime carrier for a stub\n}\n\n/**\n * Evaluates whether a user has sufficient permissions to run a component\n * based on its declared dataRequirements. Checks both entity-level read\n * permissions and query-level execution permissions.\n *\n * Runs entirely on client-side metadata — no additional server call needed.\n */\nfunction evaluateComponentPermissionsSingle(\n spec: ComponentSpec,\n currentUser: UserInfo,\n provider?: IMetadataProvider\n): PermissionEvaluationResult {\n const missingEntities: string[] = [];\n const missingQueries: string[] = [];\n const dataReqs = spec.dataRequirements;\n\n if (!dataReqs) {\n return { canRun: true, missingEntities: [], missingQueries: [] };\n }\n\n // Check entity permissions (all current components are read-only)\n const md = provider ?? Metadata.Provider;\n for (const entityReq of dataReqs.entities ?? []) {\n const entityInfo = md.EntityByName(entityReq.name);\n if (!entityInfo) continue; // Unknown entity — skip (may be stale reference)\n\n const perms = entityInfo.GetUserPermisions(currentUser);\n if (!perms?.CanRead) {\n missingEntities.push(entityReq.name);\n }\n }\n\n // Check query permissions using centralized UserCanRun logic\n const qe = QueryEngine.Instance;\n for (const queryReq of dataReqs.queries ?? []) {\n if (!queryReq.name) continue;\n\n const queryInfo = qe.FindQueryByName(queryReq.name);\n if (!queryInfo) continue; // Unknown query — skip\n\n const result = queryInfo.UserCanRun(currentUser);\n if (!result.canRun) {\n missingQueries.push(queryReq.name);\n }\n }\n\n return {\n canRun: missingEntities.length === 0 && missingQueries.length === 0,\n missingEntities,\n missingQueries,\n };\n}\n\n/**\n * Recursively evaluates permissions for a component and all its dependencies.\n * Walks the full dependency tree, deduplicating results.\n */\nexport function EvaluateComponentPermissions(\n spec: ComponentSpec,\n currentUser: UserInfo,\n provider?: IMetadataProvider\n): PermissionEvaluationResult {\n const result = evaluateComponentPermissionsSingle(spec, currentUser, provider);\n\n for (const dep of spec.dependencies ?? []) {\n const depResult = EvaluateComponentPermissions(dep, currentUser, provider);\n result.missingEntities.push(...depResult.missingEntities);\n result.missingQueries.push(...depResult.missingQueries);\n }\n\n // Deduplicate\n result.missingEntities = [...new Set(result.missingEntities)];\n result.missingQueries = [...new Set(result.missingQueries)];\n result.canRun = result.missingEntities.length === 0 && result.missingQueries.length === 0;\n\n return result;\n}\n\n/** @deprecated Use {@link EvaluateComponentPermissions}. */\nexport function evaluateComponentPermissions(\n spec: ComponentSpec,\n currentUser: UserInfo,\n provider?: IMetadataProvider\n): PermissionEvaluationResult {\n return EvaluateComponentPermissions(spec, currentUser, provider);\n}\n"]}
|
|
@@ -56,6 +56,17 @@ type QuerySyncState = 'no-query-latest' | 'no-query-older' | 'synced' | 'outdate
|
|
|
56
56
|
*/
|
|
57
57
|
export declare class DataArtifactViewerComponent extends BaseArtifactViewerPluginComponent implements OnInit {
|
|
58
58
|
private cdr;
|
|
59
|
+
OpenEntityRecord: EventEmitter<{
|
|
60
|
+
entityName: string;
|
|
61
|
+
compositeKey: CompositeKey;
|
|
62
|
+
}>;
|
|
63
|
+
/**
|
|
64
|
+
* @deprecated Use {@link OpenEntityRecord}.
|
|
65
|
+
*
|
|
66
|
+
* The same emitter under the old binding name, so a template still binding
|
|
67
|
+
* (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields
|
|
68
|
+
* initialise in order, and the other way round this captures undefined.
|
|
69
|
+
*/
|
|
59
70
|
openEntityRecord: EventEmitter<{
|
|
60
71
|
entityName: string;
|
|
61
72
|
compositeKey: CompositeKey;
|
|
@@ -147,21 +158,21 @@ export declare class DataArtifactViewerComponent extends BaseArtifactViewerPlugi
|
|
|
147
158
|
* Load data for a specific table.
|
|
148
159
|
* Handles live SQL execution, inline rows, and caching.
|
|
149
160
|
*/
|
|
150
|
-
private
|
|
161
|
+
private loadTableData;
|
|
151
162
|
/**
|
|
152
163
|
* Build QueryGridColumnConfig[] from a DataTable's column metadata.
|
|
153
164
|
* Returns null if columns have no entity metadata (grid falls back to auto-inference).
|
|
154
165
|
*/
|
|
155
|
-
private
|
|
166
|
+
private buildColumnConfigsForTable;
|
|
156
167
|
/**
|
|
157
168
|
* Handle a table load error by setting error state and falling back to inline data
|
|
158
169
|
*/
|
|
159
|
-
private
|
|
170
|
+
private handleTableError;
|
|
160
171
|
/**
|
|
161
172
|
* Initialize query sync state by loading cached metadata.
|
|
162
173
|
* Resolves the latest version number and compares saved query SQL.
|
|
163
174
|
*/
|
|
164
|
-
private
|
|
175
|
+
private initQuerySyncState;
|
|
165
176
|
/**
|
|
166
177
|
* Determine the latest version number for this artifact from cache.
|
|
167
178
|
* Falls back to current version if cache miss.
|
|
@@ -207,7 +218,7 @@ export declare class DataArtifactViewerComponent extends BaseArtifactViewerPlugi
|
|
|
207
218
|
/** Handle successful save from the dialog (both initial save and "save as new") */
|
|
208
219
|
OnQuerySaved(event: SaveQueryResult): Promise<void>;
|
|
209
220
|
/** Persist updated spec back to the artifact version entity */
|
|
210
|
-
private
|
|
221
|
+
private persistArtifactContent;
|
|
211
222
|
/**
|
|
212
223
|
* Returns a DataSnapshot with live grid data, current page state,
|
|
213
224
|
* and query sync state.
|
|
@@ -218,7 +229,7 @@ export declare class DataArtifactViewerComponent extends BaseArtifactViewerPlugi
|
|
|
218
229
|
*/
|
|
219
230
|
GetAdditionalTabs(): ArtifactViewerTab[];
|
|
220
231
|
static ɵfac: i0.ɵɵFactoryDeclaration<DataArtifactViewerComponent, never>;
|
|
221
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<DataArtifactViewerComponent, "mj-data-artifact-viewer", never, {}, { "openEntityRecord": "openEntityRecord"; "navigationRequest": "navigationRequest"; }, never, never, false, never>;
|
|
232
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DataArtifactViewerComponent, "mj-data-artifact-viewer", never, {}, { "OpenEntityRecord": "OpenEntityRecord"; "openEntityRecord": "openEntityRecord"; "navigationRequest": "navigationRequest"; }, never, never, false, never>;
|
|
222
233
|
}
|
|
223
234
|
export {};
|
|
224
235
|
//# sourceMappingURL=data-artifact-viewer.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-artifact-viewer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/plugins/data-artifact-viewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,iBAAiB,EAAU,YAAY,EAAE,MAAM,eAAe,CAAC;AAG3F,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,kBAAkB,EAAyC,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzJ,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAuB,MAAM,iCAAiC,CAAC;AACxH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,iCAAiC,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC5H,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;;AAGhE;;;;;;;;;GASG;AACH,UAAU,gBAAgB;IACxB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC,kBAAkB,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,KAAK,cAAc,GACf,iBAAiB,GACjB,gBAAgB,GAChB,QAAQ,GACR,iBAAiB,GACjB,aAAa,GACb,cAAc,CAAC;AAEnB;;;;;;;;;GASG;AACH,qBAOa,2BAA4B,SAAQ,iCAAkC,YAAW,MAAM;
|
|
1
|
+
{"version":3,"file":"data-artifact-viewer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/plugins/data-artifact-viewer.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ import { DataSnapshot, NormalizeToTables, CompositeKey } from '@memberjunction/c
|
|
|
10
10
|
import { QueryEngine, ArtifactMetadataEngine } from '@memberjunction/core-entities';
|
|
11
11
|
import { resolveTargetEntity } from '@memberjunction/ng-query-viewer';
|
|
12
12
|
import { BaseArtifactViewerPluginComponent } from '../base-artifact-viewer.component';
|
|
13
|
-
import {
|
|
13
|
+
import { BuildMultiTableSql } from '../../snapshot-helpers';
|
|
14
14
|
import * as i0 from "@angular/core";
|
|
15
15
|
import * as i1 from "@angular/common";
|
|
16
16
|
import * as i2 from "@memberjunction/ng-markdown";
|
|
@@ -384,7 +384,15 @@ function DataArtifactViewerComponent_Conditional_4_Template(rf, ctx) { if (rf &
|
|
|
384
384
|
*/
|
|
385
385
|
let DataArtifactViewerComponent = class DataArtifactViewerComponent extends BaseArtifactViewerPluginComponent {
|
|
386
386
|
cdr;
|
|
387
|
-
|
|
387
|
+
OpenEntityRecord = new EventEmitter();
|
|
388
|
+
/**
|
|
389
|
+
* @deprecated Use {@link OpenEntityRecord}.
|
|
390
|
+
*
|
|
391
|
+
* The same emitter under the old binding name, so a template still binding
|
|
392
|
+
* (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields
|
|
393
|
+
* initialise in order, and the other way round this captures undefined.
|
|
394
|
+
*/
|
|
395
|
+
openEntityRecord = this.OpenEntityRecord;
|
|
388
396
|
navigationRequest = new EventEmitter();
|
|
389
397
|
tabsChanged = new EventEmitter();
|
|
390
398
|
spec = null;
|
|
@@ -501,7 +509,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
501
509
|
}
|
|
502
510
|
// Build enriched column configs for the first table
|
|
503
511
|
if (this.ResolvedTables.length > 0) {
|
|
504
|
-
this.GridColumnConfigs = this.
|
|
512
|
+
this.GridColumnConfigs = this.buildColumnConfigsForTable(this.ResolvedTables[0]);
|
|
505
513
|
}
|
|
506
514
|
// Initialize paging state for all tables
|
|
507
515
|
for (let i = 0; i < this.ResolvedTables.length; i++) {
|
|
@@ -512,10 +520,10 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
512
520
|
this.IsLoading = true;
|
|
513
521
|
}
|
|
514
522
|
// Load cached metadata and resolve query sync state
|
|
515
|
-
await this.
|
|
523
|
+
await this.initQuerySyncState();
|
|
516
524
|
// Load data for the first (active) table
|
|
517
525
|
if (this.ResolvedTables.length > 0) {
|
|
518
|
-
await this.
|
|
526
|
+
await this.loadTableData(0);
|
|
519
527
|
}
|
|
520
528
|
// Signal parent that tabs/display content may have changed after async load
|
|
521
529
|
this.tabsChanged.emit();
|
|
@@ -530,7 +538,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
530
538
|
*/
|
|
531
539
|
async OnRefresh() {
|
|
532
540
|
this.tableDataCache.delete(this.ActiveTableIndex);
|
|
533
|
-
await this.
|
|
541
|
+
await this.loadTableData(this.ActiveTableIndex);
|
|
534
542
|
}
|
|
535
543
|
/**
|
|
536
544
|
* Handle entity link click from the grid and bubble up as openEntityRecord.
|
|
@@ -541,7 +549,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
541
549
|
// recordId may be a bare value or a "F1|v1||F2|v2" segment; FromURLSegment reads both against
|
|
542
550
|
// the entity's real primary key(s) instead of assuming a single column.
|
|
543
551
|
const compositeKey = CompositeKey.FromURLSegment(md.EntityByName(event.entityName), event.recordId);
|
|
544
|
-
this.
|
|
552
|
+
this.OpenEntityRecord.emit({
|
|
545
553
|
entityName: event.entityName,
|
|
546
554
|
compositeKey
|
|
547
555
|
});
|
|
@@ -558,7 +566,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
558
566
|
pageState.pageSize = event.PageSize;
|
|
559
567
|
// Clear cache so it reloads
|
|
560
568
|
this.tableDataCache.delete(this.ActiveTableIndex);
|
|
561
|
-
await this.
|
|
569
|
+
await this.loadTableData(this.ActiveTableIndex);
|
|
562
570
|
}
|
|
563
571
|
/**
|
|
564
572
|
* Switch to a different table tab.
|
|
@@ -573,7 +581,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
573
581
|
return;
|
|
574
582
|
// Use cached column configs or build new
|
|
575
583
|
if (!this.tableColumnConfigsCache.has(index)) {
|
|
576
|
-
const configs = this.
|
|
584
|
+
const configs = this.buildColumnConfigsForTable(table);
|
|
577
585
|
if (configs)
|
|
578
586
|
this.tableColumnConfigsCache.set(index, configs);
|
|
579
587
|
}
|
|
@@ -587,7 +595,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
587
595
|
this.PagerTotalRowCount = pageState.totalRowCount;
|
|
588
596
|
}
|
|
589
597
|
else {
|
|
590
|
-
await this.
|
|
598
|
+
await this.loadTableData(index);
|
|
591
599
|
}
|
|
592
600
|
this.cdr.detectChanges();
|
|
593
601
|
}
|
|
@@ -595,7 +603,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
595
603
|
* Load data for a specific table.
|
|
596
604
|
* Handles live SQL execution, inline rows, and caching.
|
|
597
605
|
*/
|
|
598
|
-
async
|
|
606
|
+
async loadTableData(tableIndex) {
|
|
599
607
|
const table = this.ResolvedTables[tableIndex];
|
|
600
608
|
if (!table)
|
|
601
609
|
return;
|
|
@@ -625,7 +633,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
625
633
|
this.liveExecutionTime = result.ExecutionTime;
|
|
626
634
|
}
|
|
627
635
|
else {
|
|
628
|
-
this.
|
|
636
|
+
this.handleTableError(tableIndex, result.ErrorMessage || 'Query failed');
|
|
629
637
|
}
|
|
630
638
|
}
|
|
631
639
|
else if (table.rows && table.rows.length > 0) {
|
|
@@ -639,7 +647,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
639
647
|
}
|
|
640
648
|
}
|
|
641
649
|
catch (error) {
|
|
642
|
-
this.
|
|
650
|
+
this.handleTableError(tableIndex, error instanceof Error ? error.message : 'Load failed');
|
|
643
651
|
}
|
|
644
652
|
finally {
|
|
645
653
|
this.IsLoading = false;
|
|
@@ -650,7 +658,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
650
658
|
* Build QueryGridColumnConfig[] from a DataTable's column metadata.
|
|
651
659
|
* Returns null if columns have no entity metadata (grid falls back to auto-inference).
|
|
652
660
|
*/
|
|
653
|
-
|
|
661
|
+
buildColumnConfigsForTable(table) {
|
|
654
662
|
const columns = table.columns;
|
|
655
663
|
if (!columns?.length)
|
|
656
664
|
return null;
|
|
@@ -699,7 +707,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
699
707
|
/**
|
|
700
708
|
* Handle a table load error by setting error state and falling back to inline data
|
|
701
709
|
*/
|
|
702
|
-
|
|
710
|
+
handleTableError(tableIndex, message) {
|
|
703
711
|
this.HasError = true;
|
|
704
712
|
this.ErrorMessage = message;
|
|
705
713
|
const table = this.ResolvedTables[tableIndex];
|
|
@@ -712,7 +720,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
712
720
|
* Initialize query sync state by loading cached metadata.
|
|
713
721
|
* Resolves the latest version number and compares saved query SQL.
|
|
714
722
|
*/
|
|
715
|
-
async
|
|
723
|
+
async initQuerySyncState() {
|
|
716
724
|
// Ensure the artifact-type registry is loaded (not registered for startup).
|
|
717
725
|
await ArtifactMetadataEngine.Instance.Config(false);
|
|
718
726
|
// Load THIS artifact's versions on demand (including Content, which
|
|
@@ -889,7 +897,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
889
897
|
if (saved) {
|
|
890
898
|
// Update spec with new version tracking
|
|
891
899
|
this.spec.savedAtVersionNumber = this.CurrentVersionNumber;
|
|
892
|
-
await this.
|
|
900
|
+
await this.persistArtifactContent();
|
|
893
901
|
// Refresh caches so future lookups see the updated data
|
|
894
902
|
await QueryEngine.Instance.Config(true);
|
|
895
903
|
await ArtifactMetadataEngine.Instance.Config(true);
|
|
@@ -926,7 +934,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
926
934
|
this.spec.savedQueryName = event.queryName;
|
|
927
935
|
this.spec.savedAtVersionNumber = this.CurrentVersionNumber;
|
|
928
936
|
// Persist and refresh caches
|
|
929
|
-
await this.
|
|
937
|
+
await this.persistArtifactContent();
|
|
930
938
|
await QueryEngine.Instance.Config(true);
|
|
931
939
|
await ArtifactMetadataEngine.Instance.Config(true);
|
|
932
940
|
await this.ProviderToUse.Refresh();
|
|
@@ -943,7 +951,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
943
951
|
}
|
|
944
952
|
}
|
|
945
953
|
/** Persist updated spec back to the artifact version entity */
|
|
946
|
-
async
|
|
954
|
+
async persistArtifactContent() {
|
|
947
955
|
if (!this.artifactVersion || !this.spec)
|
|
948
956
|
return;
|
|
949
957
|
this.artifactVersion.Content = JSON.stringify(this.spec);
|
|
@@ -991,7 +999,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
991
999
|
}
|
|
992
1000
|
// SQL tab — multi-table shows all queries with headers
|
|
993
1001
|
if (this.IsMultiTable) {
|
|
994
|
-
const multiSql =
|
|
1002
|
+
const multiSql = BuildMultiTableSql(this.ResolvedTables);
|
|
995
1003
|
if (multiSql) {
|
|
996
1004
|
tabs.push({
|
|
997
1005
|
label: 'SQL',
|
|
@@ -1023,7 +1031,7 @@ let DataArtifactViewerComponent = class DataArtifactViewerComponent extends Base
|
|
|
1023
1031
|
return tabs;
|
|
1024
1032
|
}
|
|
1025
1033
|
static ɵfac = function DataArtifactViewerComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || DataArtifactViewerComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
1026
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: DataArtifactViewerComponent, selectors: [["mj-data-artifact-viewer"]], outputs: { openEntityRecord: "openEntityRecord", navigationRequest: "navigationRequest" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 3, consts: [[1, "data-artifact-viewer", 3, "ngClass"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load data", "Size", "compact", 3, "Message"], ["Icon", "fa-solid fa-inbox", "Title", "No data to display", "Size", "compact"], [3, "QueryName", "QueryDescription", "SQL", "Plan"], [1, "data-toolbar"], [1, "data-title"], [1, "fas", "fa-table"], [1, "live-badge"], [1, "row-count"], [1, "exec-time"], [1, "data-actions"], ["title", "Refresh data", 1, "btn-icon", 3, "disabled"], ["title", "Save as reusable query", 1, "btn-icon", "btn-save"], [1, "table-tabs"], [1, "computations-bar"], [1, "grid-container"], [1, "saving-overlay"], ["text", "Loading data..."], ["Height", "100%", 3, "ColumnConfigs", "Data", "TotalRowCount", "PageNumber", "PageSize", "ShowToolbar", "ShowRefresh", "PersistState", "SelectionMode"], ["title", "Refresh data", 1, "btn-icon", 3, "click", "disabled"], [1, "fas", "fa-sync-alt"], ["title", "Save as reusable query", 1, "btn-icon", "btn-save", 3, "click"], [1, "fas", "fa-save"], [1, "query-badge", "query-badge-synced"], [1, "fas", "fa-check"], ["title", "Open saved query record", 1, "btn-icon", "btn-open", 3, "click"], [1, "fas", "fa-external-link-alt"], [1, "query-badge", "query-badge-outdated"], [1, "fas", "fa-circle-exclamation"], [1, "dropdown-wrapper"], ["title", "Update or save query", 1, "btn-icon", "btn-warning", 3, "click"], [1, "fas", "fa-caret-down"], [1, "query-dropdown"], [1, "query-dropdown", 3, "click"], [1, "query-dropdown-item", 3, "click"], [1, "fas", "fa-arrow-up-from-bracket", 2, "color", "#d97706"], [1, "dropdown-label"], [1, "dropdown-desc"], [1, "fas", "fa-plus", 2, "color", "#16a34a"], [1, "fas", "fa-external-link-alt", 2, "color", "var(--mj-text-muted)"], [1, "query-badge", "query-badge-muted"], [1, "fas", "fa-clock-rotate-left"], ["title", "Open saved query record", 1, "btn-icon", "btn-muted", 3, "click"], [1, "table-tab", 3, "active", "title"], [1, "table-tab", 3, "click", "title"], [1, "table-tab-name"], [1, "table-tab-count"], [1, "computation-chip", 3, "title"], [1, "computation-label"], [1, "computation-value"], [3, "text"], ["Variant", "warning", "Size", "sm", 1, "data-artifact-alert-pos"], [1, "fallback-note"], ["Height", "100%", 3, "EntityLinkClick", "PageChange", "ColumnConfigs", "Data", "TotalRowCount", "PageNumber", "PageSize", "ShowToolbar", "ShowRefresh", "PersistState", "SelectionMode"], [1, "fas", "fa-diagram-project"], [1, "plan-content"], [3, "data", "enableMermaid", "enableHighlight", "enableCollapsibleHeadings", "enableSmartypants"], [3, "Saved", "Cancelled", "QueryName", "QueryDescription", "SQL", "Plan"]], template: function DataArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1034
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: DataArtifactViewerComponent, selectors: [["mj-data-artifact-viewer"]], outputs: { OpenEntityRecord: "OpenEntityRecord", openEntityRecord: "openEntityRecord", navigationRequest: "navigationRequest" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 3, consts: [[1, "data-artifact-viewer", 3, "ngClass"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load data", "Size", "compact", 3, "Message"], ["Icon", "fa-solid fa-inbox", "Title", "No data to display", "Size", "compact"], [3, "QueryName", "QueryDescription", "SQL", "Plan"], [1, "data-toolbar"], [1, "data-title"], [1, "fas", "fa-table"], [1, "live-badge"], [1, "row-count"], [1, "exec-time"], [1, "data-actions"], ["title", "Refresh data", 1, "btn-icon", 3, "disabled"], ["title", "Save as reusable query", 1, "btn-icon", "btn-save"], [1, "table-tabs"], [1, "computations-bar"], [1, "grid-container"], [1, "saving-overlay"], ["text", "Loading data..."], ["Height", "100%", 3, "ColumnConfigs", "Data", "TotalRowCount", "PageNumber", "PageSize", "ShowToolbar", "ShowRefresh", "PersistState", "SelectionMode"], ["title", "Refresh data", 1, "btn-icon", 3, "click", "disabled"], [1, "fas", "fa-sync-alt"], ["title", "Save as reusable query", 1, "btn-icon", "btn-save", 3, "click"], [1, "fas", "fa-save"], [1, "query-badge", "query-badge-synced"], [1, "fas", "fa-check"], ["title", "Open saved query record", 1, "btn-icon", "btn-open", 3, "click"], [1, "fas", "fa-external-link-alt"], [1, "query-badge", "query-badge-outdated"], [1, "fas", "fa-circle-exclamation"], [1, "dropdown-wrapper"], ["title", "Update or save query", 1, "btn-icon", "btn-warning", 3, "click"], [1, "fas", "fa-caret-down"], [1, "query-dropdown"], [1, "query-dropdown", 3, "click"], [1, "query-dropdown-item", 3, "click"], [1, "fas", "fa-arrow-up-from-bracket", 2, "color", "#d97706"], [1, "dropdown-label"], [1, "dropdown-desc"], [1, "fas", "fa-plus", 2, "color", "#16a34a"], [1, "fas", "fa-external-link-alt", 2, "color", "var(--mj-text-muted)"], [1, "query-badge", "query-badge-muted"], [1, "fas", "fa-clock-rotate-left"], ["title", "Open saved query record", 1, "btn-icon", "btn-muted", 3, "click"], [1, "table-tab", 3, "active", "title"], [1, "table-tab", 3, "click", "title"], [1, "table-tab-name"], [1, "table-tab-count"], [1, "computation-chip", 3, "title"], [1, "computation-label"], [1, "computation-value"], [3, "text"], ["Variant", "warning", "Size", "sm", 1, "data-artifact-alert-pos"], [1, "fallback-note"], ["Height", "100%", 3, "EntityLinkClick", "PageChange", "ColumnConfigs", "Data", "TotalRowCount", "PageNumber", "PageSize", "ShowToolbar", "ShowRefresh", "PersistState", "SelectionMode"], [1, "fas", "fa-diagram-project"], [1, "plan-content"], [3, "data", "enableMermaid", "enableHighlight", "enableCollapsibleHeadings", "enableSmartypants"], [3, "Saved", "Cancelled", "QueryName", "QueryDescription", "SQL", "Plan"]], template: function DataArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1027
1035
|
i0.ɵɵelementStart(0, "div", 0);
|
|
1028
1036
|
i0.ɵɵconditionalCreate(1, DataArtifactViewerComponent_Conditional_1_Template, 3, 1)(2, DataArtifactViewerComponent_Conditional_2_Template, 1, 1, "mj-empty-state", 1)(3, DataArtifactViewerComponent_Conditional_3_Template, 1, 0, "mj-empty-state", 2);
|
|
1029
1037
|
i0.ɵɵconditionalCreate(4, DataArtifactViewerComponent_Conditional_4_Template, 1, 4, "mj-save-query-panel", 3);
|
|
@@ -1043,7 +1051,9 @@ export { DataArtifactViewerComponent };
|
|
|
1043
1051
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DataArtifactViewerComponent, [{
|
|
1044
1052
|
type: Component,
|
|
1045
1053
|
args: [{ standalone: false, selector: 'mj-data-artifact-viewer', template: "<div class=\"data-artifact-viewer\" [ngClass]=\"cssClass\">\n @if (spec) {\n @if (HasData || IsLoading || ResolvedTables.length > 0) {\n <!-- Toolbar -->\n <div class=\"data-toolbar\">\n <div class=\"data-title\">\n <i class=\"fas fa-table\"></i>\n <span>{{ spec.title || \"Data Results\" }}</span>\n @if (IsLive) {\n <span class=\"live-badge\">Live</span>\n }\n @if (DisplayRowCount != null) {\n <span class=\"row-count\">{{ DisplayRowCount | number }} rows</span>\n }\n @if (DisplayExecutionTime != null) {\n <span class=\"exec-time\">{{ DisplayExecutionTime }}ms</span>\n }\n </div>\n <div class=\"data-actions\">\n @if (IsLive) {\n <button class=\"btn-icon\" title=\"Refresh data\" (click)=\"OnRefresh()\" [disabled]=\"IsLoading\">\n <i class=\"fas fa-sync-alt\" [class.fa-spin]=\"IsLoading\"></i> Refresh\n </button>\n }\n\n @switch (QuerySyncState) {\n <!-- S1: No saved query, latest version \u2192 Save Query -->\n @case (\"no-query-latest\") {\n <button class=\"btn-icon btn-save\" title=\"Save as reusable query\" (click)=\"OnShowSaveDialog()\"><i class=\"fas fa-save\"></i> Save Query</button>\n }\n\n <!-- S2: SQL matches \u2192 green badge + Open -->\n @case (\"synced\") {\n <span class=\"query-badge query-badge-synced\"> <i class=\"fas fa-check\"></i> Saved at v{{ SavedAtVersion }} </span>\n <button class=\"btn-icon btn-open\" title=\"Open saved query record\" (click)=\"OnOpenSavedQuery()\">\n <i class=\"fas fa-external-link-alt\"></i> Open Query\n </button>\n }\n\n <!-- S3: SQL differs, latest version \u2192 amber badge + dropdown -->\n @case (\"outdated-latest\") {\n <span class=\"query-badge query-badge-outdated\"> <i class=\"fas fa-circle-exclamation\"></i> Saved at v{{ SavedAtVersion }} </span>\n <div class=\"dropdown-wrapper\">\n <button class=\"btn-icon btn-warning\" title=\"Update or save query\" (click)=\"OnToggleUpdateDropdown()\">\n <i class=\"fas fa-save\"></i> Update Query <i class=\"fas fa-caret-down\"></i>\n </button>\n @if (ShowUpdateDropdown) {\n <div class=\"query-dropdown\" (click)=\"$event.stopPropagation()\">\n <div class=\"query-dropdown-item\" (click)=\"OnUpdateExistingQuery()\">\n <i class=\"fas fa-arrow-up-from-bracket\" style=\"color: #d97706\"></i>\n <div>\n <div class=\"dropdown-label\">Update \"{{ SavedQueryDisplayName }}\"</div>\n <div class=\"dropdown-desc\">Replace saved query SQL with this version's SQL</div>\n </div>\n </div>\n <div class=\"query-dropdown-item\" (click)=\"OnSaveAsNewQuery()\">\n <i class=\"fas fa-plus\" style=\"color: #16a34a\"></i>\n <div>\n <div class=\"dropdown-label\">Save as New Query</div>\n <div class=\"dropdown-desc\">Create a new query, keep the original unchanged</div>\n </div>\n </div>\n <div class=\"query-dropdown-item\" (click)=\"OnOpenSavedQuery(); OnCloseDropdown()\">\n <i class=\"fas fa-external-link-alt\" style=\"color: var(--mj-text-muted)\"></i>\n <div>\n <div class=\"dropdown-label\">Open Saved Query</div>\n <div class=\"dropdown-desc\">View \"{{ SavedQueryDisplayName }}\" (saved at v{{ SavedAtVersion }})</div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- S4: Older version, query was updated ahead -->\n @case (\"query-ahead\") {\n <span class=\"query-badge query-badge-muted\"> <i class=\"fas fa-clock-rotate-left\"></i> Query updated at v{{ SavedAtVersion }} </span>\n <button class=\"btn-icon btn-muted\" title=\"Open saved query record\" (click)=\"OnOpenSavedQuery()\">\n <i class=\"fas fa-external-link-alt\"></i> Open Query\n </button>\n }\n\n <!-- S5: Middle version, saved at older, not latest -->\n @case (\"query-behind\") {\n <span class=\"query-badge query-badge-muted\"> <i class=\"fas fa-clock-rotate-left\"></i> Saved at v{{ SavedAtVersion }} </span>\n <button class=\"btn-icon btn-muted\" title=\"Open saved query record\" (click)=\"OnOpenSavedQuery()\">\n <i class=\"fas fa-external-link-alt\"></i> Open Query\n </button>\n }\n\n <!-- S6: No saved query, older version \u2192 no actions -->\n @case (\"no-query-older\") {\n <!-- No query actions available on older versions -->\n }\n }\n </div>\n </div>\n\n <!-- Multi-table tab strip -->\n @if (IsMultiTable) {\n <div class=\"table-tabs\">\n @for (table of ResolvedTables; track table.name; let i = $index) {\n <button class=\"table-tab\" [class.active]=\"i === ActiveTableIndex\" [title]=\"table.description || table.name\" (click)=\"OnTableTabClick(i)\">\n <span class=\"table-tab-name\">{{ table.name }}</span>\n @if (table.metadata?.rowCount != null || table.rows.length) {\n <span class=\"table-tab-count\"> ({{ table.metadata?.rowCount ?? table.rows.length }} rows) </span>\n }\n </button>\n }\n </div>\n }\n\n <!-- Computations summary bar -->\n @if (spec.computations?.length) {\n <div class=\"computations-bar\">\n @for (comp of spec.computations; track comp.name) {\n @if (!IsMultiTable || !comp.table || comp.table === ActiveTable?.name) {\n <div class=\"computation-chip\" [title]=\"comp.description || comp.name\">\n <span class=\"computation-label\">{{ comp.name }}</span>\n <span class=\"computation-value\">\n {{ comp.formattedValue || comp.value }}\n </span>\n </div>\n }\n }\n </div>\n }\n\n <!-- Grid -->\n <div class=\"grid-container\">\n <!-- Saving overlay -->\n @if (IsSaving) {\n <div class=\"saving-overlay\">\n <mj-loading [text]=\"SavingMessage\"></mj-loading>\n </div>\n }\n @if (IsLoading) {\n <mj-loading text=\"Loading data...\"></mj-loading>\n } @else if (HasError && HasData) {\n <mj-alert Variant=\"warning\" Size=\"sm\" class=\"data-artifact-alert-pos\">\n {{ ErrorMessage }}\n <span class=\"fallback-note\">(Showing cached data)</span>\n </mj-alert>\n <mj-query-data-grid\n [ColumnConfigs]=\"GridColumnConfigs\"\n [Data]=\"GridData\"\n [TotalRowCount]=\"PagerTotalRowCount\"\n [PageNumber]=\"PagerPageNumber\"\n [PageSize]=\"PagerPageSize\"\n [ShowToolbar]=\"false\"\n [ShowRefresh]=\"false\"\n [PersistState]=\"false\"\n [SelectionMode]=\"'none'\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\"\n (PageChange)=\"OnPageChange($event)\"\n Height=\"100%\"\n >\n </mj-query-data-grid>\n } @else if (HasError) {\n <mj-empty-state\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load data\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n } @else {\n <mj-query-data-grid\n [ColumnConfigs]=\"GridColumnConfigs\"\n [Data]=\"GridData\"\n [TotalRowCount]=\"PagerTotalRowCount\"\n [PageNumber]=\"PagerPageNumber\"\n [PageSize]=\"PagerPageSize\"\n [ShowToolbar]=\"false\"\n [ShowRefresh]=\"false\"\n [PersistState]=\"false\"\n [SelectionMode]=\"'none'\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\"\n (PageChange)=\"OnPageChange($event)\"\n Height=\"100%\"\n >\n </mj-query-data-grid>\n }\n </div>\n } @else if (spec.plan) {\n <!-- Plan-only view (no results yet) -->\n <div class=\"data-toolbar\">\n <div class=\"data-title\">\n <i class=\"fas fa-diagram-project\"></i>\n <span>{{ spec.title || \"Query Plan\" }}</span>\n </div>\n </div>\n <div class=\"plan-content\">\n <mj-markdown [data]=\"spec.plan\" [enableMermaid]=\"true\" [enableHighlight]=\"true\" [enableCollapsibleHeadings]=\"false\" [enableSmartypants]=\"true\">\n </mj-markdown>\n </div>\n } @else {\n <!-- No data and no plan -->\n <mj-empty-state\n Icon=\"fa-solid fa-inbox\"\n Title=\"No data to display\"\n Size=\"compact\" />\n }\n } @else if (HasError) {\n <mj-empty-state\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load data\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n } @else {\n <mj-empty-state\n Icon=\"fa-solid fa-inbox\"\n Title=\"No data to display\"\n Size=\"compact\" />\n }\n\n <!-- Save Query Panel (slide-in) -->\n @if (ShowSaveDialog) {\n <mj-save-query-panel\n [QueryName]=\"spec?.title || 'Untitled Query'\"\n [QueryDescription]=\"''\"\n [SQL]=\"spec?.metadata?.sql || ''\"\n [Plan]=\"spec?.plan || ''\"\n (Saved)=\"OnQuerySaved($event)\"\n (Cancelled)=\"ShowSaveDialog = false\"\n >\n </mj-save-query-panel>\n }\n</div>\n", styles: [".data-artifact-viewer {\n display: flex;\n flex-direction: column;\n height: 100%;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n.data-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.data-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.data-title i {\n color: var(--mj-text-muted);\n}\n\n.row-count {\n padding: 2px 8px;\n background: var(--mj-border-default);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.exec-time {\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-status-success);\n}\n\n.live-badge {\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n}\n\n.data-actions {\n display: flex;\n gap: 6px;\n}\n\n.btn-icon {\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n font-size: 11px;\n display: flex;\n align-items: center;\n gap: 4px;\n color: var(--mj-text-secondary);\n}\n\n.btn-icon:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-icon:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.btn-icon.btn-save {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-bg-surface));\n}\n\n.btn-icon.btn-save:hover {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n border-color: var(--mj-status-success);\n}\n\n.btn-icon.btn-open {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n}\n\n.btn-icon.btn-open:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n}\n\n.grid-container {\n flex: 1;\n overflow: hidden;\n min-height: 200px;\n height: 500px;\n position: relative;\n}\n\n/* Saving overlay \u2014 semi-transparent panel over the grid */\n.saving-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 80%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 50;\n}\n\n/* Positioning only \u2014 mj-alert owns its own box (bg/border/radius/padding/icon). */\n.data-artifact-alert-pos {\n margin: 0 0 8px;\n}\n\n.fallback-note {\n font-style: italic;\n color: var(--mj-text-muted);\n}\n\n.plan-content {\n flex: 1;\n overflow: auto;\n padding: 16px;\n}\n\n/* Query sync badges */\n.query-badge {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n white-space: nowrap;\n}\n\n.query-badge-synced {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.query-badge-outdated {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.query-badge-muted {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n/* Dropdown wrapper */\n.dropdown-wrapper {\n position: relative;\n}\n\n.btn-icon.btn-warning {\n color: var(--mj-status-warning);\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, var(--mj-bg-surface));\n}\n\n.btn-icon.btn-warning:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 8%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.btn-icon.btn-muted {\n color: var(--mj-text-disabled);\n border-color: var(--mj-border-default);\n}\n\n/* Query actions dropdown */\n.query-dropdown {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n overflow: hidden;\n min-width: 280px;\n z-index: 100;\n}\n\n.query-dropdown-item {\n padding: 10px 14px;\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 12px;\n cursor: pointer;\n border-bottom: 1px solid var(--mj-border-default);\n transition: background 0.1s;\n}\n\n.query-dropdown-item:last-child {\n border-bottom: none;\n}\n\n.query-dropdown-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.query-dropdown-item i {\n width: 16px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.dropdown-label {\n font-weight: 500;\n}\n\n.dropdown-desc {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n/* \u2500\u2500\u2500 Table Tab Strip \u2500\u2500\u2500 */\n\n.table-tabs {\n display: flex;\n gap: 0;\n border-bottom: 2px solid var(--mj-border-default);\n padding: 0 var(--mj-spacing-md, 16px);\n background: var(--mj-bg-surface);\n overflow-x: auto;\n}\n\n.table-tab {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-bottom: 2px solid transparent;\n margin-bottom: -2px;\n transition: color 150ms ease, border-color 150ms ease;\n white-space: nowrap;\n}\n\n.table-tab:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.table-tab.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.table-tab-name {\n text-transform: capitalize;\n}\n\n.table-tab-count {\n color: var(--mj-text-muted);\n font-weight: 400;\n font-size: 12px;\n}\n\n.table-tab.active .table-tab-count {\n color: var(--mj-brand-primary);\n opacity: 0.7;\n}\n\n/* \u2500\u2500\u2500 Computations Summary Bar \u2500\u2500\u2500 */\n\n.computations-bar {\n display: flex;\n gap: 12px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-subtle);\n overflow-x: auto;\n flex-wrap: wrap;\n}\n\n.computation-chip {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 13px;\n white-space: nowrap;\n}\n\n.computation-label {\n color: var(--mj-text-secondary);\n font-weight: 400;\n}\n\n.computation-value {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n"] }]
|
|
1046
|
-
}], () => [{ type: i0.ChangeDetectorRef }], {
|
|
1054
|
+
}], () => [{ type: i0.ChangeDetectorRef }], { OpenEntityRecord: [{
|
|
1055
|
+
type: Output
|
|
1056
|
+
}], openEntityRecord: [{
|
|
1047
1057
|
type: Output
|
|
1048
1058
|
}], navigationRequest: [{
|
|
1049
1059
|
type: Output
|