@memberjunction/ng-artifacts 6.1.0-edge.5 → 6.1.0-edge.7

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 (37) hide show
  1. package/dist/lib/components/artifact-viewer-panel.component.d.ts +30 -1
  2. package/dist/lib/components/artifact-viewer-panel.component.d.ts.map +1 -1
  3. package/dist/lib/components/artifact-viewer-panel.component.js +283 -89
  4. package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
  5. package/dist/lib/components/file-artifact-toolbar.component.js +1 -1
  6. package/dist/lib/components/plugins/component-artifact-viewer.component.js +2 -2
  7. package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
  8. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js +1 -1
  9. package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts.map +1 -1
  10. package/dist/lib/components/plugins/data-artifact-viewer.component.js +6 -8
  11. package/dist/lib/components/plugins/data-artifact-viewer.component.js.map +1 -1
  12. package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js +1 -1
  13. package/dist/lib/components/plugins/docx-artifact-viewer.component.js +1 -1
  14. package/dist/lib/components/plugins/image-artifact-viewer.component.js +1 -1
  15. package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts +8 -0
  16. package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts.map +1 -1
  17. package/dist/lib/components/plugins/json-artifact-viewer.component.js +45 -14
  18. package/dist/lib/components/plugins/json-artifact-viewer.component.js.map +1 -1
  19. package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js +1 -1
  20. package/dist/lib/components/plugins/pdf-artifact-viewer.component.js +1 -1
  21. package/dist/lib/components/plugins/save-query-dialog.component.js +7 -7
  22. package/dist/lib/components/plugins/save-query-dialog.component.js.map +1 -1
  23. package/dist/lib/components/previews/audio-artifact-preview.component.d.ts.map +1 -1
  24. package/dist/lib/components/previews/audio-artifact-preview.component.js +15 -9
  25. package/dist/lib/components/previews/audio-artifact-preview.component.js.map +1 -1
  26. package/dist/lib/components/previews/base-artifact-preview.component.d.ts +13 -0
  27. package/dist/lib/components/previews/base-artifact-preview.component.d.ts.map +1 -1
  28. package/dist/lib/components/previews/base-artifact-preview.component.js +20 -0
  29. package/dist/lib/components/previews/base-artifact-preview.component.js.map +1 -1
  30. package/dist/lib/components/previews/image-artifact-preview.component.d.ts +13 -0
  31. package/dist/lib/components/previews/image-artifact-preview.component.d.ts.map +1 -1
  32. package/dist/lib/components/previews/image-artifact-preview.component.js +55 -19
  33. package/dist/lib/components/previews/image-artifact-preview.component.js.map +1 -1
  34. package/dist/lib/components/previews/video-artifact-preview.component.d.ts.map +1 -1
  35. package/dist/lib/components/previews/video-artifact-preview.component.js +15 -9
  36. package/dist/lib/components/previews/video-artifact-preview.component.js.map +1 -1
  37. package/package.json +29 -29
@@ -1 +1 @@
1
- {"version":3,"file":"data-artifact-viewer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/plugins/data-artifact-viewer.component.ts","../../../../src/lib/components/plugins/data-artifact-viewer.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { RegisterClass } from '@memberjunction/global';\nimport { DataSnapshot, DataTable, DataComputation, MJColumnDescriptor, NormalizeToTables, Metadata, RunQuery, CompositeKey, KeyValuePair } from '@memberjunction/core';\nimport { QueryEngine, ArtifactMetadataEngine } from '@memberjunction/core-entities';\nimport { QueryGridColumnConfig, QueryEntityLinkClickEvent, resolveTargetEntity } from '@memberjunction/ng-query-viewer';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { BaseArtifactViewerPluginComponent, ArtifactViewerTab, NavigationRequest } from '../base-artifact-viewer.component';\nimport { SaveQueryResult } from './save-query-dialog.component';\nimport { createDataSnapshot, buildMultiTableSql } from '../../snapshot-helpers';\n\n/**\n * Data artifact content shape as parsed from JSON.\n *\n * Core tabular data fields (source, columns, rows, tables, metadata, etc.)\n * are handled by NormalizeToTables() from @memberjunction/core.\n * This interface adds viewer-specific fields for query sync and display.\n *\n * Columns may use either `displayName` (new) or `headerName` (legacy).\n * BuildColumnConfigsForTable handles both.\n */\ninterface DataArtifactSpec {\n source?: 'query' | 'view';\n title?: string;\n queryId?: string;\n parameters?: Record<string, string | number | boolean>;\n entityName?: string;\n extraFilter?: string;\n columns?: Array<MJColumnDescriptor & { headerName?: string }>;\n rows?: Record<string, unknown>[];\n tables?: DataTable[];\n plan?: string;\n interpretation?: string;\n computations?: DataComputation[];\n metadata?: { sql?: string; rowCount?: number; executionTimeMs?: number };\n savedQueryId?: string;\n savedQueryName?: string;\n savedAtVersionNumber?: number;\n}\n\n/**\n * Describes the relationship between the current artifact version's SQL\n * and the saved query record. Drives the toolbar UI.\n */\ntype QuerySyncState =\n | 'no-query-latest' // No saved query, viewing latest version → show \"Save Query\"\n | 'no-query-older' // No saved query, viewing older version → no actions\n | 'synced' // SQL matches saved query → green badge + \"Open Query\"\n | 'outdated-latest' // SQL differs, viewing latest → amber badge + dropdown\n | 'query-ahead' // Viewing older version, query was updated at a newer version\n | 'query-behind'; // Viewing middle version, saved at older, not latest → muted\n\n/**\n * Viewer component for Data artifacts.\n *\n * Displays tabular data using AG Grid via mj-query-data-grid. Supports two modes:\n * 1. **Live data**: When metadata.sql is present, executes the query dynamically via RunQuery({ SQL })\n * to fetch fresh data on each view. Falls back to inline rows on error.\n * 2. **Inline data**: Rows embedded directly in the artifact JSON (backward compat with older artifacts)\n *\n * The Query Builder agent emits artifacts with metadata.sql for live execution.\n */\n@Component({\n standalone: false,\n selector: 'mj-data-artifact-viewer',\n templateUrl: './data-artifact-viewer.component.html',\n styleUrls: ['./data-artifact-viewer.component.css']\n})\n@RegisterClass(BaseArtifactViewerPluginComponent, 'DataArtifactViewerPlugin')\nexport class DataArtifactViewerComponent extends BaseArtifactViewerPluginComponent implements OnInit {\n @Output() openEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n @Output() override navigationRequest = new EventEmitter<NavigationRequest>();\n public override tabsChanged = new EventEmitter<void>();\n\n public spec: DataArtifactSpec | null = null;\n public GridData: Record<string, unknown>[] = [];\n public GridColumnConfigs: QueryGridColumnConfig[] | null = null;\n public IsLoading = false;\n public IsLive = false;\n public HasError = false;\n public ErrorMessage = '';\n public ShowSaveDialog = false;\n public ShowUpdateDropdown = false;\n public IsSaving = false;\n public SavingMessage = '';\n\n /** Paging state — passed through to mj-query-data-grid's embedded pager */\n public PagerTotalRowCount = 0;\n public PagerPageNumber = 1;\n public PagerPageSize = 100;\n\n // ─── Multi-Table State ───\n\n /** All resolved tables (from multi-table or wrapped single-table) */\n public ResolvedTables: DataTable[] = [];\n\n /** Index of the currently active table tab */\n public ActiveTableIndex = 0;\n\n /** Per-table paging state */\n private tablePageState: Map<number, { pageNumber: number; pageSize: number; totalRowCount: number }> = new Map();\n\n /** Per-table live data cache (loaded lazily on tab switch) */\n private tableDataCache: Map<number, Record<string, unknown>[]> = new Map();\n\n /** Per-table column configs cache */\n private tableColumnConfigsCache: Map<number, QueryGridColumnConfig[]> = new Map();\n\n /** Whether we're in multi-table mode */\n public get IsMultiTable(): boolean {\n return this.ResolvedTables.length > 1;\n }\n\n /** The currently active table */\n public get ActiveTable(): DataTable | null {\n return this.ResolvedTables[this.ActiveTableIndex] ?? null;\n }\n\n /** Query sync state — drives the toolbar UI for saved query actions */\n public QuerySyncState: QuerySyncState = 'no-query-latest';\n\n /** Latest version number for this artifact (from cache) */\n public LatestVersionNumber = 0;\n\n /** Metadata from live execution (overrides spec.metadata when live) */\n private liveRowCount: number | null = null;\n private liveExecutionTime: number | null = null;\n\n /** SQL from the saved query record (for comparison) */\n private savedQuerySql: string | null = null;\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n public override get hasDisplayContent(): boolean {\n return this.spec != null && (this.HasData || this.IsLoading || this.ResolvedTables.length > 0);\n }\n\n public override get parentShouldShowRawContent(): boolean {\n return true;\n }\n\n public get HasData(): boolean {\n return this.GridData.length > 0;\n }\n\n public get HasInlineData(): boolean {\n // Check root-level rows (legacy single-table) or any resolved table with rows\n return !!(this.spec?.rows && this.spec.rows.length > 0) ||\n this.ResolvedTables.some(t => t.rows && t.rows.length > 0);\n }\n\n public get DisplayRowCount(): number | null {\n // In live/paged mode the pager tracks the TRUE total row count\n // (PagerTotalRowCount, from RunQueryResult.TotalRowCount) — surface that as\n // the headline count so the title reflects the full result size, not just the\n // current page (which the bottom pager already shows as a range). Falls back\n // to the page/inline row count when there's no paged total.\n if (this.PagerTotalRowCount > 0) {\n return this.PagerTotalRowCount;\n }\n return this.liveRowCount ?? this.spec?.metadata?.rowCount ?? null;\n }\n\n public get DisplayExecutionTime(): number | null {\n return this.liveExecutionTime ?? this.spec?.metadata?.executionTimeMs ?? null;\n }\n\n /** Current artifact version number */\n public get CurrentVersionNumber(): number {\n return this.artifactVersion?.VersionNumber || 1;\n }\n\n /** Whether this is the latest version of the artifact */\n public get IsLatestVersion(): boolean {\n return this.CurrentVersionNumber === this.LatestVersionNumber;\n }\n\n /**\n * The effective version number at which the query was last saved/updated.\n * When viewing an older version, this looks ahead through newer versions\n * to find the most recent savedAtVersionNumber for the same query,\n * giving the user accurate context (e.g., \"Query updated at v3\" instead\n * of the stale \"Saved at v1\" from this version's snapshot).\n */\n public EffectiveSavedAtVersion: number | null = null;\n\n /** Alias used by the template */\n public get SavedAtVersion(): number | null {\n return this.EffectiveSavedAtVersion;\n }\n\n /** Display name for the saved query */\n public get SavedQueryDisplayName(): string {\n return this.spec?.savedQueryName || 'Saved Query';\n }\n\n async ngOnInit(): Promise<void> {\n try {\n this.spec = this.parseJsonContent<DataArtifactSpec>();\n if (!this.spec) {\n this.HasError = true;\n this.ErrorMessage = 'Failed to parse data artifact content';\n return;\n }\n\n // Resolve to tables array (handles both single and multi-table)\n this.ResolvedTables = NormalizeToTables(\n this.spec as unknown as Record<string, unknown>,\n this.spec.title || 'Results'\n );\n\n if (this.ResolvedTables.length === 0 && !this.spec.plan) {\n return;\n }\n\n // Build enriched column configs for the first table\n if (this.ResolvedTables.length > 0) {\n this.GridColumnConfigs = this.BuildColumnConfigsForTable(this.ResolvedTables[0]);\n }\n\n // Initialize paging state for all tables\n for (let i = 0; i < this.ResolvedTables.length; i++) {\n this.tablePageState.set(i, { pageNumber: 1, pageSize: 100, totalRowCount: 0 });\n }\n\n // Set loading early (synchronously) so hasDisplayContent is true immediately\n if (this.ResolvedTables.some(t => t.metadata?.sql) || this.HasInlineData) {\n this.IsLoading = true;\n }\n\n // Load cached metadata and resolve query sync state\n await this.InitQuerySyncState();\n\n // Load data for the first (active) table\n if (this.ResolvedTables.length > 0) {\n await this.LoadTableData(0);\n }\n\n // Signal parent that tabs/display content may have changed after async load\n this.tabsChanged.emit();\n } catch (error) {\n this.HasError = true;\n this.ErrorMessage = error instanceof Error ? error.message : 'Failed to load data';\n }\n }\n\n /**\n * Re-execute the live SQL query for the active table\n */\n public async OnRefresh(): Promise<void> {\n this.tableDataCache.delete(this.ActiveTableIndex);\n await this.LoadTableData(this.ActiveTableIndex);\n }\n\n /**\n * Handle entity link click from the grid and bubble up as openEntityRecord.\n * Converts the grid's recordId string into a CompositeKey for the artifact viewer pipeline.\n */\n public OnEntityLinkClick(event: QueryEntityLinkClickEvent): void {\n const md = this.ProviderToUse;\n const entity = md.Entities.find(e => e.Name === event.entityName);\n const pkFieldName = entity?.FirstPrimaryKey?.Name ?? 'ID';\n\n const compositeKey = new CompositeKey([\n new KeyValuePair(pkFieldName, event.recordId)\n ]);\n this.openEntityRecord.emit({\n entityName: event.entityName,\n compositeKey\n });\n }\n\n /**\n * Handle page change from the data grid's embedded pager.\n * Re-executes the query for the active table with new page parameters.\n */\n public async OnPageChange(event: PageChangeEvent): Promise<void> {\n const pageState = this.tablePageState.get(this.ActiveTableIndex);\n if (!pageState) return;\n\n pageState.pageNumber = event.PageNumber;\n pageState.pageSize = event.PageSize;\n\n // Clear cache so it reloads\n this.tableDataCache.delete(this.ActiveTableIndex);\n await this.LoadTableData(this.ActiveTableIndex);\n }\n\n /**\n * Switch to a different table tab.\n * Loads data lazily if not already cached.\n */\n public async OnTableTabClick(index: number): Promise<void> {\n if (index === this.ActiveTableIndex) return;\n this.ActiveTableIndex = index;\n\n const table = this.ResolvedTables[index];\n if (!table) return;\n\n // Use cached column configs or build new\n if (!this.tableColumnConfigsCache.has(index)) {\n const configs = this.BuildColumnConfigsForTable(table);\n if (configs) this.tableColumnConfigsCache.set(index, configs);\n }\n this.GridColumnConfigs = this.tableColumnConfigsCache.get(index) ?? null;\n\n // Use cached data or load fresh\n if (this.tableDataCache.has(index)) {\n this.GridData = this.tableDataCache.get(index)!;\n const pageState = this.tablePageState.get(index)!;\n this.PagerPageNumber = pageState.pageNumber;\n this.PagerPageSize = pageState.pageSize;\n this.PagerTotalRowCount = pageState.totalRowCount;\n } else {\n await this.LoadTableData(index);\n }\n\n this.cdr.detectChanges();\n }\n\n /**\n * Load data for a specific table.\n * Handles live SQL execution, inline rows, and caching.\n */\n private async LoadTableData(tableIndex: number): Promise<void> {\n const table = this.ResolvedTables[tableIndex];\n if (!table) return;\n\n this.IsLoading = true;\n this.HasError = false;\n this.cdr.detectChanges();\n\n try {\n if (table.metadata?.sql) {\n // Live SQL execution\n const pageState = this.tablePageState.get(tableIndex)!;\n const rq = this.RunQueryToUse;\n const startRow = (pageState.pageNumber - 1) * pageState.pageSize;\n const result = await rq.RunQuery({\n SQL: table.metadata.sql,\n StartRow: startRow,\n MaxRows: pageState.pageSize\n });\n\n if (result.Success) {\n this.tableDataCache.set(tableIndex, result.Results);\n this.GridData = result.Results;\n this.IsLive = true;\n\n pageState.totalRowCount = result.TotalRowCount ?? result.RowCount ?? 0;\n this.PagerTotalRowCount = pageState.totalRowCount;\n this.PagerPageNumber = pageState.pageNumber;\n this.PagerPageSize = pageState.pageSize;\n\n this.liveRowCount = result.RowCount;\n this.liveExecutionTime = result.ExecutionTime;\n } else {\n this.HandleTableError(tableIndex, result.ErrorMessage || 'Query failed');\n }\n } else if (table.rows && table.rows.length > 0) {\n // Inline data\n this.tableDataCache.set(tableIndex, table.rows);\n this.GridData = table.rows;\n this.liveRowCount = table.rows.length;\n } else {\n this.GridData = [];\n }\n } catch (error) {\n this.HandleTableError(tableIndex, error instanceof Error ? error.message : 'Load failed');\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Build QueryGridColumnConfig[] from a DataTable's column metadata.\n * Returns null if columns have no entity metadata (grid falls back to auto-inference).\n */\n private BuildColumnConfigsForTable(table: DataTable): QueryGridColumnConfig[] | null {\n const columns = table.columns;\n if (!columns?.length) return null;\n\n // Only build if at least one column has entity metadata or type info\n const hasMetadata = columns.some(c => c.sourceEntity || c.sqlBaseType);\n if (!hasMetadata) return null;\n\n const md = this.ProviderToUse;\n return columns.map((col, index) => {\n const target = resolveTargetEntity(col.sourceEntity, col.sourceFieldName, md);\n const isEntityLink = !!(target.targetEntityName && (target.isPrimaryKey || target.isForeignKey));\n const baseType = (col.sqlBaseType || 'nvarchar').toLowerCase();\n\n let align: 'left' | 'center' | 'right' = 'left';\n if (['int', 'bigint', 'decimal', 'numeric', 'float', 'money', 'smallmoney', 'real'].includes(baseType)) {\n align = 'right';\n } else if (baseType === 'bit') {\n align = 'center';\n }\n\n // Support both displayName (new) and headerName (legacy) for backward compat\n const colAny = col as unknown as Record<string, unknown>;\n const title = col.displayName || (colAny['headerName'] as string) || col.field;\n\n return {\n field: col.field,\n title,\n visible: true,\n sortable: true,\n resizable: true,\n reorderable: true,\n sqlBaseType: col.sqlBaseType || 'nvarchar',\n sqlFullType: col.sqlFullType || col.sqlBaseType || 'nvarchar',\n align,\n order: index,\n sourceEntityName: col.sourceEntity,\n sourceFieldName: col.sourceFieldName,\n isEntityLink,\n targetEntityName: target.targetEntityName,\n targetEntityId: target.targetEntityId,\n targetEntityIcon: target.targetEntityIcon,\n isPrimaryKey: target.isPrimaryKey,\n isForeignKey: target.isForeignKey,\n pinned: null,\n } as QueryGridColumnConfig;\n });\n }\n\n /**\n * Handle a table load error by setting error state and falling back to inline data\n */\n private HandleTableError(tableIndex: number, message: string): void {\n this.HasError = true;\n this.ErrorMessage = message;\n const table = this.ResolvedTables[tableIndex];\n if (table?.rows && table.rows.length > 0) {\n this.GridData = table.rows;\n }\n }\n\n // ─── Query Sync State ────────────────────────────────────────────\n\n /**\n * Initialize query sync state by loading cached metadata.\n * Resolves the latest version number and compares saved query SQL.\n */\n private async InitQuerySyncState(): Promise<void> {\n // Ensure the artifact-type registry is loaded (not registered for startup).\n await ArtifactMetadataEngine.Instance.Config(false);\n\n // Load THIS artifact's versions on demand (including Content, which\n // resolveEffectiveSavedAtVersion parses). Versions are no longer bulk-loaded\n // at boot — the payload here is bounded to a single artifact's versions.\n if (this.artifactVersion?.ArtifactID) {\n await ArtifactMetadataEngine.Instance.LoadVersionsForArtifact(this.artifactVersion.ArtifactID);\n }\n\n this.LatestVersionNumber = this.resolveLatestVersionNumber();\n\n // If the loaded versions don't yet include the one we're viewing (a newer\n // version was created after we first loaded), force a re-fetch and re-resolve.\n if (this.LatestVersionNumber < this.CurrentVersionNumber && this.artifactVersion?.ArtifactID) {\n await ArtifactMetadataEngine.Instance.LoadVersionsForArtifact(this.artifactVersion.ArtifactID, undefined, undefined, true);\n this.LatestVersionNumber = this.resolveLatestVersionNumber();\n }\n\n this.EffectiveSavedAtVersion = this.resolveEffectiveSavedAtVersion();\n await this.resolveSavedQuerySql();\n this.QuerySyncState = this.computeQuerySyncState();\n }\n\n /**\n * Determine the latest version number for this artifact from cache.\n * Falls back to current version if cache miss.\n */\n private resolveLatestVersionNumber(): number {\n if (!this.artifactVersion?.ArtifactID) {\n return this.CurrentVersionNumber;\n }\n\n const versions = ArtifactMetadataEngine.Instance.GetCachedVersionsForArtifact(this.artifactVersion.ArtifactID);\n if (versions.length > 0) {\n // GetCachedVersionsForArtifact returns DESC sorted\n return versions[0].VersionNumber || 1;\n }\n\n // Cache miss — current version is our best guess\n return this.CurrentVersionNumber;\n }\n\n /**\n * Scan all versions of this artifact to find the most recent savedAtVersionNumber\n * for the same savedQueryId. When viewing an older version, this tells the user\n * where the query was *actually* last updated, not just what this version's\n * snapshot recorded at the time.\n */\n private resolveEffectiveSavedAtVersion(): number | null {\n const queryId = this.spec?.savedQueryId;\n if (!queryId) return null;\n\n // Start with this version's own value\n let effective = this.spec?.savedAtVersionNumber ?? null;\n\n if (!this.artifactVersion?.ArtifactID) return effective;\n\n // GetCachedVersionsForArtifact returns DESC sorted — scan all versions\n const versions = ArtifactMetadataEngine.Instance.GetCachedVersionsForArtifact(this.artifactVersion.ArtifactID);\n for (const v of versions) {\n try {\n if (!v.Content) continue;\n const content = typeof v.Content === 'string' ? JSON.parse(v.Content) : v.Content;\n if (content.savedQueryId === queryId && content.savedAtVersionNumber != null) {\n const vSavedAt = content.savedAtVersionNumber as number;\n if (effective == null || vSavedAt > effective) {\n effective = vSavedAt;\n }\n }\n } catch {\n // Skip versions with unparseable content\n }\n }\n\n return effective;\n }\n\n /**\n * Look up the saved query's SQL from QueryEngine cache for comparison.\n * Only fetches if savedQueryId is present.\n */\n private async resolveSavedQuerySql(): Promise<void> {\n if (!this.spec?.savedQueryId) {\n this.savedQuerySql = null;\n return;\n }\n\n // QueryEngine is registered for startup, should already be loaded\n let query = QueryEngine.Instance.FindQueryByID(this.spec.savedQueryId);\n\n if (!query) {\n // Cache miss — force refresh and retry\n await QueryEngine.Instance.Config(true);\n query = QueryEngine.Instance.FindQueryByID(this.spec.savedQueryId);\n }\n\n this.savedQuerySql = query?.SQL ?? null;\n }\n\n /**\n * Compute the query sync state from current spec, version, and saved query SQL.\n * Implements the decision tree from the UX design.\n */\n private computeQuerySyncState(): QuerySyncState {\n const hasSavedQuery = !!this.spec?.savedQueryId;\n const isLatest = this.IsLatestVersion;\n\n if (!hasSavedQuery) {\n return isLatest ? 'no-query-latest' : 'no-query-older';\n }\n\n // Compare SQL (normalize whitespace for reliable comparison)\n const specSql = this.normalizeSql(this.spec?.metadata?.sql);\n const querySql = this.normalizeSql(this.savedQuerySql);\n const sqlMatches = specSql != null && querySql != null && specSql === querySql;\n\n // Only truly synced if SQL matches AND this is the version it was saved at.\n // Even with identical SQL, a newer version should show the dropdown so the\n // user can update the version association (re-save at current version).\n const savedAtCurrent = this.EffectiveSavedAtVersion === this.CurrentVersionNumber;\n if (sqlMatches && savedAtCurrent) {\n return 'synced';\n }\n\n // SQL differs — determine position relative to saved version\n if (isLatest) {\n return 'outdated-latest';\n }\n\n // Use effective saved-at (looks ahead through newer versions)\n const savedAt = this.EffectiveSavedAtVersion;\n if (savedAt != null && this.CurrentVersionNumber < savedAt) {\n return 'query-ahead'; // query was updated at a newer version\n }\n\n return 'query-behind'; // ahead of saved but not latest\n }\n\n /** Normalize SQL for comparison: trim and collapse whitespace */\n private normalizeSql(sql: string | null | undefined): string | null {\n if (sql == null) return null;\n return sql.trim().replace(/\\s+/g, ' ');\n }\n\n // ─── Actions ────────────────────────────────────────────────────\n\n /** Navigate to the saved query in the Data Explorer's Queries browser */\n public OnOpenSavedQuery(): void {\n if (!this.spec?.savedQueryId) return;\n this.navigationRequest.emit({\n appName: 'Data Explorer',\n navItemName: 'Queries',\n queryParams: { queryId: this.spec.savedQueryId }\n });\n }\n\n /** Show the save panel for creating a brand-new query */\n public OnShowSaveDialog(): void {\n this.ShowSaveDialog = true;\n this.ShowUpdateDropdown = false;\n }\n\n /** Toggle the update query dropdown */\n public OnToggleUpdateDropdown(): void {\n this.ShowUpdateDropdown = !this.ShowUpdateDropdown;\n }\n\n /** Close the dropdown (e.g., on outside click) */\n public OnCloseDropdown(): void {\n this.ShowUpdateDropdown = false;\n }\n\n /**\n * Update the existing saved query's SQL to match this version.\n * Only available from the latest version (Scenario 3).\n */\n public async OnUpdateExistingQuery(): Promise<void> {\n this.ShowUpdateDropdown = false;\n if (!this.spec?.savedQueryId || !this.spec.metadata?.sql) return;\n\n this.IsSaving = true;\n this.SavingMessage = `Updating \"${this.SavedQueryDisplayName}\"...`;\n this.cdr.detectChanges();\n\n try {\n const md = this.ProviderToUse;\n const query = await md.GetEntityObject<import('@memberjunction/core-entities').MJQueryEntity>('MJ: Queries');\n const loaded = await query.Load(this.spec.savedQueryId);\n\n if (!loaded) {\n console.error('Failed to load saved query for update');\n return;\n }\n\n query.SQL = this.spec.metadata.sql;\n if (this.spec.plan?.trim()) {\n query.TechnicalDescription = this.spec.plan.trim();\n }\n const saved = await query.Save();\n\n if (saved) {\n // Update spec with new version tracking\n this.spec.savedAtVersionNumber = this.CurrentVersionNumber;\n await this.PersistArtifactContent();\n\n // Refresh caches so future lookups see the updated data\n await QueryEngine.Instance.Config(true);\n await ArtifactMetadataEngine.Instance.Config(true);\n\n this.savedQuerySql = this.spec.metadata.sql;\n this.EffectiveSavedAtVersion = this.CurrentVersionNumber;\n this.QuerySyncState = 'synced';\n }\n } catch (error) {\n console.error('Failed to update saved query:', error);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Save as a new query (from the dropdown).\n * Opens the save dialog which creates a fresh query record.\n */\n public OnSaveAsNewQuery(): void {\n this.ShowUpdateDropdown = false;\n this.ShowSaveDialog = true;\n }\n\n /** Handle successful save from the dialog (both initial save and \"save as new\") */\n public async OnQuerySaved(event: SaveQueryResult): Promise<void> {\n this.ShowSaveDialog = false;\n this.IsSaving = true;\n this.SavingMessage = 'Saving query...';\n this.cdr.detectChanges();\n\n try {\n // Update spec with saved query info and version tracking\n this.spec!.savedQueryId = event.queryId;\n this.spec!.savedQueryName = event.queryName;\n this.spec!.savedAtVersionNumber = this.CurrentVersionNumber;\n\n // Persist and refresh caches\n await this.PersistArtifactContent();\n await QueryEngine.Instance.Config(true);\n await ArtifactMetadataEngine.Instance.Config(true);\n await this.ProviderToUse.Refresh();\n\n this.savedQuerySql = this.spec!.metadata?.sql ?? null;\n this.EffectiveSavedAtVersion = this.CurrentVersionNumber;\n this.QuerySyncState = 'synced';\n } catch (error) {\n console.error('Failed to save query:', error);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Persist updated spec back to the artifact version entity */\n private async PersistArtifactContent(): Promise<void> {\n if (!this.artifactVersion || !this.spec) return;\n this.artifactVersion.Content = JSON.stringify(this.spec);\n await this.artifactVersion.Save();\n }\n\n /**\n * Returns a DataSnapshot with live grid data, current page state,\n * and query sync state.\n */\n public override GetCurrentStateSnapshot(): DataSnapshot | null {\n if (!this.spec) return null;\n\n const tables = NormalizeToTables(\n this.spec as unknown as Record<string, unknown>,\n this.spec.title || 'Results'\n );\n const activeTable = tables[this.ActiveTableIndex];\n\n if (activeTable) {\n // Override with live data for the active table\n if (this.IsLive) activeTable.rows = this.GridData;\n activeTable.pageNumber = this.PagerPageNumber;\n activeTable.metadata = {\n ...activeTable.metadata,\n ...(this.liveRowCount != null ? { rowCount: this.liveRowCount } : {}),\n ...(this.liveExecutionTime != null\n ? { executionTimeMs: this.liveExecutionTime } : {}),\n ...(this.PagerTotalRowCount > 0\n ? { totalAvailableRows: this.PagerTotalRowCount } : {}),\n pageSize: this.PagerPageSize\n };\n }\n\n return DataSnapshot.FromTables(tables, this.spec.title);\n }\n\n // ─── Tabs ───────────────────────────────────────────────────────\n\n /**\n * Provide Plan tab (markdown), SQL tab (code), and Interpretation tab when available\n */\n public GetAdditionalTabs(): ArtifactViewerTab[] {\n const tabs: ArtifactViewerTab[] = [];\n\n if (this.spec?.plan) {\n tabs.push({\n label: 'Plan',\n icon: 'fa-diagram-project',\n contentType: 'markdown',\n content: this.spec.plan\n });\n }\n\n // SQL tab — multi-table shows all queries with headers\n if (this.IsMultiTable) {\n const multiSql = buildMultiTableSql(this.ResolvedTables);\n if (multiSql) {\n tabs.push({\n label: 'SQL',\n icon: 'fa-database',\n contentType: 'code',\n language: 'sql',\n content: multiSql\n });\n }\n } else if (this.spec?.metadata?.sql) {\n tabs.push({\n label: 'SQL',\n icon: 'fa-database',\n contentType: 'code',\n language: 'sql',\n content: this.spec.metadata.sql\n });\n }\n\n // Interpretation tab\n if (this.spec?.interpretation) {\n tabs.push({\n label: 'Interpretation',\n icon: 'fa-lightbulb',\n contentType: 'markdown',\n content: this.spec.interpretation\n });\n }\n\n return tabs;\n }\n}\n","<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 → 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 → 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 → 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 → 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"]}
1
+ {"version":3,"file":"data-artifact-viewer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/plugins/data-artifact-viewer.component.ts","../../../../src/lib/components/plugins/data-artifact-viewer.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { RegisterClass } from '@memberjunction/global';\nimport { DataSnapshot, DataTable, DataComputation, MJColumnDescriptor, NormalizeToTables, Metadata, RunQuery, CompositeKey } from '@memberjunction/core';\nimport { QueryEngine, ArtifactMetadataEngine } from '@memberjunction/core-entities';\nimport { QueryGridColumnConfig, QueryEntityLinkClickEvent, resolveTargetEntity } from '@memberjunction/ng-query-viewer';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { BaseArtifactViewerPluginComponent, ArtifactViewerTab, NavigationRequest } from '../base-artifact-viewer.component';\nimport { SaveQueryResult } from './save-query-dialog.component';\nimport { createDataSnapshot, buildMultiTableSql } from '../../snapshot-helpers';\n\n/**\n * Data artifact content shape as parsed from JSON.\n *\n * Core tabular data fields (source, columns, rows, tables, metadata, etc.)\n * are handled by NormalizeToTables() from @memberjunction/core.\n * This interface adds viewer-specific fields for query sync and display.\n *\n * Columns may use either `displayName` (new) or `headerName` (legacy).\n * BuildColumnConfigsForTable handles both.\n */\ninterface DataArtifactSpec {\n source?: 'query' | 'view';\n title?: string;\n queryId?: string;\n parameters?: Record<string, string | number | boolean>;\n entityName?: string;\n extraFilter?: string;\n columns?: Array<MJColumnDescriptor & { headerName?: string }>;\n rows?: Record<string, unknown>[];\n tables?: DataTable[];\n plan?: string;\n interpretation?: string;\n computations?: DataComputation[];\n metadata?: { sql?: string; rowCount?: number; executionTimeMs?: number };\n savedQueryId?: string;\n savedQueryName?: string;\n savedAtVersionNumber?: number;\n}\n\n/**\n * Describes the relationship between the current artifact version's SQL\n * and the saved query record. Drives the toolbar UI.\n */\ntype QuerySyncState =\n | 'no-query-latest' // No saved query, viewing latest version → show \"Save Query\"\n | 'no-query-older' // No saved query, viewing older version → no actions\n | 'synced' // SQL matches saved query → green badge + \"Open Query\"\n | 'outdated-latest' // SQL differs, viewing latest → amber badge + dropdown\n | 'query-ahead' // Viewing older version, query was updated at a newer version\n | 'query-behind'; // Viewing middle version, saved at older, not latest → muted\n\n/**\n * Viewer component for Data artifacts.\n *\n * Displays tabular data using AG Grid via mj-query-data-grid. Supports two modes:\n * 1. **Live data**: When metadata.sql is present, executes the query dynamically via RunQuery({ SQL })\n * to fetch fresh data on each view. Falls back to inline rows on error.\n * 2. **Inline data**: Rows embedded directly in the artifact JSON (backward compat with older artifacts)\n *\n * The Query Builder agent emits artifacts with metadata.sql for live execution.\n */\n@Component({\n standalone: false,\n selector: 'mj-data-artifact-viewer',\n templateUrl: './data-artifact-viewer.component.html',\n styleUrls: ['./data-artifact-viewer.component.css']\n})\n@RegisterClass(BaseArtifactViewerPluginComponent, 'DataArtifactViewerPlugin')\nexport class DataArtifactViewerComponent extends BaseArtifactViewerPluginComponent implements OnInit {\n @Output() openEntityRecord = new EventEmitter<{entityName: string; compositeKey: CompositeKey}>();\n @Output() override navigationRequest = new EventEmitter<NavigationRequest>();\n public override tabsChanged = new EventEmitter<void>();\n\n public spec: DataArtifactSpec | null = null;\n public GridData: Record<string, unknown>[] = [];\n public GridColumnConfigs: QueryGridColumnConfig[] | null = null;\n public IsLoading = false;\n public IsLive = false;\n public HasError = false;\n public ErrorMessage = '';\n public ShowSaveDialog = false;\n public ShowUpdateDropdown = false;\n public IsSaving = false;\n public SavingMessage = '';\n\n /** Paging state — passed through to mj-query-data-grid's embedded pager */\n public PagerTotalRowCount = 0;\n public PagerPageNumber = 1;\n public PagerPageSize = 100;\n\n // ─── Multi-Table State ───\n\n /** All resolved tables (from multi-table or wrapped single-table) */\n public ResolvedTables: DataTable[] = [];\n\n /** Index of the currently active table tab */\n public ActiveTableIndex = 0;\n\n /** Per-table paging state */\n private tablePageState: Map<number, { pageNumber: number; pageSize: number; totalRowCount: number }> = new Map();\n\n /** Per-table live data cache (loaded lazily on tab switch) */\n private tableDataCache: Map<number, Record<string, unknown>[]> = new Map();\n\n /** Per-table column configs cache */\n private tableColumnConfigsCache: Map<number, QueryGridColumnConfig[]> = new Map();\n\n /** Whether we're in multi-table mode */\n public get IsMultiTable(): boolean {\n return this.ResolvedTables.length > 1;\n }\n\n /** The currently active table */\n public get ActiveTable(): DataTable | null {\n return this.ResolvedTables[this.ActiveTableIndex] ?? null;\n }\n\n /** Query sync state — drives the toolbar UI for saved query actions */\n public QuerySyncState: QuerySyncState = 'no-query-latest';\n\n /** Latest version number for this artifact (from cache) */\n public LatestVersionNumber = 0;\n\n /** Metadata from live execution (overrides spec.metadata when live) */\n private liveRowCount: number | null = null;\n private liveExecutionTime: number | null = null;\n\n /** SQL from the saved query record (for comparison) */\n private savedQuerySql: string | null = null;\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n public override get hasDisplayContent(): boolean {\n return this.spec != null && (this.HasData || this.IsLoading || this.ResolvedTables.length > 0);\n }\n\n public override get parentShouldShowRawContent(): boolean {\n return true;\n }\n\n public get HasData(): boolean {\n return this.GridData.length > 0;\n }\n\n public get HasInlineData(): boolean {\n // Check root-level rows (legacy single-table) or any resolved table with rows\n return !!(this.spec?.rows && this.spec.rows.length > 0) ||\n this.ResolvedTables.some(t => t.rows && t.rows.length > 0);\n }\n\n public get DisplayRowCount(): number | null {\n // In live/paged mode the pager tracks the TRUE total row count\n // (PagerTotalRowCount, from RunQueryResult.TotalRowCount) — surface that as\n // the headline count so the title reflects the full result size, not just the\n // current page (which the bottom pager already shows as a range). Falls back\n // to the page/inline row count when there's no paged total.\n if (this.PagerTotalRowCount > 0) {\n return this.PagerTotalRowCount;\n }\n return this.liveRowCount ?? this.spec?.metadata?.rowCount ?? null;\n }\n\n public get DisplayExecutionTime(): number | null {\n return this.liveExecutionTime ?? this.spec?.metadata?.executionTimeMs ?? null;\n }\n\n /** Current artifact version number */\n public get CurrentVersionNumber(): number {\n return this.artifactVersion?.VersionNumber || 1;\n }\n\n /** Whether this is the latest version of the artifact */\n public get IsLatestVersion(): boolean {\n return this.CurrentVersionNumber === this.LatestVersionNumber;\n }\n\n /**\n * The effective version number at which the query was last saved/updated.\n * When viewing an older version, this looks ahead through newer versions\n * to find the most recent savedAtVersionNumber for the same query,\n * giving the user accurate context (e.g., \"Query updated at v3\" instead\n * of the stale \"Saved at v1\" from this version's snapshot).\n */\n public EffectiveSavedAtVersion: number | null = null;\n\n /** Alias used by the template */\n public get SavedAtVersion(): number | null {\n return this.EffectiveSavedAtVersion;\n }\n\n /** Display name for the saved query */\n public get SavedQueryDisplayName(): string {\n return this.spec?.savedQueryName || 'Saved Query';\n }\n\n async ngOnInit(): Promise<void> {\n try {\n this.spec = this.parseJsonContent<DataArtifactSpec>();\n if (!this.spec) {\n this.HasError = true;\n this.ErrorMessage = 'Failed to parse data artifact content';\n return;\n }\n\n // Resolve to tables array (handles both single and multi-table)\n this.ResolvedTables = NormalizeToTables(\n this.spec as unknown as Record<string, unknown>,\n this.spec.title || 'Results'\n );\n\n if (this.ResolvedTables.length === 0 && !this.spec.plan) {\n return;\n }\n\n // Build enriched column configs for the first table\n if (this.ResolvedTables.length > 0) {\n this.GridColumnConfigs = this.BuildColumnConfigsForTable(this.ResolvedTables[0]);\n }\n\n // Initialize paging state for all tables\n for (let i = 0; i < this.ResolvedTables.length; i++) {\n this.tablePageState.set(i, { pageNumber: 1, pageSize: 100, totalRowCount: 0 });\n }\n\n // Set loading early (synchronously) so hasDisplayContent is true immediately\n if (this.ResolvedTables.some(t => t.metadata?.sql) || this.HasInlineData) {\n this.IsLoading = true;\n }\n\n // Load cached metadata and resolve query sync state\n await this.InitQuerySyncState();\n\n // Load data for the first (active) table\n if (this.ResolvedTables.length > 0) {\n await this.LoadTableData(0);\n }\n\n // Signal parent that tabs/display content may have changed after async load\n this.tabsChanged.emit();\n } catch (error) {\n this.HasError = true;\n this.ErrorMessage = error instanceof Error ? error.message : 'Failed to load data';\n }\n }\n\n /**\n * Re-execute the live SQL query for the active table\n */\n public async OnRefresh(): Promise<void> {\n this.tableDataCache.delete(this.ActiveTableIndex);\n await this.LoadTableData(this.ActiveTableIndex);\n }\n\n /**\n * Handle entity link click from the grid and bubble up as openEntityRecord.\n * Converts the grid's recordId string into a CompositeKey for the artifact viewer pipeline.\n */\n public OnEntityLinkClick(event: QueryEntityLinkClickEvent): void {\n const md = this.ProviderToUse;\n // recordId may be a bare value or a \"F1|v1||F2|v2\" segment; FromURLSegment reads both against\n // the entity's real primary key(s) instead of assuming a single column.\n const compositeKey = CompositeKey.FromURLSegment(md.EntityByName(event.entityName), event.recordId);\n this.openEntityRecord.emit({\n entityName: event.entityName,\n compositeKey\n });\n }\n\n /**\n * Handle page change from the data grid's embedded pager.\n * Re-executes the query for the active table with new page parameters.\n */\n public async OnPageChange(event: PageChangeEvent): Promise<void> {\n const pageState = this.tablePageState.get(this.ActiveTableIndex);\n if (!pageState) return;\n\n pageState.pageNumber = event.PageNumber;\n pageState.pageSize = event.PageSize;\n\n // Clear cache so it reloads\n this.tableDataCache.delete(this.ActiveTableIndex);\n await this.LoadTableData(this.ActiveTableIndex);\n }\n\n /**\n * Switch to a different table tab.\n * Loads data lazily if not already cached.\n */\n public async OnTableTabClick(index: number): Promise<void> {\n if (index === this.ActiveTableIndex) return;\n this.ActiveTableIndex = index;\n\n const table = this.ResolvedTables[index];\n if (!table) return;\n\n // Use cached column configs or build new\n if (!this.tableColumnConfigsCache.has(index)) {\n const configs = this.BuildColumnConfigsForTable(table);\n if (configs) this.tableColumnConfigsCache.set(index, configs);\n }\n this.GridColumnConfigs = this.tableColumnConfigsCache.get(index) ?? null;\n\n // Use cached data or load fresh\n if (this.tableDataCache.has(index)) {\n this.GridData = this.tableDataCache.get(index)!;\n const pageState = this.tablePageState.get(index)!;\n this.PagerPageNumber = pageState.pageNumber;\n this.PagerPageSize = pageState.pageSize;\n this.PagerTotalRowCount = pageState.totalRowCount;\n } else {\n await this.LoadTableData(index);\n }\n\n this.cdr.detectChanges();\n }\n\n /**\n * Load data for a specific table.\n * Handles live SQL execution, inline rows, and caching.\n */\n private async LoadTableData(tableIndex: number): Promise<void> {\n const table = this.ResolvedTables[tableIndex];\n if (!table) return;\n\n this.IsLoading = true;\n this.HasError = false;\n this.cdr.detectChanges();\n\n try {\n if (table.metadata?.sql) {\n // Live SQL execution\n const pageState = this.tablePageState.get(tableIndex)!;\n const rq = this.RunQueryToUse;\n const startRow = (pageState.pageNumber - 1) * pageState.pageSize;\n const result = await rq.RunQuery({\n SQL: table.metadata.sql,\n StartRow: startRow,\n MaxRows: pageState.pageSize\n });\n\n if (result.Success) {\n this.tableDataCache.set(tableIndex, result.Results);\n this.GridData = result.Results;\n this.IsLive = true;\n\n pageState.totalRowCount = result.TotalRowCount ?? result.RowCount ?? 0;\n this.PagerTotalRowCount = pageState.totalRowCount;\n this.PagerPageNumber = pageState.pageNumber;\n this.PagerPageSize = pageState.pageSize;\n\n this.liveRowCount = result.RowCount;\n this.liveExecutionTime = result.ExecutionTime;\n } else {\n this.HandleTableError(tableIndex, result.ErrorMessage || 'Query failed');\n }\n } else if (table.rows && table.rows.length > 0) {\n // Inline data\n this.tableDataCache.set(tableIndex, table.rows);\n this.GridData = table.rows;\n this.liveRowCount = table.rows.length;\n } else {\n this.GridData = [];\n }\n } catch (error) {\n this.HandleTableError(tableIndex, error instanceof Error ? error.message : 'Load failed');\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Build QueryGridColumnConfig[] from a DataTable's column metadata.\n * Returns null if columns have no entity metadata (grid falls back to auto-inference).\n */\n private BuildColumnConfigsForTable(table: DataTable): QueryGridColumnConfig[] | null {\n const columns = table.columns;\n if (!columns?.length) return null;\n\n // Only build if at least one column has entity metadata or type info\n const hasMetadata = columns.some(c => c.sourceEntity || c.sqlBaseType);\n if (!hasMetadata) return null;\n\n const md = this.ProviderToUse;\n return columns.map((col, index) => {\n const target = resolveTargetEntity(col.sourceEntity, col.sourceFieldName, md);\n const isEntityLink = !!(target.targetEntityName && (target.isPrimaryKey || target.isForeignKey));\n const baseType = (col.sqlBaseType || 'nvarchar').toLowerCase();\n\n let align: 'left' | 'center' | 'right' = 'left';\n if (['int', 'bigint', 'decimal', 'numeric', 'float', 'money', 'smallmoney', 'real'].includes(baseType)) {\n align = 'right';\n } else if (baseType === 'bit') {\n align = 'center';\n }\n\n // Support both displayName (new) and headerName (legacy) for backward compat\n const colAny = col as unknown as Record<string, unknown>;\n const title = col.displayName || (colAny['headerName'] as string) || col.field;\n\n return {\n field: col.field,\n title,\n visible: true,\n sortable: true,\n resizable: true,\n reorderable: true,\n sqlBaseType: col.sqlBaseType || 'nvarchar',\n sqlFullType: col.sqlFullType || col.sqlBaseType || 'nvarchar',\n align,\n order: index,\n sourceEntityName: col.sourceEntity,\n sourceFieldName: col.sourceFieldName,\n isEntityLink,\n targetEntityName: target.targetEntityName,\n targetEntityId: target.targetEntityId,\n targetEntityIcon: target.targetEntityIcon,\n isPrimaryKey: target.isPrimaryKey,\n isForeignKey: target.isForeignKey,\n pinned: null,\n } as QueryGridColumnConfig;\n });\n }\n\n /**\n * Handle a table load error by setting error state and falling back to inline data\n */\n private HandleTableError(tableIndex: number, message: string): void {\n this.HasError = true;\n this.ErrorMessage = message;\n const table = this.ResolvedTables[tableIndex];\n if (table?.rows && table.rows.length > 0) {\n this.GridData = table.rows;\n }\n }\n\n // ─── Query Sync State ────────────────────────────────────────────\n\n /**\n * Initialize query sync state by loading cached metadata.\n * Resolves the latest version number and compares saved query SQL.\n */\n private async InitQuerySyncState(): Promise<void> {\n // Ensure the artifact-type registry is loaded (not registered for startup).\n await ArtifactMetadataEngine.Instance.Config(false);\n\n // Load THIS artifact's versions on demand (including Content, which\n // resolveEffectiveSavedAtVersion parses). Versions are no longer bulk-loaded\n // at boot — the payload here is bounded to a single artifact's versions.\n if (this.artifactVersion?.ArtifactID) {\n await ArtifactMetadataEngine.Instance.LoadVersionsForArtifact(this.artifactVersion.ArtifactID);\n }\n\n this.LatestVersionNumber = this.resolveLatestVersionNumber();\n\n // If the loaded versions don't yet include the one we're viewing (a newer\n // version was created after we first loaded), force a re-fetch and re-resolve.\n if (this.LatestVersionNumber < this.CurrentVersionNumber && this.artifactVersion?.ArtifactID) {\n await ArtifactMetadataEngine.Instance.LoadVersionsForArtifact(this.artifactVersion.ArtifactID, undefined, undefined, true);\n this.LatestVersionNumber = this.resolveLatestVersionNumber();\n }\n\n this.EffectiveSavedAtVersion = this.resolveEffectiveSavedAtVersion();\n await this.resolveSavedQuerySql();\n this.QuerySyncState = this.computeQuerySyncState();\n }\n\n /**\n * Determine the latest version number for this artifact from cache.\n * Falls back to current version if cache miss.\n */\n private resolveLatestVersionNumber(): number {\n if (!this.artifactVersion?.ArtifactID) {\n return this.CurrentVersionNumber;\n }\n\n const versions = ArtifactMetadataEngine.Instance.GetCachedVersionsForArtifact(this.artifactVersion.ArtifactID);\n if (versions.length > 0) {\n // GetCachedVersionsForArtifact returns DESC sorted\n return versions[0].VersionNumber || 1;\n }\n\n // Cache miss — current version is our best guess\n return this.CurrentVersionNumber;\n }\n\n /**\n * Scan all versions of this artifact to find the most recent savedAtVersionNumber\n * for the same savedQueryId. When viewing an older version, this tells the user\n * where the query was *actually* last updated, not just what this version's\n * snapshot recorded at the time.\n */\n private resolveEffectiveSavedAtVersion(): number | null {\n const queryId = this.spec?.savedQueryId;\n if (!queryId) return null;\n\n // Start with this version's own value\n let effective = this.spec?.savedAtVersionNumber ?? null;\n\n if (!this.artifactVersion?.ArtifactID) return effective;\n\n // GetCachedVersionsForArtifact returns DESC sorted — scan all versions\n const versions = ArtifactMetadataEngine.Instance.GetCachedVersionsForArtifact(this.artifactVersion.ArtifactID);\n for (const v of versions) {\n try {\n if (!v.Content) continue;\n const content = typeof v.Content === 'string' ? JSON.parse(v.Content) : v.Content;\n if (content.savedQueryId === queryId && content.savedAtVersionNumber != null) {\n const vSavedAt = content.savedAtVersionNumber as number;\n if (effective == null || vSavedAt > effective) {\n effective = vSavedAt;\n }\n }\n } catch {\n // Skip versions with unparseable content\n }\n }\n\n return effective;\n }\n\n /**\n * Look up the saved query's SQL from QueryEngine cache for comparison.\n * Only fetches if savedQueryId is present.\n */\n private async resolveSavedQuerySql(): Promise<void> {\n if (!this.spec?.savedQueryId) {\n this.savedQuerySql = null;\n return;\n }\n\n // QueryEngine is registered for startup, should already be loaded\n let query = QueryEngine.Instance.FindQueryByID(this.spec.savedQueryId);\n\n if (!query) {\n // Cache miss — force refresh and retry\n await QueryEngine.Instance.Config(true);\n query = QueryEngine.Instance.FindQueryByID(this.spec.savedQueryId);\n }\n\n this.savedQuerySql = query?.SQL ?? null;\n }\n\n /**\n * Compute the query sync state from current spec, version, and saved query SQL.\n * Implements the decision tree from the UX design.\n */\n private computeQuerySyncState(): QuerySyncState {\n const hasSavedQuery = !!this.spec?.savedQueryId;\n const isLatest = this.IsLatestVersion;\n\n if (!hasSavedQuery) {\n return isLatest ? 'no-query-latest' : 'no-query-older';\n }\n\n // Compare SQL (normalize whitespace for reliable comparison)\n const specSql = this.normalizeSql(this.spec?.metadata?.sql);\n const querySql = this.normalizeSql(this.savedQuerySql);\n const sqlMatches = specSql != null && querySql != null && specSql === querySql;\n\n // Only truly synced if SQL matches AND this is the version it was saved at.\n // Even with identical SQL, a newer version should show the dropdown so the\n // user can update the version association (re-save at current version).\n const savedAtCurrent = this.EffectiveSavedAtVersion === this.CurrentVersionNumber;\n if (sqlMatches && savedAtCurrent) {\n return 'synced';\n }\n\n // SQL differs — determine position relative to saved version\n if (isLatest) {\n return 'outdated-latest';\n }\n\n // Use effective saved-at (looks ahead through newer versions)\n const savedAt = this.EffectiveSavedAtVersion;\n if (savedAt != null && this.CurrentVersionNumber < savedAt) {\n return 'query-ahead'; // query was updated at a newer version\n }\n\n return 'query-behind'; // ahead of saved but not latest\n }\n\n /** Normalize SQL for comparison: trim and collapse whitespace */\n private normalizeSql(sql: string | null | undefined): string | null {\n if (sql == null) return null;\n return sql.trim().replace(/\\s+/g, ' ');\n }\n\n // ─── Actions ────────────────────────────────────────────────────\n\n /** Navigate to the saved query in the Data Explorer's Queries browser */\n public OnOpenSavedQuery(): void {\n if (!this.spec?.savedQueryId) return;\n this.navigationRequest.emit({\n appName: 'Data Explorer',\n navItemName: 'Queries',\n queryParams: { queryId: this.spec.savedQueryId }\n });\n }\n\n /** Show the save panel for creating a brand-new query */\n public OnShowSaveDialog(): void {\n this.ShowSaveDialog = true;\n this.ShowUpdateDropdown = false;\n }\n\n /** Toggle the update query dropdown */\n public OnToggleUpdateDropdown(): void {\n this.ShowUpdateDropdown = !this.ShowUpdateDropdown;\n }\n\n /** Close the dropdown (e.g., on outside click) */\n public OnCloseDropdown(): void {\n this.ShowUpdateDropdown = false;\n }\n\n /**\n * Update the existing saved query's SQL to match this version.\n * Only available from the latest version (Scenario 3).\n */\n public async OnUpdateExistingQuery(): Promise<void> {\n this.ShowUpdateDropdown = false;\n if (!this.spec?.savedQueryId || !this.spec.metadata?.sql) return;\n\n this.IsSaving = true;\n this.SavingMessage = `Updating \"${this.SavedQueryDisplayName}\"...`;\n this.cdr.detectChanges();\n\n try {\n const md = this.ProviderToUse;\n const query = await md.GetEntityObject<import('@memberjunction/core-entities').MJQueryEntity>('MJ: Queries');\n const loaded = await query.Load(this.spec.savedQueryId);\n\n if (!loaded) {\n console.error('Failed to load saved query for update');\n return;\n }\n\n query.SQL = this.spec.metadata.sql;\n if (this.spec.plan?.trim()) {\n query.TechnicalDescription = this.spec.plan.trim();\n }\n const saved = await query.Save();\n\n if (saved) {\n // Update spec with new version tracking\n this.spec.savedAtVersionNumber = this.CurrentVersionNumber;\n await this.PersistArtifactContent();\n\n // Refresh caches so future lookups see the updated data\n await QueryEngine.Instance.Config(true);\n await ArtifactMetadataEngine.Instance.Config(true);\n\n this.savedQuerySql = this.spec.metadata.sql;\n this.EffectiveSavedAtVersion = this.CurrentVersionNumber;\n this.QuerySyncState = 'synced';\n }\n } catch (error) {\n console.error('Failed to update saved query:', error);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Save as a new query (from the dropdown).\n * Opens the save dialog which creates a fresh query record.\n */\n public OnSaveAsNewQuery(): void {\n this.ShowUpdateDropdown = false;\n this.ShowSaveDialog = true;\n }\n\n /** Handle successful save from the dialog (both initial save and \"save as new\") */\n public async OnQuerySaved(event: SaveQueryResult): Promise<void> {\n this.ShowSaveDialog = false;\n this.IsSaving = true;\n this.SavingMessage = 'Saving query...';\n this.cdr.detectChanges();\n\n try {\n // Update spec with saved query info and version tracking\n this.spec!.savedQueryId = event.queryId;\n this.spec!.savedQueryName = event.queryName;\n this.spec!.savedAtVersionNumber = this.CurrentVersionNumber;\n\n // Persist and refresh caches\n await this.PersistArtifactContent();\n await QueryEngine.Instance.Config(true);\n await ArtifactMetadataEngine.Instance.Config(true);\n await this.ProviderToUse.Refresh();\n\n this.savedQuerySql = this.spec!.metadata?.sql ?? null;\n this.EffectiveSavedAtVersion = this.CurrentVersionNumber;\n this.QuerySyncState = 'synced';\n } catch (error) {\n console.error('Failed to save query:', error);\n } finally {\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Persist updated spec back to the artifact version entity */\n private async PersistArtifactContent(): Promise<void> {\n if (!this.artifactVersion || !this.spec) return;\n this.artifactVersion.Content = JSON.stringify(this.spec);\n await this.artifactVersion.Save();\n }\n\n /**\n * Returns a DataSnapshot with live grid data, current page state,\n * and query sync state.\n */\n public override GetCurrentStateSnapshot(): DataSnapshot | null {\n if (!this.spec) return null;\n\n const tables = NormalizeToTables(\n this.spec as unknown as Record<string, unknown>,\n this.spec.title || 'Results'\n );\n const activeTable = tables[this.ActiveTableIndex];\n\n if (activeTable) {\n // Override with live data for the active table\n if (this.IsLive) activeTable.rows = this.GridData;\n activeTable.pageNumber = this.PagerPageNumber;\n activeTable.metadata = {\n ...activeTable.metadata,\n ...(this.liveRowCount != null ? { rowCount: this.liveRowCount } : {}),\n ...(this.liveExecutionTime != null\n ? { executionTimeMs: this.liveExecutionTime } : {}),\n ...(this.PagerTotalRowCount > 0\n ? { totalAvailableRows: this.PagerTotalRowCount } : {}),\n pageSize: this.PagerPageSize\n };\n }\n\n return DataSnapshot.FromTables(tables, this.spec.title);\n }\n\n // ─── Tabs ───────────────────────────────────────────────────────\n\n /**\n * Provide Plan tab (markdown), SQL tab (code), and Interpretation tab when available\n */\n public GetAdditionalTabs(): ArtifactViewerTab[] {\n const tabs: ArtifactViewerTab[] = [];\n\n if (this.spec?.plan) {\n tabs.push({\n label: 'Plan',\n icon: 'fa-diagram-project',\n contentType: 'markdown',\n content: this.spec.plan\n });\n }\n\n // SQL tab — multi-table shows all queries with headers\n if (this.IsMultiTable) {\n const multiSql = buildMultiTableSql(this.ResolvedTables);\n if (multiSql) {\n tabs.push({\n label: 'SQL',\n icon: 'fa-database',\n contentType: 'code',\n language: 'sql',\n content: multiSql\n });\n }\n } else if (this.spec?.metadata?.sql) {\n tabs.push({\n label: 'SQL',\n icon: 'fa-database',\n contentType: 'code',\n language: 'sql',\n content: this.spec.metadata.sql\n });\n }\n\n // Interpretation tab\n if (this.spec?.interpretation) {\n tabs.push({\n label: 'Interpretation',\n icon: 'fa-lightbulb',\n contentType: 'markdown',\n content: this.spec.interpretation\n });\n }\n\n return tabs;\n }\n}\n","<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 → 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 → 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 → 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 → 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"]}
@@ -675,7 +675,7 @@ export class DataRequirementsViewerComponent {
675
675
  } if (rf & 2) {
676
676
  i0.ɵɵadvance();
677
677
  i0.ɵɵconditional(!ctx.hasData ? 1 : 2);
678
- } }, dependencies: [i1.NgClass, i2.MarkdownComponent, i3.MJEmptyStateComponent], styles: [".data-requirements-viewer[_ngcontent-%COMP%] {\n padding: 0;\n height: 100%;\n overflow-y: auto;\n background: var(--mj-bg-surface-sunken);\n}\n\n\n\n.summary-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 0;\n}\n\n.mode-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n}\n\n.mode-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n opacity: 0.9;\n}\n\n.stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n line-height: 1;\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n opacity: 0.85;\n}\n\n\n\n.description-section[_ngcontent-%COMP%] {\n padding: 20px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.description-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.description-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.description-content[_ngcontent-%COMP%] {\n font-size: 14px;\n line-height: 1.6;\n color: var(--mj-text-secondary);\n}\n\n.description-content[_ngcontent-%COMP%] p {\n margin: 0 0 12px 0;\n}\n\n.description-content[_ngcontent-%COMP%] p:last-child {\n margin-bottom: 0;\n}\n\n.description-content[_ngcontent-%COMP%] pre {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n}\n\n.description-content[_ngcontent-%COMP%] code {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 13px;\n}\n\n\n\n.section[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 18px;\n}\n\n\n\n.cards-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n\n\n.data-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n transition: box-shadow 0.2s ease, border-color 0.2s ease;\n}\n\n.data-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.data-card.expanded[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-md);\n}\n\n\n\n.card-header[_ngcontent-%COMP%] {\n padding: 16px;\n cursor: pointer;\n user-select: none;\n}\n\n.card-title-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.card-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.card-icon.query-icon[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.card-title-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.title-with-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n margin-bottom: 4px;\n}\n\n.card-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.new-query-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 700;\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n animation: _ngcontent-%COMP%_subtle-pulse 2s ease-in-out infinite;\n}\n\n.new-query-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n@keyframes _ngcontent-%COMP%_subtle-pulse {\n 0%, 100% {\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n }\n 50% {\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-status-success) 40%, transparent);\n }\n}\n\n.card-path[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n}\n\n.card-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 12px;\n padding: 4px;\n}\n\n.data-card.expanded[_ngcontent-%COMP%] .expand-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.card-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.permissions-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.permission-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 4px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-inverse);\n text-transform: capitalize;\n}\n\n.permission-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.field-count[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.entity-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.entity-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 4px;\n font-size: 11px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.entity-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n\n\n.card-body[_ngcontent-%COMP%] {\n padding: 0 16px 16px 16px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n\n\n.usage-context[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 12px;\n margin-top: 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-status-warning);\n}\n\n.usage-context[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n margin-top: 2px;\n}\n\n\n\n.fields-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n\n.fields-title[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.fields-table[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.fields-header[_ngcontent-%COMP%] {\n display: flex;\n padding: 10px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.field-row[_ngcontent-%COMP%] {\n display: flex;\n padding: 10px 12px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n font-size: 13px;\n align-items: center;\n}\n\n.field-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.field-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-col[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.name-col[_ngcontent-%COMP%] {\n flex: 0 0 200px;\n min-width: 0;\n}\n\n.type-col[_ngcontent-%COMP%] {\n flex: 0 0 120px;\n}\n\n.tags-col[_ngcontent-%COMP%] {\n flex: 0 0 160px;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.desc-col[_ngcontent-%COMP%] {\n flex: 1;\n color: var(--mj-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.field-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.required-indicator[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-weight: bold;\n}\n\n.field-type[_ngcontent-%COMP%] {\n padding: 2px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n}\n\n.usage-tag[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n\n\n.parameters-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n\n.parameters-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.parameters-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.parameters-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.parameter-item[_ngcontent-%COMP%] {\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.param-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.param-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 14px;\n}\n\n.required-badge[_ngcontent-%COMP%] {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n text-transform: uppercase;\n}\n\n.optional-badge[_ngcontent-%COMP%] {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-text-muted);\n color: var(--mj-text-inverse);\n text-transform: uppercase;\n}\n\n.param-type[_ngcontent-%COMP%] {\n padding: 2px 6px;\n background: var(--mj-border-default);\n border-radius: 4px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n}\n\n.param-description[_ngcontent-%COMP%] {\n margin: 8px 0 0 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n}\n\n.param-sample[_ngcontent-%COMP%] {\n margin-top: 8px;\n font-size: 12px;\n}\n\n.sample-label[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n margin-right: 4px;\n}\n\n.param-sample[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n padding: 2px 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n color: var(--mj-status-error);\n}\n\n\n\n.sql-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n\n.sql-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sql-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.sql-code[_ngcontent-%COMP%] {\n margin: 0;\n padding: 16px;\n background: var(--mj-bg-code-block, #1e1e1e);\n border-radius: var(--mj-radius-md);\n font-size: var(--mj-text-xs);\n line-height: 1.5;\n color: var(--mj-text-code, #d4d4d4);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n overflow-x: auto;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n\n\n@media (max-width: 768px) {\n .summary-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n align-items: flex-start;\n }\n\n .stats[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: space-around;\n }\n\n .name-col[_ngcontent-%COMP%] {\n flex: 0 0 140px;\n }\n\n .type-col[_ngcontent-%COMP%] {\n flex: 0 0 90px;\n }\n\n .tags-col[_ngcontent-%COMP%] {\n flex: 0 0 120px;\n }\n\n .card-meta[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 8px;\n align-items: flex-start;\n }\n}"] });
678
+ } }, dependencies: [i1.NgClass, i2.MarkdownComponent, i3.MJEmptyStateComponent], styles: [".data-requirements-viewer[_ngcontent-%COMP%] {\n padding: 0;\n height: 100%;\n overflow-y: auto;\n background: var(--mj-bg-surface-sunken);\n}\n\n\n.summary-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 0;\n}\n\n.mode-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n}\n\n.mode-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n opacity: 0.9;\n}\n\n.stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n line-height: 1;\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n opacity: 0.85;\n}\n\n\n.description-section[_ngcontent-%COMP%] {\n padding: 20px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.description-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.description-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.description-content[_ngcontent-%COMP%] {\n font-size: 14px;\n line-height: 1.6;\n color: var(--mj-text-secondary);\n}\n\n.description-content[_ngcontent-%COMP%] p {\n margin: 0 0 12px 0;\n}\n\n.description-content[_ngcontent-%COMP%] p:last-child {\n margin-bottom: 0;\n}\n\n.description-content[_ngcontent-%COMP%] pre {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n}\n\n.description-content[_ngcontent-%COMP%] code {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 13px;\n}\n\n\n.section[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 18px;\n}\n\n\n.cards-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n\n.data-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n transition: box-shadow 0.2s ease, border-color 0.2s ease;\n}\n\n.data-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.data-card.expanded[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-md);\n}\n\n\n.card-header[_ngcontent-%COMP%] {\n padding: 16px;\n cursor: pointer;\n user-select: none;\n}\n\n.card-title-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.card-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.card-icon.query-icon[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.card-title-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.title-with-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n margin-bottom: 4px;\n}\n\n.card-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.new-query-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 700;\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n animation: _ngcontent-%COMP%_subtle-pulse 2s ease-in-out infinite;\n}\n\n.new-query-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n@keyframes _ngcontent-%COMP%_subtle-pulse {\n 0%, 100% {\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n }\n 50% {\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-status-success) 40%, transparent);\n }\n}\n\n.card-path[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n}\n\n.card-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 12px;\n padding: 4px;\n}\n\n.data-card.expanded[_ngcontent-%COMP%] .expand-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n.card-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.permissions-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.permission-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 4px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-inverse);\n text-transform: capitalize;\n}\n\n.permission-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.field-count[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.entity-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.entity-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 4px;\n font-size: 11px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.entity-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n\n.card-body[_ngcontent-%COMP%] {\n padding: 0 16px 16px 16px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n\n.usage-context[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 12px;\n margin-top: 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-status-warning);\n}\n\n.usage-context[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n margin-top: 2px;\n}\n\n\n.fields-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n\n.fields-title[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n.fields-table[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.fields-header[_ngcontent-%COMP%] {\n display: flex;\n padding: 10px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.field-row[_ngcontent-%COMP%] {\n display: flex;\n padding: 10px 12px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n font-size: 13px;\n align-items: center;\n}\n\n.field-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.field-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.field-col[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.name-col[_ngcontent-%COMP%] {\n flex: 0 0 200px;\n min-width: 0;\n}\n\n.type-col[_ngcontent-%COMP%] {\n flex: 0 0 120px;\n}\n\n.tags-col[_ngcontent-%COMP%] {\n flex: 0 0 160px;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.desc-col[_ngcontent-%COMP%] {\n flex: 1;\n color: var(--mj-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.field-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.required-indicator[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-weight: bold;\n}\n\n.field-type[_ngcontent-%COMP%] {\n padding: 2px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n}\n\n.usage-tag[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n\n.parameters-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n\n.parameters-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.parameters-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.parameters-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.parameter-item[_ngcontent-%COMP%] {\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.param-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.param-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 14px;\n}\n\n.required-badge[_ngcontent-%COMP%] {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n text-transform: uppercase;\n}\n\n.optional-badge[_ngcontent-%COMP%] {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-text-muted);\n color: var(--mj-text-inverse);\n text-transform: uppercase;\n}\n\n.param-type[_ngcontent-%COMP%] {\n padding: 2px 6px;\n background: var(--mj-border-default);\n border-radius: 4px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n}\n\n.param-description[_ngcontent-%COMP%] {\n margin: 8px 0 0 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n}\n\n.param-sample[_ngcontent-%COMP%] {\n margin-top: 8px;\n font-size: 12px;\n}\n\n.sample-label[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n margin-right: 4px;\n}\n\n.param-sample[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n padding: 2px 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n color: var(--mj-status-error);\n}\n\n\n.sql-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n\n.sql-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sql-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.sql-code[_ngcontent-%COMP%] {\n margin: 0;\n padding: 16px;\n background: var(--mj-bg-code-block, #1e1e1e);\n border-radius: var(--mj-radius-md);\n font-size: var(--mj-text-xs);\n line-height: 1.5;\n color: var(--mj-text-code, #d4d4d4);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n overflow-x: auto;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n\n@media (max-width: 768px) {\n .summary-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n align-items: flex-start;\n }\n\n .stats[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: space-around;\n }\n\n .name-col[_ngcontent-%COMP%] {\n flex: 0 0 140px;\n }\n\n .type-col[_ngcontent-%COMP%] {\n flex: 0 0 90px;\n }\n\n .tags-col[_ngcontent-%COMP%] {\n flex: 0 0 120px;\n }\n\n .card-meta[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 8px;\n align-items: flex-start;\n }\n}"] });
679
679
  }
680
680
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DataRequirementsViewerComponent, [{
681
681
  type: Component,
@@ -197,7 +197,7 @@ let DocxArtifactViewerComponent = class DocxArtifactViewerComponent extends Base
197
197
  i0.ɵɵproperty("fileName", ctx.artifactVersion.FileName || "document.docx")("isDownloading", ctx.isDownloading)("showPrint", true);
198
198
  i0.ɵɵadvance(2);
199
199
  i0.ɵɵconditional(ctx.isLoading ? 3 : ctx.errorMessage ? 4 : 5);
200
- } }, dependencies: [i3.FileArtifactToolbarComponent], styles: [".docx-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface);\n }\n\n .docx-viewer__body[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n }\n\n .docx-viewer__state[_ngcontent-%COMP%] {\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 .docx-viewer__state--error[_ngcontent-%COMP%] {\n color: var(--mj-status-error-text);\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] {\n padding: 32px 48px;\n max-width: 900px;\n margin: 0 auto;\n color: var(--mj-text-primary);\n font-size: 14px;\n line-height: 1.7;\n }\n\n \n\n .docx-viewer__content[_ngcontent-%COMP%] :is(h1[_ngcontent-%COMP%], h2[_ngcontent-%COMP%], h3[_ngcontent-%COMP%], h4[_ngcontent-%COMP%], h5[_ngcontent-%COMP%], h6[_ngcontent-%COMP%]) {\n color: var(--mj-text-primary);\n margin-top: 1.5em;\n margin-bottom: 0.5em;\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] table[_ngcontent-%COMP%] {\n border-collapse: collapse;\n width: 100%;\n margin: 1em 0;\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] :is(td[_ngcontent-%COMP%], th[_ngcontent-%COMP%]) {\n border: 1px solid var(--mj-border-default);\n padding: 6px 10px;\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n font-weight: 600;\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--mj-text-link);\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n max-width: 100%;\n height: auto;\n }"] });
200
+ } }, dependencies: [i3.FileArtifactToolbarComponent], styles: [".docx-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface);\n }\n\n .docx-viewer__body[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n }\n\n .docx-viewer__state[_ngcontent-%COMP%] {\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 .docx-viewer__state--error[_ngcontent-%COMP%] {\n color: var(--mj-status-error-text);\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] {\n padding: 32px 48px;\n max-width: 900px;\n margin: 0 auto;\n color: var(--mj-text-primary);\n font-size: 14px;\n line-height: 1.7;\n }\n\n \n .docx-viewer__content[_ngcontent-%COMP%] :is(h1[_ngcontent-%COMP%], h2[_ngcontent-%COMP%], h3[_ngcontent-%COMP%], h4[_ngcontent-%COMP%], h5[_ngcontent-%COMP%], h6[_ngcontent-%COMP%]) {\n color: var(--mj-text-primary);\n margin-top: 1.5em;\n margin-bottom: 0.5em;\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] table[_ngcontent-%COMP%] {\n border-collapse: collapse;\n width: 100%;\n margin: 1em 0;\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] :is(td[_ngcontent-%COMP%], th[_ngcontent-%COMP%]) {\n border: 1px solid var(--mj-border-default);\n padding: 6px 10px;\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n font-weight: 600;\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--mj-text-link);\n }\n\n .docx-viewer__content[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n max-width: 100%;\n height: auto;\n }"] });
201
201
  };
202
202
  DocxArtifactViewerComponent = __decorate([
203
203
  RegisterClass(BaseArtifactViewerPluginComponent, 'DocxArtifactViewerPlugin')
@@ -361,7 +361,7 @@ let ImageArtifactViewerComponent = class ImageArtifactViewerComponent extends Ba
361
361
  i0.ɵɵconditional(ctx.errorMessage ? 3 : 4);
362
362
  i0.ɵɵadvance(2);
363
363
  i0.ɵɵconditional(ctx.naturalWidth && ctx.naturalHeight && !ctx.isLoading && !ctx.errorMessage ? 5 : -1);
364
- } }, dependencies: [i2.NgClass, i3.FileArtifactToolbarComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n }\n\n .image-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n position: relative;\n }\n\n .image-viewer__body[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n }\n\n \n\n\n .image-viewer__body--actual[_ngcontent-%COMP%] {\n align-items: flex-start;\n justify-content: flex-start;\n }\n\n .image-viewer__state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n color: var(--mj-text-muted);\n font-size: 14px;\n }\n\n .image-viewer__state--error[_ngcontent-%COMP%] {\n color: var(--mj-status-error-text);\n }\n\n .image-viewer__img[_ngcontent-%COMP%] {\n \n\n max-width: 100%;\n max-height: 100%;\n width: auto;\n height: auto;\n object-fit: contain;\n cursor: zoom-in;\n background: var(--mj-bg-surface);\n border-radius: 4px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transition: opacity 0.18s ease-out;\n }\n\n \n\n\n .image-viewer__img--actual[_ngcontent-%COMP%] {\n max-width: none;\n max-height: none;\n width: auto;\n height: auto;\n cursor: zoom-out;\n }\n\n \n\n\n .image-viewer__img--hidden[_ngcontent-%COMP%] {\n opacity: 0;\n position: absolute;\n pointer-events: none;\n }\n\n .image-viewer__dimensions[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 8px;\n right: 12px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-bg-surface-elevated) 90%, transparent);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n color: var(--mj-text-muted);\n font-size: 11px;\n font-variant-numeric: tabular-nums;\n pointer-events: none;\n \n\n }"] });
364
+ } }, dependencies: [i2.NgClass, i3.FileArtifactToolbarComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n }\n\n .image-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n position: relative;\n }\n\n .image-viewer__body[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n }\n\n \n\n .image-viewer__body--actual[_ngcontent-%COMP%] {\n align-items: flex-start;\n justify-content: flex-start;\n }\n\n .image-viewer__state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n color: var(--mj-text-muted);\n font-size: 14px;\n }\n\n .image-viewer__state--error[_ngcontent-%COMP%] {\n color: var(--mj-status-error-text);\n }\n\n .image-viewer__img[_ngcontent-%COMP%] {\n \n max-width: 100%;\n max-height: 100%;\n width: auto;\n height: auto;\n object-fit: contain;\n cursor: zoom-in;\n background: var(--mj-bg-surface);\n border-radius: 4px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transition: opacity 0.18s ease-out;\n }\n\n \n\n .image-viewer__img--actual[_ngcontent-%COMP%] {\n max-width: none;\n max-height: none;\n width: auto;\n height: auto;\n cursor: zoom-out;\n }\n\n \n\n .image-viewer__img--hidden[_ngcontent-%COMP%] {\n opacity: 0;\n position: absolute;\n pointer-events: none;\n }\n\n .image-viewer__dimensions[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 8px;\n right: 12px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-bg-surface-elevated) 90%, transparent);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n color: var(--mj-text-muted);\n font-size: 11px;\n font-variant-numeric: tabular-nums;\n pointer-events: none;\n \n }"] });
365
365
  };
366
366
  ImageArtifactViewerComponent = __decorate([
367
367
  RegisterClass(BaseArtifactViewerPluginComponent, 'ImageArtifactViewerPlugin')
@@ -38,6 +38,14 @@ export declare class JsonArtifactViewerComponent extends BaseArtifactViewerPlugi
38
38
  get parentShouldShowRawContent(): boolean;
39
39
  private loadVersionAttributes;
40
40
  private parseAttributeValue;
41
+ /**
42
+ * Returns the iframe's document when accessible, or null.
43
+ * With allow-same-origin removed from the sandbox (see template), the frame is
44
+ * cross-origin to the app: contentDocument returns null or the access throws a
45
+ * SecurityError depending on the browser. Both outcomes are tolerated — the
46
+ * style/resize enhancements below are optional niceties, not requirements.
47
+ */
48
+ private getIframeDocument;
41
49
  onIframeLoad(): void;
42
50
  private resizeIframeToContent;
43
51
  openInNewWindow(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"json-artifact-viewer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/plugins/json-artifact-viewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAa,UAAU,EAAE,MAAM,eAAe,CAAC;AAEvG,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE1E,OAAO,EAAE,iCAAiC,EAAE,MAAM,mCAAmC,CAAC;AACtF,OAAO,EAAE,YAAY,EAAW,MAAM,sBAAsB,CAAC;;AAI7D;;;;GAIG;AACH,qBAsHa,2BAA4B,SAAQ,iCAAkC,YAAW,MAAM,EAAE,SAAS;IAkB3G,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,SAAS;IAlBK,SAAS,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAE3D,WAAW,SAAM;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,WAAW,EAAE,eAAe,GAAG,IAAI,CAAQ;IAClD,OAAO,CAAC,iBAAiB,CAA0C;IACnE,OAAO,CAAC,aAAa,CAAuB;IAE5C;;OAEG;IACH,IAAoB,iBAAiB,IAAI,OAAO,CAE/C;gBAGS,GAAG,EAAE,iBAAiB,EACtB,SAAS,EAAE,YAAY;IAKjC,WAAW,IAAI,IAAI;IASb,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAU/B;;;OAGG;IACH,IAAoB,wBAAwB,IAAI,OAAO,CAEtD;IAED;;;;OAIG;IACH,IAAoB,0BAA0B,IAAI,OAAO,CAExD;YAEa,qBAAqB;IA6DnC,OAAO,CAAC,mBAAmB;IAyB3B,YAAY,IAAI,IAAI;IA2DpB,OAAO,CAAC,qBAAqB;IAsB7B,eAAe,IAAI,IAAI;IAUvB,SAAS,IAAI,IAAI;IAWjB,MAAM,IAAI,IAAI;IAYE,uBAAuB,IAAI,YAAY,GAAG,IAAI;IAI9D;;;OAGG;IACH,OAAO,CAAC,sBAAsB;yCA5QnB,2BAA2B;2CAA3B,2BAA2B;CA+RvC"}
1
+ {"version":3,"file":"json-artifact-viewer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/plugins/json-artifact-viewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAa,UAAU,EAAE,MAAM,eAAe,CAAC;AAEvG,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE1E,OAAO,EAAE,iCAAiC,EAAE,MAAM,mCAAmC,CAAC;AACtF,OAAO,EAAE,YAAY,EAAW,MAAM,sBAAsB,CAAC;;AAI7D;;;;GAIG;AACH,qBA8Ha,2BAA4B,SAAQ,iCAAkC,YAAW,MAAM,EAAE,SAAS;IAkB3G,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,SAAS;IAlBK,SAAS,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAE3D,WAAW,SAAM;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,WAAW,EAAE,eAAe,GAAG,IAAI,CAAQ;IAClD,OAAO,CAAC,iBAAiB,CAA0C;IACnE,OAAO,CAAC,aAAa,CAAuB;IAE5C;;OAEG;IACH,IAAoB,iBAAiB,IAAI,OAAO,CAE/C;gBAGS,GAAG,EAAE,iBAAiB,EACtB,SAAS,EAAE,YAAY;IAKjC,WAAW,IAAI,IAAI;IASb,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAU/B;;;OAGG;IACH,IAAoB,wBAAwB,IAAI,OAAO,CAEtD;IAED;;;;OAIG;IACH,IAAoB,0BAA0B,IAAI,OAAO,CAExD;YAEa,qBAAqB;IA6DnC,OAAO,CAAC,mBAAmB;IAyB3B;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAUzB,YAAY,IAAI,IAAI;IA0DpB,OAAO,CAAC,qBAAqB;IAwB7B,eAAe,IAAI,IAAI;IAUvB,SAAS,IAAI,IAAI;IAkBjB,MAAM,IAAI,IAAI;IAYE,uBAAuB,IAAI,YAAY,GAAG,IAAI;IAI9D;;;OAGG;IACH,OAAO,CAAC,sBAAsB;yCArSnB,2BAA2B;2CAA3B,2BAA2B;CAwTvC"}
@@ -188,11 +188,28 @@ let JsonArtifactViewerComponent = class JsonArtifactViewerComponent extends Base
188
188
  return value === 'null' ? null : value;
189
189
  }
190
190
  }
191
+ /**
192
+ * Returns the iframe's document when accessible, or null.
193
+ * With allow-same-origin removed from the sandbox (see template), the frame is
194
+ * cross-origin to the app: contentDocument returns null or the access throws a
195
+ * SecurityError depending on the browser. Both outcomes are tolerated — the
196
+ * style/resize enhancements below are optional niceties, not requirements.
197
+ */
198
+ getIframeDocument() {
199
+ try {
200
+ const iframe = this.htmlFrame?.nativeElement;
201
+ if (!iframe)
202
+ return null;
203
+ return iframe.contentDocument || iframe.contentWindow?.document || null;
204
+ }
205
+ catch {
206
+ return null;
207
+ }
208
+ }
191
209
  onIframeLoad() {
192
210
  // Inject base styles if HTML doesn't have them
193
211
  if (this.htmlFrame) {
194
- const iframe = this.htmlFrame.nativeElement;
195
- const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
212
+ const iframeDoc = this.getIframeDocument();
196
213
  if (iframeDoc) {
197
214
  // Check if HTML already has styles
198
215
  const hasStyles = iframeDoc.querySelector('style') || iframeDoc.querySelector('link[rel="stylesheet"]');
@@ -244,7 +261,9 @@ let JsonArtifactViewerComponent = class JsonArtifactViewerComponent extends Base
244
261
  resizeIframeToContent() {
245
262
  if (this.htmlFrame) {
246
263
  const iframe = this.htmlFrame.nativeElement;
247
- const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
264
+ // Cross-origin (sandboxed) frames yield no document — the CSS flex sizing on
265
+ // .html-iframe is the fallback in that case.
266
+ const iframeDoc = this.getIframeDocument();
248
267
  if (iframeDoc && iframeDoc.body) {
249
268
  // Get the actual content height
250
269
  const contentHeight = Math.max(iframeDoc.body.scrollHeight, iframeDoc.body.offsetHeight, iframeDoc.documentElement.scrollHeight, iframeDoc.documentElement.offsetHeight);
@@ -265,11 +284,19 @@ let JsonArtifactViewerComponent = class JsonArtifactViewerComponent extends Base
265
284
  }
266
285
  printHtml() {
267
286
  if (this.htmlFrame) {
268
- const iframe = this.htmlFrame.nativeElement;
269
- const iframeWindow = iframe.contentWindow;
270
- if (iframeWindow) {
271
- iframeWindow.focus();
272
- iframeWindow.print();
287
+ try {
288
+ const iframe = this.htmlFrame.nativeElement;
289
+ const iframeWindow = iframe.contentWindow;
290
+ if (iframeWindow) {
291
+ iframeWindow.focus();
292
+ iframeWindow.print();
293
+ }
294
+ }
295
+ catch {
296
+ // The sandboxed frame is cross-origin, so scripting into it can throw a
297
+ // SecurityError in some browsers. Fall back to printing the host page,
298
+ // which includes the rendered iframe content.
299
+ window.print();
273
300
  }
274
301
  }
275
302
  }
@@ -311,7 +338,7 @@ let JsonArtifactViewerComponent = class JsonArtifactViewerComponent extends Base
311
338
  } if (rf & 2) {
312
339
  let _t;
313
340
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.htmlFrame = _t.first);
314
- } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 10, vars: 3, consts: [["htmlFrame", ""], [1, "json-artifact-viewer", 3, "ngClass"], [1, "display-toolbar"], ["title", "Copy Content", 1, "btn-icon", 3, "click"], [1, "fas", "fa-copy"], [1, "display-content"], ["sandbox", "allow-same-origin allow-scripts allow-popups allow-popups-to-escape-sandbox allow-modals", 1, "html-iframe", 3, "src"], [1, "markdown-content"], [1, "json-editor-container"], ["title", "Open in New Window", 1, "btn-icon", 3, "click"], [1, "fas", "fa-external-link-alt"], ["title", "Print", 1, "btn-icon", 3, "click"], [1, "fas", "fa-print"], ["sandbox", "allow-same-origin allow-scripts allow-popups allow-popups-to-escape-sandbox allow-modals", 1, "html-iframe", 3, "load", "src"], [3, "data", "enableCollapsibleHeadings", "enableLineNumbers", "enableSmartypants", "enableHtml"], [2, "width", "100%", "height", "100%", 3, "ngModelChange", "ngModel", "language", "readonly"]], template: function JsonArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
341
+ } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 10, vars: 3, consts: [["htmlFrame", ""], [1, "json-artifact-viewer", 3, "ngClass"], [1, "display-toolbar"], ["title", "Copy Content", 1, "btn-icon", 3, "click"], [1, "fas", "fa-copy"], [1, "display-content"], ["sandbox", "allow-scripts allow-popups allow-popups-to-escape-sandbox allow-modals", 1, "html-iframe", 3, "src"], [1, "markdown-content"], [1, "json-editor-container"], ["title", "Open in New Window", 1, "btn-icon", 3, "click"], [1, "fas", "fa-external-link-alt"], ["title", "Print", 1, "btn-icon", 3, "click"], [1, "fas", "fa-print"], ["sandbox", "allow-scripts allow-popups allow-popups-to-escape-sandbox allow-modals", 1, "html-iframe", 3, "load", "src"], [3, "data", "enableCollapsibleHeadings", "enableLineNumbers", "enableSmartypants", "enableHtml"], [2, "width", "100%", "height", "100%", 3, "ngModelChange", "ngModel", "language", "readonly"]], template: function JsonArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
315
342
  i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "button", 3);
316
343
  i0.ɵɵlistener("click", function JsonArtifactViewerComponent_Template_button_click_2_listener() { return ctx.onCopy(); });
317
344
  i0.ɵɵelement(3, "i", 4);
@@ -328,7 +355,7 @@ let JsonArtifactViewerComponent = class JsonArtifactViewerComponent extends Base
328
355
  i0.ɵɵconditional(ctx.displayHtml ? 5 : -1);
329
356
  i0.ɵɵadvance(2);
330
357
  i0.ɵɵconditional(ctx.displayHtml && ctx.htmlBlobUrl ? 7 : ctx.displayMarkdown ? 8 : 9);
331
- } }, dependencies: [i2.NgClass, i3.NgControlStatus, i3.NgModel, i4.MarkdownComponent, i5.CodeEditorComponent], styles: [".json-artifact-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .display-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .btn-icon[_ngcontent-%COMP%] {\n padding: 6px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n }\n\n .btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n }\n\n .display-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n .html-iframe[_ngcontent-%COMP%] {\n width: 100%;\n border: none;\n background: var(--mj-bg-surface);\n display: block;\n }\n\n .markdown-content[_ngcontent-%COMP%] {\n flex: 1;\n padding: 20px;\n overflow: auto;\n min-height: 0;\n background: var(--mj-bg-surface);\n }\n\n .json-editor-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n min-height: 0;\n }"] });
358
+ } }, dependencies: [i2.NgClass, i3.NgControlStatus, i3.NgModel, i4.MarkdownComponent, i5.CodeEditorComponent], styles: [".json-artifact-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .display-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .btn-icon[_ngcontent-%COMP%] {\n padding: 6px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n }\n\n .btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n }\n\n .display-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n .html-iframe[_ngcontent-%COMP%] {\n width: 100%;\n border: none;\n background: var(--mj-bg-surface);\n display: block;\n \n\n flex: 1;\n min-height: 0;\n }\n\n .markdown-content[_ngcontent-%COMP%] {\n flex: 1;\n padding: 20px;\n overflow: auto;\n min-height: 0;\n background: var(--mj-bg-surface);\n }\n\n .json-editor-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n min-height: 0;\n }"] });
332
359
  };
333
360
  JsonArtifactViewerComponent = __decorate([
334
361
  RegisterClass(BaseArtifactViewerPluginComponent, 'JsonArtifactViewerPlugin')
@@ -356,11 +383,15 @@ export { JsonArtifactViewerComponent };
356
383
  <!-- Display content: priority order = displayHtml > displayMarkdown > JSON editor -->
357
384
  <div class="display-content">
358
385
  @if (displayHtml && htmlBlobUrl) {
359
- <!-- Sandboxed iframe for rich HTML using blob URL -->
386
+ <!-- Sandboxed iframe for rich HTML using blob URL.
387
+ SECURITY: never add allow-same-origin here — a blob: URL inherits the app origin,
388
+ so allow-same-origin + allow-scripts on LLM-produced HTML is in-origin XSS
389
+ (script in the artifact could read the app's storage/cookies and DOM).
390
+ Same pattern as whiteboard-srcdoc.pipe.ts. -->
360
391
  <iframe
361
392
  #htmlFrame
362
393
  [src]="htmlBlobUrl"
363
- sandbox="allow-same-origin allow-scripts allow-popups allow-popups-to-escape-sandbox allow-modals"
394
+ sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox allow-modals"
364
395
  class="html-iframe"
365
396
  (load)="onIframeLoad()">
366
397
  </iframe>
@@ -384,10 +415,10 @@ export { JsonArtifactViewerComponent };
384
415
  }
385
416
  </div>
386
417
  </div>
387
- `, styles: ["\n .json-artifact-viewer {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .display-toolbar {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .btn-icon {\n padding: 6px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n }\n\n .btn-icon:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n }\n\n .display-content {\n flex: 1;\n overflow: auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n .html-iframe {\n width: 100%;\n border: none;\n background: var(--mj-bg-surface);\n display: block;\n }\n\n .markdown-content {\n flex: 1;\n padding: 20px;\n overflow: auto;\n min-height: 0;\n background: var(--mj-bg-surface);\n }\n\n .json-editor-container {\n flex: 1;\n overflow: auto;\n min-height: 0;\n }\n "] }]
418
+ `, styles: ["\n .json-artifact-viewer {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .display-toolbar {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .btn-icon {\n padding: 6px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n }\n\n .btn-icon:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n }\n\n .display-content {\n flex: 1;\n overflow: auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n .html-iframe {\n width: 100%;\n border: none;\n background: var(--mj-bg-surface);\n display: block;\n /* The frame is cross-origin (sandbox without allow-same-origin), so script-driven\n auto-resize is unavailable \u2014 fill the container instead. */\n flex: 1;\n min-height: 0;\n }\n\n .markdown-content {\n flex: 1;\n padding: 20px;\n overflow: auto;\n min-height: 0;\n background: var(--mj-bg-surface);\n }\n\n .json-editor-container {\n flex: 1;\n overflow: auto;\n min-height: 0;\n }\n "] }]
388
419
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.DomSanitizer }], { htmlFrame: [{
389
420
  type: ViewChild,
390
421
  args: ['htmlFrame']
391
422
  }] }); })();
392
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(JsonArtifactViewerComponent, { className: "JsonArtifactViewerComponent", filePath: "src/lib/components/plugins/json-artifact-viewer.component.ts", lineNumber: 133 }); })();
423
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(JsonArtifactViewerComponent, { className: "JsonArtifactViewerComponent", filePath: "src/lib/components/plugins/json-artifact-viewer.component.ts", lineNumber: 141 }); })();
393
424
  //# sourceMappingURL=json-artifact-viewer.component.js.map