@memberjunction/ng-dashboards 6.1.3 → 6.2.0-edge.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +6 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +99 -45
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +4 -0
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +16 -6
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +4 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +14 -4
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +2 -2
- package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
- package/dist/DevTools/graphql-console.component.d.ts.map +1 -1
- package/dist/DevTools/graphql-console.component.js +2 -0
- package/dist/DevTools/graphql-console.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +2 -0
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts +4 -12
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js +39 -78
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts +3 -0
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +7 -6
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts +3 -0
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +7 -6
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/at-risk.view-models.d.ts +41 -3
- package/dist/PredictiveStudio/at-risk.view-models.d.ts.map +1 -1
- package/dist/PredictiveStudio/at-risk.view-models.js +99 -6
- package/dist/PredictiveStudio/at-risk.view-models.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.d.ts +4 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.js +61 -37
- package/dist/PredictiveStudio/components/ps-catalog.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-experiments.component.d.ts +12 -0
- package/dist/PredictiveStudio/components/ps-experiments.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-experiments.component.js +426 -184
- package/dist/PredictiveStudio/components/ps-experiments.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts +84 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js +1397 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts +66 -34
- package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipelines.component.js +2456 -743
- package/dist/PredictiveStudio/components/ps-pipelines.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts +194 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.js +1902 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-production.component.d.ts +17 -1
- package/dist/PredictiveStudio/components/ps-production.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-production.component.js +653 -372
- package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-registry.component.d.ts +21 -61
- package/dist/PredictiveStudio/components/ps-registry.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-registry.component.js +214 -681
- package/dist/PredictiveStudio/components/ps-registry.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts +49 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js +658 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js.map +1 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts +42 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts.map +1 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.js +90 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.js.map +1 -0
- package/dist/PredictiveStudio/predictive-studio.view-models.d.ts +14 -2
- package/dist/PredictiveStudio/predictive-studio.view-models.d.ts.map +1 -1
- package/dist/PredictiveStudio/predictive-studio.view-models.js +41 -5
- package/dist/PredictiveStudio/predictive-studio.view-models.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts +9 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.js +178 -65
- package/dist/PredictiveStudio/resources/ps-models-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts +9 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js +307 -369
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-resource-base.js +1 -1
- package/dist/PredictiveStudio/resources/ps-resource-base.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts +17 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.js +309 -138
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.d.ts +1 -0
- package/dist/VersionHistory/components/graph-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +6 -5
- package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
- package/dist/predictive-studio-dashboards.module.d.ts +10 -8
- package/dist/predictive-studio-dashboards.module.d.ts.map +1 -1
- package/dist/predictive-studio-dashboards.module.js +13 -3
- package/dist/predictive-studio-dashboards.module.js.map +1 -1
- package/package.json +64 -63
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ps-studio-resource.component.js","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-studio-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { LogError, UserInfo } from '@memberjunction/core';\nimport { MJConversationEntity, MJEnvironmentEntityExtended } from '@memberjunction/core-entities';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { PSResourceBase } from './ps-resource-base';\nimport { PSPanelKey } from '../predictive-studio.types';\nimport {\n STUDIO_SECTIONS,\n PSSection,\n sectionGroups,\n sectionsInGroup,\n sectionLabel,\n hasSection,\n routeHomeNavigate,\n} from '../predictive-studio.nav';\nimport { buildStudioAgentContext, resolvePSRecord, buildPSNotFoundError } from '../predictive-studio-agent-context';\nimport { validateStringParam } from '../../shared/agent-tool-validation';\n\n/** Predictive Studio application ID (from `metadata/applications/.predictive-studio-application.json`). */\nconst PREDICTIVE_STUDIO_APP_ID = '299C9272-8D38-40CA-85D4-0980F2C9FAD1';\nconst MODEL_DEV_AGENT_NAME = 'Model Development Agent';\n\n/**\n * **Studio** — the analyst workbench door (one of Predictive Studio's three consolidated nav items,\n * alongside `Predictions` and `Models`). Hosts the build/run section panels (`ps-home`, `ps-pipelines`,\n * `ps-catalog`, `ps-experiments`, `ps-compare`) behind an internal left-nav grouped by lifecycle\n * (Overview · Build · Run), so the outer app nav stays quiet while analysts get all the depth one click\n * in. The active section round-trips through the `section` query param (deep links + back/forward). A\n * single docked **Model Development Agent** copilot is shared by every section's \"Ask the agent\" CTA —\n * wired with the full conversation lifecycle (`isNewConversation` → `conversationCreated`) so the first\n * message actually creates + sends. Cross-door navigation (to a Models section) routes via the nav\n * service; see {@link routeHomeNavigate}.\n */\n@RegisterClass(BaseResourceComponent, 'PredictiveStudioStudioResource')\n@Component({\n standalone: false,\n selector: 'mj-ps-studio-resource',\n template: `\n <mj-page-header-interior [Title]=\"activeLabel\" [Subtitle]=\"activeSubtitle\">\n </mj-page-header-interior>\n <mj-page-body-interior [Flex]=\"true\" [Padding]=\"false\">\n @if (isLoading) {\n <mj-loading text=\"Loading Studio…\" size=\"medium\"></mj-loading>\n } @else if (loadError) {\n <div class=\"ps-load-error\" data-testid=\"ps-load-error\" role=\"alert\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div class=\"ps-load-error-text\">\n <strong>Couldn't load {{ sectionTitle }}</strong>\n <span class=\"ps-load-error-detail\">{{ loadError }}</span>\n </div>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"retryLoad()\"><i class=\"fa-solid fa-rotate-right\"></i> Try again</button>\n </div>\n } @else {\n <div class=\"ps-studio-host\" [class.chat-open]=\"chatOpen\" data-testid=\"ps-studio-shell\">\n <aside class=\"ps-leftnav\">\n @for (group of groups; track group) {\n @if (group) { <div class=\"ps-nav-group\">{{ group }}</div> }\n @for (item of itemsForGroup(group); track item.key) {\n <button class=\"ps-nav-item\" [class.active]=\"activeSection === item.key\"\n [attr.data-testid]=\"'ps-nav-' + item.key\" (click)=\"selectSection(item.key)\">\n <i [class]=\"item.icon\"></i> <span>{{ item.label }}</span>\n </button>\n }\n }\n </aside>\n\n <section class=\"ps-content\" [class.fill]=\"activeSection === 'pipelines'\" [attr.data-testid]=\"'ps-panel-' + activeSection\">\n @switch (activeSection) {\n @case ('home') { <ps-home [engine]=\"engine\" [provider]=\"ProviderToUse\" [currentUser]=\"ProviderToUse.CurrentUser\" (navigate)=\"mapNavigate($event)\" (askAgent)=\"onAskAgent($event)\"></ps-home> }\n @case ('pipelines') { <ps-pipelines [engine]=\"engine\" [provider]=\"ProviderToUse\" [currentUser]=\"ProviderToUse.CurrentUser\" (askAgent)=\"onAskAgent($event)\"></ps-pipelines> }\n @case ('catalog') { <ps-catalog [engine]=\"engine\" (askAgent)=\"onAskAgent($event)\"></ps-catalog> }\n @case ('experiments') { <ps-experiments [engine]=\"engine\" [provider]=\"ProviderToUse\" [currentUser]=\"ProviderToUse.CurrentUser\"></ps-experiments> }\n @case ('compare') { <ps-compare [engine]=\"engine\"></ps-compare> }\n }\n </section>\n\n @if (chatOpen) {\n <aside class=\"ps-copilot\" data-testid=\"ps-studio-copilot\">\n <div class=\"ps-copilot-head\">\n <div class=\"ps-copilot-title\"><i class=\"fa-solid fa-robot\"></i> Model Dev Agent</div>\n <button class=\"ps-copilot-close\" (click)=\"closeChat()\" aria-label=\"Close agent chat\"><i class=\"fa-solid fa-xmark\"></i></button>\n </div>\n <div class=\"ps-copilot-body\">\n @if (currentUser) {\n <mj-conversation-chat-area\n [Provider]=\"Provider\" [environmentId]=\"chatEnvironmentId\" [currentUser]=\"currentUser\"\n [conversation]=\"chatConversation\" [conversationId]=\"chatConversationId\" [isNewConversation]=\"chatIsNewConversation\"\n [suppressNewConversationEmptyState]=\"true\" [allowMentions]=\"false\" [overlayMode]=\"true\"\n [showExportButton]=\"false\" [showShareButton]=\"false\" [showArtifactIndicator]=\"false\"\n [showAgentPicker]=\"false\" [showAgentModePicker]=\"false\"\n [defaultAgentId]=\"modelDevAgentId\" [pendingMessage]=\"pendingPrompt\"\n [applicationScope]=\"'Application'\" [applicationId]=\"applicationId\" [appContext]=\"chatAppContext\"\n (conversationCreated)=\"onChatConversationCreated($event)\"\n (pendingMessageConsumed)=\"onChatPendingMessageConsumed()\">\n </mj-conversation-chat-area>\n } @else { <div class=\"ps-copilot-empty\"><mj-loading text=\"Connecting…\" size=\"small\"></mj-loading></div> }\n </div>\n </aside>\n }\n </div>\n }\n </mj-page-body-interior>\n `,\n styles: [\n `\n :host { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-studio-host { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .ps-leftnav { width: 210px; flex: none; border-right: 1px solid var(--mj-border-default); background: var(--mj-bg-surface-card); overflow-y: auto; padding: 10px 8px; display: flex; flex-direction: column; gap: 2px; }\n .ps-nav-group { font-size: var(--mj-text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--mj-text-muted); padding: 12px 10px 4px; }\n .ps-nav-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 8px 10px; border: none; background: transparent; border-radius: var(--mj-radius-md); cursor: pointer; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); font-weight: 500; transition: background .12s, color .12s; }\n .ps-nav-item i { width: 18px; text-align: center; color: var(--mj-text-muted); }\n .ps-nav-item:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .ps-nav-item.active { background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); color: var(--mj-brand-primary); font-weight: 600; }\n .ps-nav-item.active i { color: var(--mj-brand-primary); }\n .ps-content { flex: 1; min-width: 0; overflow-y: auto; padding: 8px 14px 24px; }\n /* Fill mode (pipelines): the section stops page-scrolling so the panel's inner\n columns (canvas / inspector) can each own their scrollbar. */\n .ps-content.fill { overflow: hidden; display: flex; flex-direction: column; padding-bottom: 14px; }\n .ps-content.fill > * { flex: 1; min-height: 0; display: flex; flex-direction: column; }\n .ps-copilot { width: 420px; max-width: 42vw; flex: none; border-left: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); display: flex; flex-direction: column; min-height: 0; }\n .ps-copilot-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--mj-border-default); }\n .ps-copilot-title { display: flex; align-items: center; gap: 8px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-copilot-title i { color: var(--mj-brand-primary); }\n .ps-copilot-close { background: transparent; border: none; cursor: pointer; padding: 6px 8px; border-radius: 6px; color: var(--mj-text-muted); }\n .ps-copilot-close:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-secondary); }\n .ps-copilot-body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }\n .ps-copilot-body mj-conversation-chat-area { flex: 1; min-height: 0; display: block; }\n .ps-copilot-empty { display: flex; align-items: center; justify-content: center; flex: 1; }\n .ps-load-error { display: flex; align-items: center; gap: 14px; max-width: 620px; margin: 32px auto; padding: 18px 20px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-lg); }\n .ps-load-error > i { font-size: 24px; color: var(--mj-status-error); }\n .ps-load-error-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n .ps-load-error-text strong { color: var(--mj-text-primary); }\n .ps-load-error-detail { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); word-break: break-word; }\n @media (max-width: 1100px) { .ps-studio-host.chat-open .ps-content, .ps-studio-host.chat-open .ps-leftnav { display: none; } .ps-copilot { width: 100%; max-width: none; border-left: none; } }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PSStudioResourceComponent extends PSResourceBase {\n protected readonly SectionKey = 'studio';\n protected readonly SectionLabel = 'Studio';\n protected readonly SectionIcon = 'fa-solid fa-flask-vial';\n\n private readonly cdrLocal = inject(ChangeDetectorRef);\n\n /** The active workbench section (which panel renders). Round-trips through the `section` query param. */\n public activeSection: PSPanelKey = 'home';\n public readonly sections: readonly PSSection[] = STUDIO_SECTIONS;\n\n // ── docked Model Dev Agent copilot ───────────────────────────────\n public chatOpen = false;\n public pendingPrompt: string | null = null;\n private _modelDevAgentId: string | null = null;\n /** Conversation lifecycle (see {@link onChatConversationCreated}) — without it the first send no-ops. */\n public chatConversation: MJConversationEntity | null = null;\n public chatConversationId: string | null = null;\n public chatIsNewConversation = true;\n\n override ngOnInit(): void {\n super.ngOnInit();\n const initial = this.GetQueryParams()['section'] as PSPanelKey | undefined;\n if (initial && hasSection(this.sections, initial)) this.activeSection = initial;\n }\n\n /** React to deep-link / back-forward `section` changes after the initial mount. */\n protected override OnQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): void {\n const next = params['section'] as PSPanelKey | undefined;\n if (next && next !== this.activeSection && hasSection(this.sections, next)) {\n this.activeSection = next;\n this.cdrLocal.detectChanges();\n }\n }\n\n /** Deep agent context for the Studio door (build/run workbench counts + active section). */\n protected override extraAgentContext(): Record<string, unknown> {\n return buildStudioAgentContext({\n ActiveSection: this.activeSection,\n ActiveSectionLabel: this.activeLabel,\n SectionLabels: this.sections.map((s) => s.label),\n PublishedModelCount: this.engine.PublishedModels.length,\n RunningSessionCount: this.engine.RunningSessions.length,\n PipelineCount: this.engine.Pipelines.length,\n AlgorithmCount: this.engine.Algorithms.length,\n ExperimentCount: this.engine.Experiments.length,\n TrainingRunCount: this.engine.TrainingRuns.length,\n ChatOpen: this.chatOpen,\n });\n }\n\n /**\n * 🔒 Read/navigate-only agent tools for the Studio door: switch the active section, or open the docked\n * Model Dev Agent co-pilot. NO build/train/publish tool is exposed — model creation runs through the\n * co-pilot conversation (the approve-gated builder), never a fire-and-forget agent tool.\n */\n protected override registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'SwitchStudioSection',\n Description:\n 'Switch the Studio workbench to a section. Pass the section key or label (see SectionLabels): Overview, Training Pipelines, Algorithm Catalog, Experiments, or Compare Runs.',\n ParameterSchema: { type: 'object', properties: { section: { type: 'string', description: 'The section key or label to switch to' } } },\n Handler: async (params: Record<string, unknown>) => {\n const check = validateStringParam(params['section'], 'section');\n if (!check.ok) return check.result;\n const candidates = this.sections.map((s) => ({ ID: s.key, Name: s.label }));\n const match = resolvePSRecord(check.value, candidates);\n if (!match) return { Success: false, ErrorMessage: buildPSNotFoundError(check.value, candidates, 'section') };\n this.selectSection(match.ID as PSPanelKey);\n return { Success: true, Data: { activeSection: match.Name } };\n },\n },\n {\n Name: 'OpenModelDevAgentCopilot',\n Description:\n 'Open the docked Model Development Agent co-pilot in the Studio (does not send a message — the user drives the conversation). Use when the user wants to design/build a new prediction.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n this.openCopilot();\n return { Success: true, Data: { chatOpen: true } };\n },\n },\n ]);\n }\n\n // ── left-nav ─────────────────────────────────────────────────────\n public get groups(): string[] { return sectionGroups(this.sections); }\n public itemsForGroup(group: string): PSSection[] { return sectionsInGroup(this.sections, group); }\n public get activeLabel(): string { return sectionLabel(this.sections, this.activeSection); }\n\n /** Section-specific subtitle for the interior header (so every section doesn't repeat one generic line). */\n public get activeSubtitle(): string {\n const map: Record<string, string> = {\n home: 'Start a new prediction from your data, a template, or the agent.',\n pipelines: 'Assemble features and train from the algorithm catalog.',\n catalog: 'Browse algorithms with a fit guide for your use case.',\n experiments: 'Run and track model experiments.',\n compare: 'Compare runs on the honest holdout score.',\n };\n return map[this.activeSection] ?? '';\n }\n\n public selectSection(key: PSPanelKey): void {\n if (this.activeSection === key) return;\n this.activeSection = key;\n this.UpdateQueryParams({ section: key });\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n /** The Overview panel's in-app navigation: switch section in-place, or cross to the Models door. */\n public mapNavigate(key: PSPanelKey): void {\n const target = routeHomeNavigate(key);\n if (target.kind === 'section') {\n this.selectSection(target.key);\n } else if (target.kind === 'app') {\n void this.navigationService.SwitchToApp(PREDICTIVE_STUDIO_APP_ID, target.navLabel, { section: target.section });\n }\n }\n\n // ── copilot ──────────────────────────────────────────────────────\n public get currentUser(): UserInfo | null { return this.ProviderToUse.CurrentUser ?? null; }\n\n public get chatEnvironmentId(): string {\n return (this.Data?.Configuration?.['environmentId'] as string | undefined) || MJEnvironmentEntityExtended.DefaultEnvironmentID;\n }\n public get applicationId(): string | null { return (this.Data?.Configuration?.['applicationId'] as string | undefined) ?? null; }\n public get modelDevAgentId(): string | null { return this._modelDevAgentId; }\n public get chatAppContext(): Record<string, unknown> {\n return { app: 'Predictive Studio', section: this.activeSection, publishedModels: this.engine.Models.filter((m) => m.Status === 'Published').length };\n }\n\n public onAskAgent(starterPrompt: string): void {\n this.pendingPrompt = starterPrompt;\n this.chatOpen = true;\n void this.ensureModelDevAgentResolved();\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n /** Open the docked co-pilot (clean chat) — used by the read-only `OpenModelDevAgentCopilot` agent tool. */\n public openCopilot(): void {\n this.pendingPrompt = null;\n this.chatOpen = true;\n void this.ensureModelDevAgentResolved();\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n public closeChat(): void {\n this.chatOpen = false;\n this.pendingPrompt = null;\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n /** Chat-area created its backing conversation on the first send — capture it + leave new-mode so the thread renders. */\n public onChatConversationCreated(event: { conversation: MJConversationEntity; pendingMessage?: string }): void {\n this.pendingPrompt = event.pendingMessage ?? null;\n this.chatConversation = event.conversation;\n this.chatConversationId = event.conversation.ID;\n this.chatIsNewConversation = false;\n this.cdrLocal.detectChanges();\n }\n\n /** Chat-area delivered the seeded prompt — clear the buffer so a re-render doesn't resend it. */\n public onChatPendingMessageConsumed(): void {\n this.pendingPrompt = null;\n this.cdrLocal.detectChanges();\n }\n\n private async ensureModelDevAgentResolved(): Promise<void> {\n if (this._modelDevAgentId) return;\n try {\n await AIEngineBase.Instance.Config(false, this.ProviderToUse.CurrentUser ?? undefined);\n this._modelDevAgentId =\n AIEngineBase.Instance.Agents?.find((a) => a.Name?.trim().toLowerCase() === MODEL_DEV_AGENT_NAME.toLowerCase())?.ID ?? null;\n if (!this._modelDevAgentId) LogError(`PSStudioResource: '${MODEL_DEV_AGENT_NAME}' not found — chat uses default-agent routing.`);\n this.cdrLocal.detectChanges();\n } catch (err) {\n LogError(`PSStudioResource.ensureModelDevAgentResolved: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n}\n\n/** Tree-shaking prevention — called from the subpath module so the @RegisterClass survives bundling. */\nexport function LoadPSStudioResource(): void {\n // intentionally empty\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ps-studio-resource.component.js","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-studio-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ViewChild, inject } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { LogError, UserInfo } from '@memberjunction/core';\nimport { MJConversationEntity, MJEnvironmentEntityExtended, MJMLAlgorithmEntity, UserInfoEngine } from '@memberjunction/core-entities';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { PSResourceBase } from './ps-resource-base';\nimport { PSPanelKey } from '../predictive-studio.types';\nimport { PSPipelinesComponent } from '../components/ps-pipelines.component';\nimport {\n STUDIO_SECTIONS,\n PSSection,\n sectionGroups,\n sectionsInGroup,\n sectionLabel,\n hasSection,\n routeHomeNavigate,\n} from '../predictive-studio.nav';\nimport {\n buildStudioAgentContext,\n resolvePSRecord,\n buildPSNotFoundError,\n} from '../predictive-studio-agent-context';\nimport { validateStringParam } from '../../shared/agent-tool-validation';\nimport type { NavigationRequest } from '@memberjunction/ng-artifacts';\n\n/** Predictive Studio application ID (from `metadata/applications/.predictive-studio-application.json`). */\nconst PREDICTIVE_STUDIO_APP_ID = '299C9272-8D38-40CA-85D4-0980F2C9FAD1';\nconst MODEL_DEV_AGENT_NAME = 'Model Development Agent';\n\n/**\n * **Studio** — the analyst workbench door (one of Predictive Studio's three consolidated nav items,\n * alongside `Predictions` and `Models`). Hosts the build/run section panels (`ps-home`, `ps-pipelines`,\n * `ps-catalog`, `ps-experiments`, `ps-compare`) behind an internal left-nav grouped by lifecycle\n * (Overview · Build · Run), so the outer app nav stays quiet while analysts get all the depth one click\n * in. The active section round-trips through the `section` query param (deep links + back/forward). A\n * single docked **Model Development Agent** copilot is shared by every section's \"Ask the agent\" CTA —\n * wired with the full conversation lifecycle (`isNewConversation` → `conversationCreated`) so the first\n * message actually creates + sends. Cross-door navigation (to a Models section) routes via the nav\n * service; see {@link routeHomeNavigate}.\n */\n@RegisterClass(BaseResourceComponent, 'PredictiveStudioStudioResource')\n@Component({\n standalone: false,\n selector: 'mj-ps-studio-resource',\n template: `\n <mj-page-header-interior [Title]=\"activeLabel\" [Subtitle]=\"activeSubtitle\">\n </mj-page-header-interior>\n <mj-page-body-interior [Flex]=\"true\" [Padding]=\"false\">\n @if (isLoading) {\n <mj-loading text=\"Loading Studio…\" size=\"medium\"></mj-loading>\n } @else if (loadError) {\n <div class=\"ps-load-error\" data-testid=\"ps-load-error\" role=\"alert\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div class=\"ps-load-error-text\">\n <strong>Couldn't load {{ sectionTitle }}</strong>\n <span class=\"ps-load-error-detail\">{{ loadError }}</span>\n </div>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"retryLoad()\"><i class=\"fa-solid fa-rotate-right\"></i> Try again</button>\n </div>\n } @else {\n <div class=\"ps-studio-host\" [class.nav-collapsed]=\"isNavCollapsed\" [class.chat-open]=\"chatOpen\" data-testid=\"ps-studio-shell\">\n @if (isNavCollapsed) {\n <div class=\"ps-nav-collapsed-strip\" role=\"region\" aria-label=\"Studio navigation (collapsed)\">\n <button class=\"ps-nav-rail-collapse\" type=\"button\" (click)=\"toggleNav()\" aria-label=\"Expand studio navigation\" title=\"Expand navigation\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n <div class=\"ps-nav-collapsed-strip-label\"><i class=\"fa-solid fa-flask-vial\"></i> Studio</div>\n </div>\n }\n\n <as-split direction=\"horizontal\" class=\"studio-outer-splitter\" unit=\"percent\" [gutterSize]=\"isNavCollapsed ? 0 : 6\" (dragEnd)=\"onNavSplitDragEnd($event.sizes)\">\n @if (!isNavCollapsed) {\n <as-split-area [size]=\"navSizePct\" [minSize]=\"10\" [maxSize]=\"30\">\n <aside class=\"ps-leftnav\">\n <div class=\"ps-leftnav-header\">\n <span class=\"ps-leftnav-title\">Studio</span>\n <button class=\"ps-leftnav-collapse-btn\" type=\"button\" (click)=\"toggleNav()\" title=\"Collapse navigation\" aria-label=\"Collapse navigation\">\n <i class=\"fa-solid fa-chevron-left\"></i>\n </button>\n </div>\n @for (group of groups; track group) {\n @if (group) { <div class=\"ps-nav-group\">{{ group }}</div> }\n @for (item of itemsForGroup(group); track item.key) {\n <button class=\"ps-nav-item\" [class.active]=\"activeSection === item.key\"\n [attr.data-testid]=\"'ps-nav-' + item.key\" (click)=\"selectSection(item.key)\">\n <i [class]=\"item.icon\"></i> <span>{{ item.label }}</span>\n </button>\n }\n }\n </aside>\n </as-split-area>\n }\n\n <as-split-area [size]=\"isNavCollapsed ? 100 : (100 - navSizePct)\" [minSize]=\"60\">\n <div class=\"ps-studio-workspace\">\n <as-split direction=\"horizontal\" class=\"studio-copilot-splitter\" unit=\"percent\" [gutterSize]=\"chatOpen ? 6 : 0\" (dragEnd)=\"onCopilotSplitDragEnd($event.sizes)\">\n <as-split-area [size]=\"chatOpen ? (copilotExpanded ? 40 : mainSizePct) : 100\" [minSize]=\"30\">\n <section class=\"ps-content\" [class.fill]=\"activeSection === 'pipelines'\" [attr.data-testid]=\"'ps-panel-' + activeSection\">\n @switch (activeSection) {\n @case ('home') { <ps-home [engine]=\"engine\" [provider]=\"ProviderToUse\" [currentUser]=\"ProviderToUse.CurrentUser\" (navigate)=\"mapNavigate($event)\" (askAgent)=\"onAskAgent($event)\"></ps-home> }\n @case ('pipelines') { <ps-pipelines #pipelinesComp [engine]=\"engine\" [provider]=\"ProviderToUse\" [currentUser]=\"ProviderToUse.CurrentUser\" (askAgent)=\"onAskAgent($event)\" (navigate)=\"mapNavigate($event)\"></ps-pipelines> }\n @case ('catalog') { <ps-catalog [engine]=\"engine\" (askAgent)=\"onAskAgent($event)\" (createPipeline)=\"onCreatePipelineFromCatalog($event)\"></ps-catalog> }\n @case ('experiments') { <ps-experiments [engine]=\"engine\" [provider]=\"ProviderToUse\" [currentUser]=\"ProviderToUse.CurrentUser\"></ps-experiments> }\n @case ('compare') { <ps-compare [engine]=\"engine\"></ps-compare> }\n }\n </section>\n </as-split-area>\n\n @if (chatOpen) {\n <as-split-area [size]=\"copilotExpanded ? 60 : copilotSizePct\" [minSize]=\"20\" [maxSize]=\"70\">\n <aside class=\"ps-copilot\" [class.expanded]=\"copilotExpanded\" data-testid=\"ps-studio-copilot\">\n <div class=\"ps-copilot-head\">\n <div class=\"ps-copilot-title\"><i class=\"fa-solid fa-robot\"></i> Model Dev Agent</div>\n <div class=\"ps-copilot-actions\">\n <button class=\"ps-copilot-btn\" (click)=\"toggleCopilotExpanded()\" [title]=\"copilotExpanded ? 'Collapse panel' : 'Expand panel'\"><i class=\"fa-solid\" [class.fa-up-right-and-down-left-from-center]=\"!copilotExpanded\" [class.fa-down-left-and-up-right-to-center]=\"copilotExpanded\"></i></button>\n <button class=\"ps-copilot-close\" (click)=\"closeChat()\" aria-label=\"Close agent chat\"><i class=\"fa-solid fa-xmark\"></i></button>\n </div>\n </div>\n <div class=\"ps-copilot-body\">\n @if (currentUser) {\n <mj-conversation-chat-area\n [Provider]=\"Provider\" [environmentId]=\"chatEnvironmentId\" [currentUser]=\"currentUser\"\n [conversation]=\"chatConversation\" [conversationId]=\"chatConversationId\" [isNewConversation]=\"chatIsNewConversation\"\n [suppressNewConversationEmptyState]=\"true\" [allowMentions]=\"false\" [overlayMode]=\"false\"\n [showExportButton]=\"false\" [showShareButton]=\"false\" [showArtifactIndicator]=\"true\"\n [showAgentPicker]=\"false\" [showAgentModePicker]=\"false\"\n [defaultAgentId]=\"modelDevAgentId\" [pendingMessage]=\"pendingPrompt\"\n [applicationScope]=\"'Application'\" [applicationId]=\"applicationId\" [appContext]=\"chatAppContext\"\n (conversationCreated)=\"onChatConversationCreated($event)\"\n (pendingMessageConsumed)=\"onChatPendingMessageConsumed()\"\n (navigationRequest)=\"onNavigationRequest($event)\">\n </mj-conversation-chat-area>\n } @else { <div class=\"ps-copilot-empty\"><mj-loading text=\"Connecting…\" size=\"small\"></mj-loading></div> }\n </div>\n </aside>\n </as-split-area>\n }\n </as-split>\n </div>\n </as-split-area>\n </as-split>\n </div>\n }\n </mj-page-body-interior>\n `,\n styles: [\n `\n :host { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-studio-host { display: flex; flex: 1; min-height: 0; overflow: hidden; width: 100%; height: 100%; }\n .studio-outer-splitter { flex: 1; width: 100%; height: 100%; min-height: 0; min-width: 0; background: transparent; }\n .studio-outer-splitter .as-split-gutter { background: transparent; transition: background-color 0.15s ease; position: relative; }\n .studio-outer-splitter .as-split-gutter:hover { background-color: var(--mj-brand-primary, #6366f1); }\n .studio-outer-splitter .as-split-gutter::after { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 2px; height: 24px; border-radius: 1px; background: var(--mj-border-strong, #cbd5e1); }\n .studio-outer-splitter .as-split-gutter:hover::after { background: #ffffff; }\n\n .ps-nav-collapsed-strip { width: 44px; min-width: 44px; max-width: 44px; flex: none; background: var(--mj-bg-surface); border-right: 1px solid var(--mj-border-default); display: flex; flex-direction: column; align-items: center; padding: 10px 0; gap: 14px; z-index: 2; }\n .ps-nav-rail-collapse { background: var(--mj-bg-surface-subtle); border: 1px solid var(--mj-border-default); border-radius: 6px; color: var(--mj-text-secondary); cursor: pointer; display: grid; place-items: center; width: 28px; height: 28px; padding: 0; font-size: 11px; transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease; }\n .ps-nav-rail-collapse:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); border-color: var(--mj-border-strong); }\n .ps-nav-collapsed-strip-label { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; color: var(--mj-text-muted); display: flex; align-items: center; gap: 8px; text-transform: uppercase; }\n\n .ps-leftnav { width: 100%; height: 100%; border-right: 1px solid var(--mj-border-default); background: var(--mj-bg-surface-card); overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 2px; box-sizing: border-box; }\n .ps-leftnav-header { display: flex; align-items: center; justify-content: space-between; padding: 4px 6px 8px; border-bottom: 1px solid var(--mj-border-subtle); margin-bottom: 4px; }\n .ps-leftnav-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--mj-text-muted); }\n .ps-leftnav-collapse-btn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 6px; border: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); color: var(--mj-text-muted); cursor: pointer; transition: all 0.15s ease; padding: 0; }\n .ps-leftnav-collapse-btn:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); border-color: var(--mj-border-strong); }\n\n .ps-nav-group { font-size: var(--mj-text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--mj-text-muted); padding: 10px 8px 4px; }\n .ps-nav-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 8px 10px; border: none; background: transparent; border-radius: var(--mj-radius-md); cursor: pointer; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); font-weight: 500; transition: background .12s, color .12s; }\n .ps-nav-item i { width: 18px; text-align: center; color: var(--mj-text-muted); }\n .ps-nav-item:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .ps-nav-item.active { background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); color: var(--mj-brand-primary); font-weight: 600; }\n .ps-nav-item.active i { color: var(--mj-brand-primary); }\n\n .ps-studio-workspace { display: flex; flex: 1; width: 100%; height: 100%; min-height: 0; min-width: 0; overflow: hidden; }\n .studio-copilot-splitter { flex: 1; width: 100%; height: 100%; min-height: 0; min-width: 0; }\n .studio-copilot-splitter .as-split-gutter { background: transparent; transition: background-color 0.15s ease; position: relative; }\n .studio-copilot-splitter .as-split-gutter:hover { background-color: var(--mj-brand-primary, #6366f1); }\n .studio-copilot-splitter .as-split-gutter::after { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 2px; height: 24px; border-radius: 1px; background: var(--mj-border-strong, #cbd5e1); }\n .ps-content { width: 100%; height: 100%; flex: 1; min-width: 0; overflow-y: auto; padding: 8px 14px 24px; }\n /* Fill mode (pipelines): the section stops page-scrolling so the panel's inner\n columns (canvas / inspector) can each own their scrollbar. */\n .ps-content.fill { overflow: hidden; display: flex; flex-direction: column; padding-bottom: 14px; }\n .ps-content.fill > * { flex: 1; min-height: 0; display: flex; flex-direction: column; }\n .ps-copilot { width: 100%; height: 100%; max-width: none; flex: 1; border-left: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); display: flex; flex-direction: column; min-height: 0; }\n .ps-copilot-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--mj-border-default); }\n .ps-copilot-title { display: flex; align-items: center; gap: 8px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-copilot-title i { color: var(--mj-brand-primary); }\n .ps-copilot-actions { display: flex; align-items: center; gap: 4px; }\n .ps-copilot-btn { background: transparent; border: none; cursor: pointer; padding: 6px 8px; border-radius: 6px; color: var(--mj-text-muted); }\n .ps-copilot-btn:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-secondary); }\n .ps-copilot-close { background: transparent; border: none; cursor: pointer; padding: 6px 8px; border-radius: 6px; color: var(--mj-text-muted); }\n .ps-copilot-close:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-secondary); }\n .ps-copilot-body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }\n .ps-copilot-body mj-conversation-chat-area { flex: 1; min-height: 0; display: block; }\n .ps-copilot-empty { display: flex; align-items: center; justify-content: center; flex: 1; }\n .ps-load-error { display: flex; align-items: center; gap: 14px; max-width: 620px; margin: 32px auto; padding: 18px 20px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-lg); }\n .ps-load-error > i { font-size: 24px; color: var(--mj-status-error); }\n .ps-load-error-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n .ps-load-error-text strong { color: var(--mj-text-primary); }\n .ps-load-error-detail { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); word-break: break-word; }\n @media (max-width: 1100px) { .ps-studio-host.chat-open .ps-content, .ps-studio-host.chat-open .ps-leftnav { display: none; } .ps-copilot { width: 100%; max-width: none; border-left: none; } }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PSStudioResourceComponent extends PSResourceBase {\n protected readonly SectionKey = 'studio';\n protected readonly SectionLabel = 'Studio';\n protected readonly SectionIcon = 'fa-solid fa-flask-vial';\n\n private readonly cdrLocal = inject(ChangeDetectorRef);\n\n /** The active workbench section (which panel renders). Round-trips through the `section` query param. */\n public activeSection: PSPanelKey = 'home';\n public readonly sections: readonly PSSection[] = STUDIO_SECTIONS;\n\n @ViewChild('pipelinesComp') pipelinesComponent?: PSPipelinesComponent;\n\n public onCreatePipelineFromCatalog(algo: MJMLAlgorithmEntity): void {\n this.selectSection('pipelines');\n setTimeout(() => {\n this.pipelinesComponent?.openWizard(algo.ID);\n }, 50);\n }\n\n // ── docked Model Dev Agent copilot ───────────────────────────────\n public chatOpen = false;\n public pendingPrompt: string | null = null;\n private _modelDevAgentId: string | null = null;\n /** Conversation lifecycle (see {@link onChatConversationCreated}) — without it the first send no-ops. */\n public chatConversation: MJConversationEntity | null = null;\n public chatConversationId: string | null = null;\n public chatIsNewConversation = true;\n public isNavCollapsed = false;\n public navSizePct = 14;\n public mainSizePct = 68;\n public copilotSizePct = 32;\n\n override ngOnInit(): void {\n super.ngOnInit();\n const initial = this.GetQueryParams()['section'] as PSPanelKey | undefined;\n if (initial && hasSection(this.sections, initial)) this.activeSection = initial;\n this.loadLayoutPrefs();\n }\n\n public toggleNav(): void {\n this.isNavCollapsed = !this.isNavCollapsed;\n this.saveLayoutPrefs();\n this.cdrLocal.detectChanges();\n }\n\n public onNavSplitDragEnd(sizes: readonly (number | '*')[]): void {\n if (Array.isArray(sizes) && sizes.length === 2 && typeof sizes[0] === 'number') {\n this.navSizePct = Math.round(sizes[0]);\n this.saveLayoutPrefs();\n }\n }\n\n public onCopilotSplitDragEnd(sizes: readonly (number | '*')[]): void {\n if (Array.isArray(sizes) && sizes.length === 2 && typeof sizes[0] === 'number' && typeof sizes[1] === 'number') {\n this.mainSizePct = Math.round(sizes[0]);\n this.copilotSizePct = Math.round(sizes[1]);\n this.saveLayoutPrefs();\n }\n }\n\n private loadLayoutPrefs(): void {\n const saved = UserInfoEngine.Instance.GetSetting('mj.predictiveStudio.studio.layout');\n if (saved) {\n try {\n const parsed = JSON.parse(saved);\n if (typeof parsed.navSizePct === 'number' && parsed.navSizePct >= 10 && parsed.navSizePct <= 35) {\n this.navSizePct = parsed.navSizePct;\n }\n if (typeof parsed.isNavCollapsed === 'boolean') {\n this.isNavCollapsed = parsed.isNavCollapsed;\n }\n if (typeof parsed.copilotSizePct === 'number' && parsed.copilotSizePct >= 20 && parsed.copilotSizePct <= 60) {\n this.copilotSizePct = parsed.copilotSizePct;\n this.mainSizePct = 100 - this.copilotSizePct;\n }\n } catch {}\n }\n }\n\n private saveLayoutPrefs(): void {\n const prefs = {\n navSizePct: this.navSizePct,\n isNavCollapsed: this.isNavCollapsed,\n copilotSizePct: this.copilotSizePct,\n mainSizePct: this.mainSizePct,\n };\n UserInfoEngine.Instance.SetSettingDebounced('mj.predictiveStudio.studio.layout', JSON.stringify(prefs));\n }\n\n /** React to deep-link / back-forward `section` changes after the initial mount. */\n protected override OnQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): void {\n const next = params['section'] as PSPanelKey | undefined;\n if (next && next !== this.activeSection && hasSection(this.sections, next)) {\n this.activeSection = next;\n this.cdrLocal.detectChanges();\n }\n }\n\n /** Deep agent context for the Studio door (build/run workbench counts + active section). */\n protected override extraAgentContext(): Record<string, unknown> {\n return buildStudioAgentContext({\n ActiveSection: this.activeSection,\n ActiveSectionLabel: this.activeLabel,\n SectionLabels: this.sections.map((s) => s.label),\n PublishedModelCount: this.engine.PublishedModels.length,\n RunningSessionCount: this.engine.RunningSessions.length,\n PipelineCount: this.engine.Pipelines.length,\n AlgorithmCount: this.engine.Algorithms.length,\n ExperimentCount: this.engine.Experiments.length,\n TrainingRunCount: this.engine.TrainingRuns.length,\n ChatOpen: this.chatOpen,\n });\n }\n\n /**\n * 🔒 Read/navigate-only agent tools for the Studio door: switch the active section, or open the docked\n * Model Dev Agent co-pilot. NO build/train/publish tool is exposed — model creation runs through the\n * co-pilot conversation (the approve-gated builder), never a fire-and-forget agent tool.\n */\n protected override registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'SwitchStudioSection',\n Description:\n 'Switch the Studio workbench to a section. Pass the section key or label (see SectionLabels): Overview, Training Pipelines, Algorithm Catalog, Experiments, or Compare Runs.',\n ParameterSchema: { type: 'object', properties: { section: { type: 'string', description: 'The section key or label to switch to' } } },\n Handler: async (params: Record<string, unknown>) => {\n const check = validateStringParam(params['section'], 'section');\n if (!check.ok) return check.result;\n const candidates = this.sections.map((s) => ({ ID: s.key, Name: s.label }));\n const match = resolvePSRecord(check.value, candidates);\n if (!match) return { Success: false, ErrorMessage: buildPSNotFoundError(check.value, candidates, 'section') };\n this.selectSection(match.ID as PSPanelKey);\n return { Success: true, Data: { activeSection: match.Name } };\n },\n },\n {\n Name: 'OpenModelDevAgentCopilot',\n Description:\n 'Open the docked Model Development Agent co-pilot in the Studio (does not send a message — the user drives the conversation). Use when the user wants to design/build a new prediction.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n this.openCopilot();\n return { Success: true, Data: { chatOpen: true } };\n },\n },\n ]);\n }\n\n // ── left-nav ─────────────────────────────────────────────────────\n public get groups(): string[] { return sectionGroups(this.sections); }\n public itemsForGroup(group: string): PSSection[] { return sectionsInGroup(this.sections, group); }\n public get activeLabel(): string { return sectionLabel(this.sections, this.activeSection); }\n\n /** Section-specific subtitle for the interior header (so every section doesn't repeat one generic line). */\n public get activeSubtitle(): string {\n const map: Record<string, string> = {\n home: 'Start a new prediction from your data, a template, or the agent.',\n pipelines: 'Assemble features and train from the algorithm catalog.',\n catalog: 'Browse algorithms with a fit guide for your use case.',\n experiments: 'Run and track model experiments.',\n compare: 'Compare runs on the honest holdout score.',\n };\n return map[this.activeSection] ?? '';\n }\n\n public selectSection(key: PSPanelKey): void {\n if (this.activeSection === key) return;\n this.activeSection = key;\n this.UpdateQueryParams({ section: key });\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n /** The Overview panel's in-app navigation: switch section in-place, or cross to the Models door. */\n public mapNavigate(key: PSPanelKey): void {\n const target = routeHomeNavigate(key);\n if (target.kind === 'section') {\n this.selectSection(target.key);\n } else if (target.kind === 'app') {\n void this.navigationService.SwitchToApp(PREDICTIVE_STUDIO_APP_ID, target.navLabel, { section: target.section });\n }\n }\n\n // ── copilot ──────────────────────────────────────────────────────\n public get currentUser(): UserInfo | null { return this.ProviderToUse.CurrentUser ?? null; }\n\n public get chatEnvironmentId(): string {\n return (this.Data?.Configuration?.['environmentId'] as string | undefined) || MJEnvironmentEntityExtended.DefaultEnvironmentID;\n }\n public get applicationId(): string | null { return (this.Data?.Configuration?.['applicationId'] as string | undefined) ?? null; }\n public get modelDevAgentId(): string | null { return this._modelDevAgentId; }\n public get chatAppContext(): Record<string, unknown> {\n return { app: 'Predictive Studio', section: this.activeSection, publishedModels: this.engine.Models.filter((m) => m.Status === 'Published').length };\n }\n\n public onAskAgent(starterPrompt: string): void {\n this.pendingPrompt = starterPrompt;\n this.chatOpen = true;\n void this.ensureModelDevAgentResolved();\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n /** Open the docked co-pilot (clean chat) — used by the read-only `OpenModelDevAgentCopilot` agent tool. */\n public openCopilot(): void {\n this.pendingPrompt = null;\n this.chatOpen = true;\n void this.ensureModelDevAgentResolved();\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n public closeChat(): void {\n this.chatOpen = false;\n this.pendingPrompt = null;\n this.copilotExpanded = false;\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n public copilotExpanded = false;\n\n public toggleCopilotExpanded(): void {\n this.copilotExpanded = !this.copilotExpanded;\n this.cdrLocal.detectChanges();\n }\n\n public onNavigationRequest(req: NavigationRequest): void {\n if (req.navItemName === 'Models' || req.queryParams?.['modelId']) {\n void this.navigationService.SwitchToApp(PREDICTIVE_STUDIO_APP_ID, 'Models', req.queryParams);\n } else if (req.appName) {\n void this.navigationService.SwitchToApp(req.appName, req.navItemName, req.queryParams);\n }\n }\n\n /** Chat-area created its backing conversation on the first send — capture it + leave new-mode so the thread renders. */\n public onChatConversationCreated(event: { conversation: MJConversationEntity; pendingMessage?: string }): void {\n this.pendingPrompt = event.pendingMessage ?? null;\n this.chatConversation = event.conversation;\n this.chatConversationId = event.conversation.ID;\n this.chatIsNewConversation = false;\n this.cdrLocal.detectChanges();\n }\n\n /** Chat-area delivered the seeded prompt — clear the buffer so a re-render doesn't resend it. */\n public onChatPendingMessageConsumed(): void {\n this.pendingPrompt = null;\n this.cdrLocal.detectChanges();\n }\n\n private async ensureModelDevAgentResolved(): Promise<void> {\n if (this._modelDevAgentId) return;\n try {\n await AIEngineBase.Instance.Config(false, this.ProviderToUse.CurrentUser ?? undefined);\n this._modelDevAgentId =\n AIEngineBase.Instance.Agents?.find((a) => a.Name?.trim().toLowerCase() === MODEL_DEV_AGENT_NAME.toLowerCase())?.ID ?? null;\n if (!this._modelDevAgentId) LogError(`PSStudioResource: '${MODEL_DEV_AGENT_NAME}' not found — chat uses default-agent routing.`);\n this.cdrLocal.detectChanges();\n } catch (err) {\n LogError(`PSStudioResource.ensureModelDevAgentResolved: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n}\n\n/** Tree-shaking prevention — called from the subpath module so the @RegisterClass survives bundling. */\nexport function LoadPSStudioResource(): void {\n // intentionally empty\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-resource.component.d.ts","sourceRoot":"","sources":["../../../src/VersionHistory/components/graph-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAA2B,MAAM,eAAe,CAAC;AACxH,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAY,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAkB,MAAM,+BAA+B,CAAC;;AAW7E,UAAU,UAAU;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,gBAAgB;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,qBAQa,oCAAqC,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS,EAAE,aAAa;IA0B3G,OAAO,CAAC,GAAG;IAzBhB,SAAS,UAAQ;IAGjB,WAAW,EAAE,UAAU,EAAE,CAAM;IAC/B,gBAAgB,EAAE,UAAU,EAAE,CAAM;IACpC,UAAU,SAAM;IAChB,YAAY,SAAM;IAClB,gBAAgB,EAAE,MAAM,EAAE,CAAM;IAGhC,cAAc,EAAE,UAAU,GAAG,IAAI,CAAQ;IACzC,kBAAkB,EAAE,UAAU,GAAG,IAAI,CAAQ;IAC7C,oBAAoB,EAAE,gBAAgB,EAAE,CAAM;IAC9C,iBAAiB,EAAE,gBAAgB,EAAE,CAAM;IAG3C,aAAa,SAAK;IAClB,sBAAsB,SAAK;IAC3B,kBAAkB,SAAK;IAE9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAA0C;IAC3E,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAsB;IACtC,UAAmB,QAAQ,gBAAuB;gBAE9B,GAAG,EAAE,iBAAiB;IAI1C,QAAQ,IAAI,IAAI;IAMhB,WAAW,IAAI,IAAI;IAMnB;;;;OAIG;IACH,eAAe,IAAI,IAAI;IAevB;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;;;;OAKG;IACH,OAAO,CAAC,0BAA0B;IAgBlC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,wBAAwB;IAuBhC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAaxB,iFAAiF;IACjF,OAAO,CAAC,kBAAkB;IAiB1B,0CAA0C;IAC1C,OAAO,CAAC,kBAAkB;IASpB,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAIxD,QAAQ,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"graph-resource.component.d.ts","sourceRoot":"","sources":["../../../src/VersionHistory/components/graph-resource.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -72,7 +72,7 @@ function VersionHistoryGraphResourceComponent_Conditional_13_For_4_Template(rf,
|
|
|
72
72
|
const entity_r5 = ctx.$implicit;
|
|
73
73
|
i0.ɵɵclassProp("selected", entity_r5.IsSelected);
|
|
74
74
|
i0.ɵɵadvance(2);
|
|
75
|
-
i0.ɵɵtextInterpolate(entity_r5.
|
|
75
|
+
i0.ɵɵtextInterpolate(entity_r5.DisplayName);
|
|
76
76
|
i0.ɵɵadvance(2);
|
|
77
77
|
i0.ɵɵconditional(entity_r5.ReferencedByCount > 0 ? 4 : -1);
|
|
78
78
|
i0.ɵɵadvance();
|
|
@@ -414,12 +414,13 @@ let VersionHistoryGraphResourceComponent = class VersionHistoryGraphResourceComp
|
|
|
414
414
|
const entities = this.metadata.Entities;
|
|
415
415
|
this.AllEntities = entities.map(e => ({
|
|
416
416
|
Name: e.Name,
|
|
417
|
+
DisplayName: e.DisplayNameOrName,
|
|
417
418
|
ID: e.ID,
|
|
418
419
|
SchemaName: e.SchemaName,
|
|
419
420
|
ReferencedByCount: this.countReferencedBy(e),
|
|
420
421
|
DependsOnCount: this.countDependsOn(e),
|
|
421
422
|
IsSelected: false
|
|
422
|
-
})).sort((a, b) => a.
|
|
423
|
+
})).sort((a, b) => a.DisplayName.localeCompare(b.DisplayName));
|
|
423
424
|
// Extract unique schemas, sorted
|
|
424
425
|
const schemaSet = new Set(this.AllEntities.map(e => e.SchemaName));
|
|
425
426
|
this.AvailableSchemas = Array.from(schemaSet).sort();
|
|
@@ -489,7 +490,7 @@ let VersionHistoryGraphResourceComponent = class VersionHistoryGraphResourceComp
|
|
|
489
490
|
}
|
|
490
491
|
if (this.SearchText) {
|
|
491
492
|
const search = this.SearchText.toLowerCase();
|
|
492
|
-
result = result.filter(e => e.Name.toLowerCase().includes(search));
|
|
493
|
+
result = result.filter(e => e.DisplayName.toLowerCase().includes(search) || e.Name.toLowerCase().includes(search));
|
|
493
494
|
}
|
|
494
495
|
this.FilteredEntities = result;
|
|
495
496
|
this.publishAgentContext();
|
|
@@ -615,7 +616,7 @@ VersionHistoryGraphResourceComponent = VersionHistoryGraphResourceComponent_1 =
|
|
|
615
616
|
export { VersionHistoryGraphResourceComponent };
|
|
616
617
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(VersionHistoryGraphResourceComponent, [{
|
|
617
618
|
type: Component,
|
|
618
|
-
args: [{ standalone: false, selector: 'mj-version-history-graph-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<mj-page-layout>\n <mj-page-header\n Title=\"Entity Dependency Graph\"\n Icon=\"fa-solid fa-diagram-project\"\n Subtitle=\"Explore entity relationships used by the version history system\">\n <div meta>\n <mj-stat-badge Icon=\"fa-solid fa-table\" [Count]=\"TotalEntities\" Label=\"entities\"></mj-stat-badge>\n <mj-stat-badge Icon=\"fa-solid fa-diagram-project\" [Count]=\"EntitiesWithDependents\" Label=\"with dependents\"></mj-stat-badge>\n <mj-stat-badge Icon=\"fa-solid fa-arrow-right-arrow-left\" [Count]=\"TotalRelationships\" Label=\"relationships\"></mj-stat-badge>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"Refresh()\"></mj-refresh-button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Filter entities...\"\n [Value]=\"SearchText\"\n (ValueChange)=\"OnSearchChange($event)\">\n </mj-page-search>\n @if (AvailableSchemas.length > 1) {\n @for (schema of AvailableSchemas; track schema) {\n <mj-filter-chip\n [Label]=\"schema\"\n [Count]=\"GetSchemaEntityCount(schema)\"\n [Active]=\"SchemaFilter === schema\"\n (Clicked)=\"OnSchemaFilterChange(schema)\">\n </mj-filter-chip>\n }\n }\n </div>\n </mj-page-header>\n\n <mj-page-body [Flex]=\"true\">\n @if (IsLoading) {\n <mj-loading text=\"Loading dependency graph...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Main Layout: Entity List + Detail -->\n <div class=\"graph-layout\">\n <!-- Entity List \u2014 page-header [toolbar] owns search + schema chips -->\n <div class=\"entity-list-panel\">\n <div class=\"entity-scroll-list\">\n @for (entity of FilteredEntities; track entity) {\n <div class=\"entity-list-item\"\n [class.selected]=\"entity.IsSelected\"\n (click)=\"SelectEntity(entity)\">\n <div class=\"entity-list-name\">{{entity.Name}}</div>\n <div class=\"entity-list-badges\">\n @if (entity.ReferencedByCount > 0) {\n <span class=\"dep-badge\"\n [ngClass]=\"GetDependencyLevel(entity.ReferencedByCount)\"\n title=\"Referenced by (entities with FKs to this)\">\n {{entity.ReferencedByCount}} <i class=\"fa-solid fa-arrow-down\"></i>\n </span>\n }\n @if (entity.DependsOnCount > 0) {\n <span class=\"dep-badge level-depends-on\"\n title=\"Depends on (entities this has FKs to)\">\n {{entity.DependsOnCount}} <i class=\"fa-solid fa-arrow-up\"></i>\n </span>\n }\n </div>\n </div>\n }\n @if (FilteredEntities.length === 0) {\n <mj-empty-state Variant=\"no-results\" Size=\"compact\"\n Title=\"No entities match your search.\" />\n }\n </div>\n </div>\n <!-- Detail Panel -->\n <div class=\"entity-detail-panel\">\n @if (SelectedEntity) {\n <div class=\"detail-header\">\n <i class=\"fa-solid fa-table detail-icon\"></i>\n <div class=\"detail-header-text\">\n <h3 class=\"detail-title\">{{SelectedEntity.Name}}</h3>\n <span class=\"detail-schema\">{{SelectedEntity.SchemaName}}</span>\n </div>\n </div>\n <!-- Referenced By (entities that have FKs pointing to this entity) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-down section-icon referenced-by-icon\"></i>\n <h4>Referenced By</h4>\n <span class=\"section-count\">{{ReferencedByEntities.length}}</span>\n </div>\n <p class=\"section-hint\">Entities that have foreign keys pointing to <strong>{{SelectedEntity.Name}}</strong></p>\n @if (ReferencedByEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of ReferencedByEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.ToEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.ToEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (ReferencedByEntities.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-link-slash\"\n Title=\"No entities reference this entity.\" />\n }\n </div>\n <!-- Depends On (entities this entity has FKs to) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-up section-icon depends-on-icon\"></i>\n <h4>Depends On</h4>\n <span class=\"section-count\">{{DependsOnEntities.length}}</span>\n </div>\n <p class=\"section-hint\"><strong>{{SelectedEntity.Name}}</strong> has foreign keys pointing to these entities</p>\n @if (DependsOnEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of DependsOnEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.FromEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.FromEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (DependsOnEntities.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-link-slash\"\n Title=\"This entity has no foreign key dependencies.\" />\n }\n </div>\n } @else {\n <mj-empty-state class=\"graph-detail-empty\" Icon=\"fa-solid fa-diagram-project\"\n Title=\"Select an Entity\"\n Message=\"Choose an entity from the list to explore its dependency relationships.\" />\n }\n </div>\n </div>\n }\n </mj-page-body>\n</mj-page-layout>\n", styles: ["/* Main Layout */\n.graph-layout {\n display: grid;\n grid-template-columns: 340px 1fr;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n/* Entity List Panel */\n.entity-list-panel {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n}\n\n.entity-scroll-list {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n\n.entity-list-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.entity-list-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.entity-list-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.entity-list-name {\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n}\n\n.entity-list-badges {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.dep-badge {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.dep-badge i { font-size: 9px; }\n\n.level-none { display: none; }\n\n.level-low {\n background: color-mix(in srgb, var(--mj-status-success) 10%, transparent);\n color: var(--mj-status-success);\n}\n\n.level-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, transparent);\n color: var(--mj-status-warning);\n}\n\n.level-high {\n background: color-mix(in srgb, var(--mj-status-error) 10%, transparent);\n color: var(--mj-status-error);\n}\n\n.level-depends-on {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n\n/* Detail Panel */\n.entity-detail-panel {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 24px;\n overflow-y: auto;\n max-height: calc(100vh - 280px);\n}\n\n.detail-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 28px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.detail-header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-icon {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.detail-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.detail-schema {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n/* Relationship Sections */\n.relationship-section {\n margin-bottom: 28px;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.section-header h4 {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n flex: 1;\n}\n\n.section-hint {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin: 0 0 12px 0;\n}\n\n.section-hint strong {\n color: var(--mj-text-secondary);\n}\n\n.section-icon {\n font-size: 14px;\n}\n\n.referenced-by-icon { color: var(--mj-status-success); }\n.depends-on-icon { color: var(--mj-brand-primary); }\n\n.section-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.relationship-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.relationship-item {\n border-radius: 8px;\n transition: background 0.15s ease;\n}\n\n.relationship-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.rel-main {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n}\n\n.rel-icon {\n font-size: 12px;\n color: var(--mj-brand-primary);\n opacity: 0.7;\n flex-shrink: 0;\n}\n\n.rel-entity-name {\n font-size: 14px;\n color: var(--mj-brand-primary);\n font-weight: 500;\n}\n\n.rel-entity-name:hover {\n text-decoration: underline;\n}\n\n.rel-join-field {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n font-family: 'SF Mono', 'Fira Code', monospace;\n margin-left: 4px;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.rel-join-field i {\n font-size: 9px;\n opacity: 0.5;\n}\n\n\n/* No-selection placeholder fills the detail pane so it centers (the small\n relationship/list empties stay compact \u2014 natural height). */\n.graph-detail-empty {\n height: 100%;\n}\n"] }]
|
|
619
|
+
args: [{ standalone: false, selector: 'mj-version-history-graph-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<mj-page-layout>\n <mj-page-header\n Title=\"Entity Dependency Graph\"\n Icon=\"fa-solid fa-diagram-project\"\n Subtitle=\"Explore entity relationships used by the version history system\">\n <div meta>\n <mj-stat-badge Icon=\"fa-solid fa-table\" [Count]=\"TotalEntities\" Label=\"entities\"></mj-stat-badge>\n <mj-stat-badge Icon=\"fa-solid fa-diagram-project\" [Count]=\"EntitiesWithDependents\" Label=\"with dependents\"></mj-stat-badge>\n <mj-stat-badge Icon=\"fa-solid fa-arrow-right-arrow-left\" [Count]=\"TotalRelationships\" Label=\"relationships\"></mj-stat-badge>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"Refresh()\"></mj-refresh-button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Filter entities...\"\n [Value]=\"SearchText\"\n (ValueChange)=\"OnSearchChange($event)\">\n </mj-page-search>\n @if (AvailableSchemas.length > 1) {\n @for (schema of AvailableSchemas; track schema) {\n <mj-filter-chip\n [Label]=\"schema\"\n [Count]=\"GetSchemaEntityCount(schema)\"\n [Active]=\"SchemaFilter === schema\"\n (Clicked)=\"OnSchemaFilterChange(schema)\">\n </mj-filter-chip>\n }\n }\n </div>\n </mj-page-header>\n\n <mj-page-body [Flex]=\"true\">\n @if (IsLoading) {\n <mj-loading text=\"Loading dependency graph...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Main Layout: Entity List + Detail -->\n <div class=\"graph-layout\">\n <!-- Entity List \u2014 page-header [toolbar] owns search + schema chips -->\n <div class=\"entity-list-panel\">\n <div class=\"entity-scroll-list\">\n @for (entity of FilteredEntities; track entity) {\n <div class=\"entity-list-item\"\n [class.selected]=\"entity.IsSelected\"\n (click)=\"SelectEntity(entity)\">\n <div class=\"entity-list-name\">{{entity.DisplayName}}</div>\n <div class=\"entity-list-badges\">\n @if (entity.ReferencedByCount > 0) {\n <span class=\"dep-badge\"\n [ngClass]=\"GetDependencyLevel(entity.ReferencedByCount)\"\n title=\"Referenced by (entities with FKs to this)\">\n {{entity.ReferencedByCount}} <i class=\"fa-solid fa-arrow-down\"></i>\n </span>\n }\n @if (entity.DependsOnCount > 0) {\n <span class=\"dep-badge level-depends-on\"\n title=\"Depends on (entities this has FKs to)\">\n {{entity.DependsOnCount}} <i class=\"fa-solid fa-arrow-up\"></i>\n </span>\n }\n </div>\n </div>\n }\n @if (FilteredEntities.length === 0) {\n <mj-empty-state Variant=\"no-results\" Size=\"compact\"\n Title=\"No entities match your search.\" />\n }\n </div>\n </div>\n <!-- Detail Panel -->\n <div class=\"entity-detail-panel\">\n @if (SelectedEntity) {\n <div class=\"detail-header\">\n <i class=\"fa-solid fa-table detail-icon\"></i>\n <div class=\"detail-header-text\">\n <h3 class=\"detail-title\">{{SelectedEntity.Name}}</h3>\n <span class=\"detail-schema\">{{SelectedEntity.SchemaName}}</span>\n </div>\n </div>\n <!-- Referenced By (entities that have FKs pointing to this entity) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-down section-icon referenced-by-icon\"></i>\n <h4>Referenced By</h4>\n <span class=\"section-count\">{{ReferencedByEntities.length}}</span>\n </div>\n <p class=\"section-hint\">Entities that have foreign keys pointing to <strong>{{SelectedEntity.Name}}</strong></p>\n @if (ReferencedByEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of ReferencedByEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.ToEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.ToEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (ReferencedByEntities.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-link-slash\"\n Title=\"No entities reference this entity.\" />\n }\n </div>\n <!-- Depends On (entities this entity has FKs to) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-up section-icon depends-on-icon\"></i>\n <h4>Depends On</h4>\n <span class=\"section-count\">{{DependsOnEntities.length}}</span>\n </div>\n <p class=\"section-hint\"><strong>{{SelectedEntity.Name}}</strong> has foreign keys pointing to these entities</p>\n @if (DependsOnEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of DependsOnEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.FromEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.FromEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (DependsOnEntities.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-link-slash\"\n Title=\"This entity has no foreign key dependencies.\" />\n }\n </div>\n } @else {\n <mj-empty-state class=\"graph-detail-empty\" Icon=\"fa-solid fa-diagram-project\"\n Title=\"Select an Entity\"\n Message=\"Choose an entity from the list to explore its dependency relationships.\" />\n }\n </div>\n </div>\n }\n </mj-page-body>\n</mj-page-layout>\n", styles: ["/* Main Layout */\n.graph-layout {\n display: grid;\n grid-template-columns: 340px 1fr;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n/* Entity List Panel */\n.entity-list-panel {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n}\n\n.entity-scroll-list {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n}\n\n.entity-list-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.entity-list-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.entity-list-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.entity-list-name {\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n}\n\n.entity-list-badges {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.dep-badge {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.dep-badge i { font-size: 9px; }\n\n.level-none { display: none; }\n\n.level-low {\n background: color-mix(in srgb, var(--mj-status-success) 10%, transparent);\n color: var(--mj-status-success);\n}\n\n.level-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, transparent);\n color: var(--mj-status-warning);\n}\n\n.level-high {\n background: color-mix(in srgb, var(--mj-status-error) 10%, transparent);\n color: var(--mj-status-error);\n}\n\n.level-depends-on {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n\n/* Detail Panel */\n.entity-detail-panel {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 24px;\n overflow-y: auto;\n max-height: calc(100vh - 280px);\n}\n\n.detail-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 28px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.detail-header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-icon {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.detail-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.detail-schema {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n/* Relationship Sections */\n.relationship-section {\n margin-bottom: 28px;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.section-header h4 {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n flex: 1;\n}\n\n.section-hint {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin: 0 0 12px 0;\n}\n\n.section-hint strong {\n color: var(--mj-text-secondary);\n}\n\n.section-icon {\n font-size: 14px;\n}\n\n.referenced-by-icon { color: var(--mj-status-success); }\n.depends-on-icon { color: var(--mj-brand-primary); }\n\n.section-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.relationship-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.relationship-item {\n border-radius: 8px;\n transition: background 0.15s ease;\n}\n\n.relationship-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.rel-main {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n}\n\n.rel-icon {\n font-size: 12px;\n color: var(--mj-brand-primary);\n opacity: 0.7;\n flex-shrink: 0;\n}\n\n.rel-entity-name {\n font-size: 14px;\n color: var(--mj-brand-primary);\n font-weight: 500;\n}\n\n.rel-entity-name:hover {\n text-decoration: underline;\n}\n\n.rel-join-field {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n font-family: 'SF Mono', 'Fira Code', monospace;\n margin-left: 4px;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.rel-join-field i {\n font-size: 9px;\n opacity: 0.5;\n}\n\n\n/* No-selection placeholder fills the detail pane so it centers (the small\n relationship/list empties stay compact \u2014 natural height). */\n.graph-detail-empty {\n height: 100%;\n}\n"] }]
|
|
619
620
|
}], () => [{ type: i0.ChangeDetectorRef }], null); })();
|
|
620
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryGraphResourceComponent, { className: "VersionHistoryGraphResourceComponent", filePath: "src/VersionHistory/components/graph-resource.component.ts", lineNumber:
|
|
621
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryGraphResourceComponent, { className: "VersionHistoryGraphResourceComponent", filePath: "src/VersionHistory/components/graph-resource.component.ts", lineNumber: 42 }); })();
|
|
621
622
|
//# sourceMappingURL=graph-resource.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-resource.component.js","sourceRoot":"","sources":["../../../src/VersionHistory/components/graph-resource.component.ts","../../../src/VersionHistory/components/graph-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, AfterViewInit, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { Metadata, EntityInfo } from '@memberjunction/core';\nimport { ResourceData, UserInfoEngine } from '@memberjunction/core-entities';\nimport { AgentToolResult, validateStringParam } from '../../shared/agent-tool-validation';\nimport {\n buildVersionHistoryGraphAgentContext,\n resolveGraphEntity,\n VersionHistoryGraphSelectedEntitySummary,\n} from '../version-history-graph-agent-context';\n\ninterface VersionGraphPreferences {\n SchemaFilter: string;\n}\ninterface EntityNode {\n Name: string;\n ID: string;\n SchemaName: string;\n ReferencedByCount: number;\n DependsOnCount: number;\n IsSelected: boolean;\n}\n\ninterface RelationshipEdge {\n FromEntity: string;\n ToEntity: string;\n RelatedEntityJoinField: string;\n Type: string;\n}\n\n@RegisterClass(BaseResourceComponent, 'VersionHistoryGraphResource')\n@Component({\n standalone: false,\n selector: 'mj-version-history-graph-resource',\n templateUrl: './graph-resource.component.html',\n styleUrls: ['./graph-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class VersionHistoryGraphResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy, AfterViewInit {\n public IsLoading = true;\n\n // Entity browser\n public AllEntities: EntityNode[] = [];\n public FilteredEntities: EntityNode[] = [];\n public SearchText = '';\n public SchemaFilter = '';\n public AvailableSchemas: string[] = [];\n\n // Selected entity detail\n public SelectedEntity: EntityNode | null = null;\n public SelectedEntityInfo: EntityInfo | null = null;\n public ReferencedByEntities: RelationshipEdge[] = [];\n public DependsOnEntities: RelationshipEdge[] = [];\n\n // Stats\n public TotalEntities = 0;\n public EntitiesWithDependents = 0;\n public TotalRelationships = 0;\n\n private static readonly PREFS_KEY = 'VersionHistory.Graph.UserPreferences';\n private preferencesLoaded = false;\n private metadata = this.ProviderToUse;\n protected override destroy$ = new Subject<void>();\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n ngOnInit(): void {\n super.ngOnInit();\n this.loadUserPreferences();\n this.LoadData();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * After the view initializes, publish the initial agent context and register\n * the client tools the AI agent can invoke against this surface. The ongoing\n * context re-emit happens in {@link applyFilter} and {@link SelectEntity}.\n */\n ngAfterViewInit(): void {\n this.publishAgentContext();\n this.registerAgentClientTools();\n }\n\n // ========================================\n // AI AGENT CONTEXT & CLIENT TOOLS\n //\n // 🔒 SAFETY BOUNDARY: This surface is a read-only browse/filter/inspect view\n // over entity-relationship metadata. It exposes ONLY select / filter / search\n // tools to the agent — NO mutation of any kind (no schema edits, no entity\n // changes, no restore/rollback, no deletion). Every tool below only changes\n // what the user is LOOKING at; none changes data.\n // ========================================\n\n /**\n * Publish the current Dependency-Graph state to the AI agent via\n * NavigationService. Shaping lives in the pure\n * {@link buildVersionHistoryGraphAgentContext} helper so it stays\n * unit-testable. Called on load, on filter changes, and on entity selection.\n */\n private publishAgentContext(): void {\n const context = buildVersionHistoryGraphAgentContext({\n SelectedEntityName: this.SelectedEntity?.Name ?? null,\n SelectedEntityId: this.SelectedEntity?.ID ?? null,\n SelectedEntitySummary: this.buildSelectedEntitySummary(),\n TotalEntities: this.TotalEntities,\n EntitiesWithDependents: this.EntitiesWithDependents,\n TotalRelationships: this.TotalRelationships,\n SearchText: this.SearchText,\n SchemaFilter: this.SchemaFilter,\n VisibleEntityCount: this.FilteredEntities.length,\n VisibleEntityNames: this.FilteredEntities.map(e => e.Name),\n AvailableSchemas: this.AvailableSchemas,\n });\n this.navigationService.SetAgentContext(this, context);\n }\n\n /**\n * Build the selected entity's dependency summary for the agent context, or\n * null when no entity is selected. Reads the already-derived ReferencedBy /\n * DependsOn relationship lists so the co-agent can describe the entity's place\n * in the graph and suggest neighbours as next selections.\n */\n private buildSelectedEntitySummary(): VersionHistoryGraphSelectedEntitySummary | null {\n const node = this.SelectedEntity;\n if (!node) {\n return null;\n }\n return {\n ID: node.ID,\n Name: node.Name,\n SchemaName: node.SchemaName,\n ReferencedByCount: this.ReferencedByEntities.length,\n DependsOnCount: this.DependsOnEntities.length,\n ReferencedByEntityNames: this.ReferencedByEntities.map(r => r.ToEntity),\n DependsOnEntityNames: this.DependsOnEntities.map(r => r.FromEntity),\n };\n }\n\n /**\n * Register the read-only client tools the AI agent can invoke against the\n * Dependency Graph. Each handler is tolerant — it never throws and returns a\n * typed `{ Success, Data?, ErrorMessage? }` result.\n *\n * Tools:\n * - SelectEntityForDependencyView: select an entity by name to inspect its\n * dependencies (delegates to {@link NavigateToEntity}, which clears any\n * schema filter so the entity is reachable).\n * - FilterEntitiesBySchema: filter the entity list to a single schema.\n * - SearchEntities: filter the entity list by an entity-name substring.\n */\n private registerAgentClientTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'SelectEntityForDependencyView',\n Description: 'Select an entity by its ID or name to inspect what references it and what it depends on. Resolution: exact ID, then exact name, then a name-contains match. Clears any active schema filter so the entity is reachable. View-only.',\n ParameterSchema: { type: 'object', properties: { entityName: { type: 'string', description: 'Entity ID or name.' } }, required: ['entityName'] },\n Handler: async (params: Record<string, unknown>) => this.toolSelectEntity(params),\n },\n {\n Name: 'FilterEntitiesBySchema',\n Description: 'Filter the entity list to a single schema. Pass an empty string to clear the schema filter.',\n ParameterSchema: { type: 'object', properties: { schema: { type: 'string' } }, required: ['schema'] },\n Handler: async (params: Record<string, unknown>) => this.toolFilterBySchema(params),\n },\n {\n Name: 'SearchEntities',\n Description: 'Filter the entity list by an entity-name substring. Pass an empty string to clear the search.',\n ParameterSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] },\n Handler: async (params: Record<string, unknown>) => this.toolSearchEntities(params),\n },\n ]);\n }\n\n /**\n * Resolve an entity by ID or name (exact ID → exact name → name-contains) and\n * select it for the dependency view. View-only.\n */\n private toolSelectEntity(params: Record<string, unknown>): AgentToolResult & { Data?: Record<string, unknown> } {\n const parsed = validateStringParam(params['entityName'], 'entityName');\n if (!parsed.ok) {\n return parsed.result;\n }\n const resolution = resolveGraphEntity(parsed.value, this.AllEntities);\n if (!resolution.ok) {\n return { Success: false, ErrorMessage: resolution.error };\n }\n this.NavigateToEntity(resolution.entity.Name);\n return { Success: true, Data: { SelectedEntityId: resolution.entity.ID, SelectedEntityName: resolution.entity.Name } };\n }\n\n /** Apply a schema filter deterministically (no toggle), validating it exists. */\n private toolFilterBySchema(params: Record<string, unknown>): AgentToolResult & { Data?: Record<string, unknown> } {\n const parsed = validateStringParam(params['schema'], 'schema');\n if (!parsed.ok) {\n return parsed.result;\n }\n const value = parsed.value.trim();\n if (value && !this.AvailableSchemas.includes(value)) {\n return { Success: false, ErrorMessage: `Schema \"${value}\" is not available. Available schemas: ${this.AvailableSchemas.join(', ')}.` };\n }\n // Set deterministically rather than via OnSchemaFilterChange's toggle semantics,\n // so the agent always lands on the requested filter regardless of current state.\n this.SchemaFilter = value;\n this.applyFilter();\n this.persistPreferences();\n return { Success: true, Data: { SchemaFilter: this.SchemaFilter, VisibleEntityCount: this.FilteredEntities.length } };\n }\n\n /** Apply an entity-name search filter. */\n private toolSearchEntities(params: Record<string, unknown>): AgentToolResult & { Data?: Record<string, unknown> } {\n const parsed = validateStringParam(params['text'], 'text');\n if (!parsed.ok) {\n return parsed.result;\n }\n this.OnSearchChange(parsed.value);\n return { Success: true, Data: { SearchText: this.SearchText, VisibleEntityCount: this.FilteredEntities.length } };\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Dependency Graph';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-diagram-project';\n }\n\n public LoadData(): void {\n try {\n this.IsLoading = true;\n this.cdr.markForCheck();\n\n const entities = this.metadata.Entities;\n\n this.AllEntities = entities.map(e => ({\n Name: e.Name,\n ID: e.ID,\n SchemaName: e.SchemaName,\n ReferencedByCount: this.countReferencedBy(e),\n DependsOnCount: this.countDependsOn(e),\n IsSelected: false\n })).sort((a, b) => a.Name.localeCompare(b.Name));\n\n // Extract unique schemas, sorted\n const schemaSet = new Set(this.AllEntities.map(e => e.SchemaName));\n this.AvailableSchemas = Array.from(schemaSet).sort();\n\n this.TotalEntities = this.AllEntities.length;\n this.EntitiesWithDependents = this.AllEntities.filter(e => e.ReferencedByCount > 0).length;\n this.TotalRelationships = this.AllEntities.reduce((sum, e) => sum + e.ReferencedByCount, 0);\n\n this.applyFilter();\n } catch (error) {\n console.error('Error loading dependency graph data:', error);\n } finally {\n this.IsLoading = false;\n this.NotifyLoadComplete();\n this.publishAgentContext();\n this.cdr.markForCheck();\n }\n }\n\n /** Count entities that reference this entity (have FKs pointing to it), excluding self-references */\n private countReferencedBy(entity: EntityInfo): number {\n return entity.RelatedEntities.filter(r =>\n r.Type.trim().toUpperCase() === 'ONE TO MANY' &&\n r.RelatedEntity !== entity.Name\n ).length;\n }\n\n /** Count entities this entity depends on (has FKs pointing to), excluding self-references */\n private countDependsOn(entity: EntityInfo): number {\n return this.metadata.Entities.filter(e =>\n e.Name !== entity.Name &&\n e.RelatedEntities.some(r =>\n r.Type.trim().toUpperCase() === 'ONE TO MANY' &&\n r.RelatedEntity === entity.Name\n )\n ).length;\n }\n\n public OnSearchChange(text: string): void {\n this.SearchText = text;\n this.applyFilter();\n }\n\n public OnSchemaFilterChange(schema: string): void {\n this.SchemaFilter = this.SchemaFilter === schema ? '' : schema;\n this.applyFilter();\n this.persistPreferences();\n }\n\n private loadUserPreferences(): void {\n try {\n const raw = UserInfoEngine.Instance.GetSetting(VersionHistoryGraphResourceComponent.PREFS_KEY);\n if (raw) {\n const prefs: VersionGraphPreferences = JSON.parse(raw);\n if (prefs.SchemaFilter != null) {\n this.SchemaFilter = prefs.SchemaFilter;\n }\n }\n } catch (error) {\n console.error('Error loading graph preferences:', error);\n this.SchemaFilter = '';\n }\n this.preferencesLoaded = true;\n }\n\n private persistPreferences(): void {\n if (!this.preferencesLoaded) return;\n const prefs: VersionGraphPreferences = {\n SchemaFilter: this.SchemaFilter\n };\n UserInfoEngine.Instance.SetSettingDebounced(VersionHistoryGraphResourceComponent.PREFS_KEY, JSON.stringify(prefs));\n }\n\n private applyFilter(): void {\n let result = this.AllEntities;\n\n if (this.SchemaFilter) {\n result = result.filter(e => e.SchemaName === this.SchemaFilter);\n }\n\n if (this.SearchText) {\n const search = this.SearchText.toLowerCase();\n result = result.filter(e => e.Name.toLowerCase().includes(search));\n }\n\n this.FilteredEntities = result;\n this.publishAgentContext();\n this.cdr.markForCheck();\n }\n\n public SelectEntity(entityNode: EntityNode): void {\n if (this.SelectedEntity) {\n this.SelectedEntity.IsSelected = false;\n }\n\n entityNode.IsSelected = true;\n this.SelectedEntity = entityNode;\n\n const entityInfo = this.metadata.Entities.find(e => UUIDsEqual(e.ID, entityNode.ID));\n this.SelectedEntityInfo = entityInfo ?? null;\n\n if (entityInfo) {\n this.ReferencedByEntities = this.buildReferencedByList(entityInfo);\n this.DependsOnEntities = this.buildDependsOnList(entityInfo);\n } else {\n this.ReferencedByEntities = [];\n this.DependsOnEntities = [];\n }\n\n this.publishAgentContext();\n this.cdr.markForCheck();\n }\n\n /** Entities that have FKs pointing TO the selected entity (it is the \"one\" side) */\n private buildReferencedByList(entityInfo: EntityInfo): RelationshipEdge[] {\n return entityInfo.RelatedEntities\n .filter(r =>\n r.Type.trim().toUpperCase() === 'ONE TO MANY' &&\n r.RelatedEntity !== entityInfo.Name\n )\n .map(r => ({\n FromEntity: entityInfo.Name,\n ToEntity: r.RelatedEntity,\n RelatedEntityJoinField: r.RelatedEntityJoinField,\n Type: r.Type\n }))\n .sort((a, b) => a.ToEntity.localeCompare(b.ToEntity));\n }\n\n /** Entities the selected entity has FKs pointing to (it is the \"many\" side) */\n private buildDependsOnList(entityInfo: EntityInfo): RelationshipEdge[] {\n return this.metadata.Entities\n .filter(e =>\n e.Name !== entityInfo.Name &&\n e.RelatedEntities.some(r =>\n r.Type.trim().toUpperCase() === 'ONE TO MANY' &&\n r.RelatedEntity === entityInfo.Name\n )\n )\n .map(e => {\n const rel = e.RelatedEntities.find(r =>\n r.Type.trim().toUpperCase() === 'ONE TO MANY' &&\n r.RelatedEntity === entityInfo.Name\n )!;\n return {\n FromEntity: e.Name,\n ToEntity: entityInfo.Name,\n RelatedEntityJoinField: rel.RelatedEntityJoinField,\n Type: rel.Type\n };\n })\n .sort((a, b) => a.FromEntity.localeCompare(b.FromEntity));\n }\n\n public NavigateToEntity(entityName: string): void {\n const node = this.AllEntities.find(e => e.Name === entityName);\n if (node) {\n // Clear schema filter so the entity is visible\n if (this.SchemaFilter && node.SchemaName !== this.SchemaFilter) {\n this.SchemaFilter = '';\n this.applyFilter();\n }\n this.SelectEntity(node);\n }\n }\n\n public GetDependencyLevel(count: number): string {\n if (count === 0) return 'level-none';\n if (count <= 3) return 'level-low';\n if (count <= 10) return 'level-medium';\n return 'level-high';\n }\n\n public GetSchemaEntityCount(schema: string): number {\n return this.AllEntities.filter(e => e.SchemaName === schema).length;\n }\n\n public Refresh(): void {\n this.LoadData();\n }\n}\n","<mj-page-layout>\n <mj-page-header\n Title=\"Entity Dependency Graph\"\n Icon=\"fa-solid fa-diagram-project\"\n Subtitle=\"Explore entity relationships used by the version history system\">\n <div meta>\n <mj-stat-badge Icon=\"fa-solid fa-table\" [Count]=\"TotalEntities\" Label=\"entities\"></mj-stat-badge>\n <mj-stat-badge Icon=\"fa-solid fa-diagram-project\" [Count]=\"EntitiesWithDependents\" Label=\"with dependents\"></mj-stat-badge>\n <mj-stat-badge Icon=\"fa-solid fa-arrow-right-arrow-left\" [Count]=\"TotalRelationships\" Label=\"relationships\"></mj-stat-badge>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"Refresh()\"></mj-refresh-button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Filter entities...\"\n [Value]=\"SearchText\"\n (ValueChange)=\"OnSearchChange($event)\">\n </mj-page-search>\n @if (AvailableSchemas.length > 1) {\n @for (schema of AvailableSchemas; track schema) {\n <mj-filter-chip\n [Label]=\"schema\"\n [Count]=\"GetSchemaEntityCount(schema)\"\n [Active]=\"SchemaFilter === schema\"\n (Clicked)=\"OnSchemaFilterChange(schema)\">\n </mj-filter-chip>\n }\n }\n </div>\n </mj-page-header>\n\n <mj-page-body [Flex]=\"true\">\n @if (IsLoading) {\n <mj-loading text=\"Loading dependency graph...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Main Layout: Entity List + Detail -->\n <div class=\"graph-layout\">\n <!-- Entity List — page-header [toolbar] owns search + schema chips -->\n <div class=\"entity-list-panel\">\n <div class=\"entity-scroll-list\">\n @for (entity of FilteredEntities; track entity) {\n <div class=\"entity-list-item\"\n [class.selected]=\"entity.IsSelected\"\n (click)=\"SelectEntity(entity)\">\n <div class=\"entity-list-name\">{{entity.Name}}</div>\n <div class=\"entity-list-badges\">\n @if (entity.ReferencedByCount > 0) {\n <span class=\"dep-badge\"\n [ngClass]=\"GetDependencyLevel(entity.ReferencedByCount)\"\n title=\"Referenced by (entities with FKs to this)\">\n {{entity.ReferencedByCount}} <i class=\"fa-solid fa-arrow-down\"></i>\n </span>\n }\n @if (entity.DependsOnCount > 0) {\n <span class=\"dep-badge level-depends-on\"\n title=\"Depends on (entities this has FKs to)\">\n {{entity.DependsOnCount}} <i class=\"fa-solid fa-arrow-up\"></i>\n </span>\n }\n </div>\n </div>\n }\n @if (FilteredEntities.length === 0) {\n <mj-empty-state Variant=\"no-results\" Size=\"compact\"\n Title=\"No entities match your search.\" />\n }\n </div>\n </div>\n <!-- Detail Panel -->\n <div class=\"entity-detail-panel\">\n @if (SelectedEntity) {\n <div class=\"detail-header\">\n <i class=\"fa-solid fa-table detail-icon\"></i>\n <div class=\"detail-header-text\">\n <h3 class=\"detail-title\">{{SelectedEntity.Name}}</h3>\n <span class=\"detail-schema\">{{SelectedEntity.SchemaName}}</span>\n </div>\n </div>\n <!-- Referenced By (entities that have FKs pointing to this entity) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-down section-icon referenced-by-icon\"></i>\n <h4>Referenced By</h4>\n <span class=\"section-count\">{{ReferencedByEntities.length}}</span>\n </div>\n <p class=\"section-hint\">Entities that have foreign keys pointing to <strong>{{SelectedEntity.Name}}</strong></p>\n @if (ReferencedByEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of ReferencedByEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.ToEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.ToEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (ReferencedByEntities.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-link-slash\"\n Title=\"No entities reference this entity.\" />\n }\n </div>\n <!-- Depends On (entities this entity has FKs to) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-up section-icon depends-on-icon\"></i>\n <h4>Depends On</h4>\n <span class=\"section-count\">{{DependsOnEntities.length}}</span>\n </div>\n <p class=\"section-hint\"><strong>{{SelectedEntity.Name}}</strong> has foreign keys pointing to these entities</p>\n @if (DependsOnEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of DependsOnEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.FromEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.FromEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (DependsOnEntities.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-link-slash\"\n Title=\"This entity has no foreign key dependencies.\" />\n }\n </div>\n } @else {\n <mj-empty-state class=\"graph-detail-empty\" Icon=\"fa-solid fa-diagram-project\"\n Title=\"Select an Entity\"\n Message=\"Choose an entity from the list to explore its dependency relationships.\" />\n }\n </div>\n </div>\n }\n </mj-page-body>\n</mj-page-layout>\n"]}
|
|
1
|
+
{"version":3,"file":"graph-resource.component.js","sourceRoot":"","sources":["../../../src/VersionHistory/components/graph-resource.component.ts","../../../src/VersionHistory/components/graph-resource.component.html"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAE,SAAS,EAAuD,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxH,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAG,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAgB,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAmB,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC1F,OAAO,EACH,oCAAoC,EACpC,kBAAkB,GAErB,MAAM,wCAAwC,CAAC;;;;;;;ICUtC,0CAI2C;IAAzC,wPAAW,sCAA4B,KAAC;IAC1C,iBAAiB;;;;IAFf,AADA,AADA,iCAAgB,iDACsB,6CACJ;;;IAJtC,oJAOC;;;IAPD,sCAOC;;;IAOL,iCAA4D;;;IAgB9C,gCAEoD;IAClD,YAA6B;IAAA,wBAAsC;IACrE,iBAAO;;;;IAHL,gFAAwD;IAExD,cAA6B;IAA7B,4DAA6B;;;IAI/B,gCACgD;IAC9C,YAA0B;IAAA,wBAAoC;IAChE,iBAAO;;;IADL,cAA0B;IAA1B,yDAA0B;;;;IAflC,+BAEiC;IAA/B,yOAAS,8BAAoB,KAAC;IAC9B,+BAA8B;IAAA,YAAsB;IAAA,iBAAM;IAC1D,+BAAgC;IAC9B,6HAAoC;IAOpC,6HAAiC;IAOrC,AADE,iBAAM,EACF;;;IAlBJ,gDAAoC;IAEN,eAAsB;IAAtB,2CAAsB;IAElD,eAMC;IAND,0DAMC;IACD,cAKC;IALD,uDAKC;;;IAKL,qCAC2C;;;;IA0BnC,AADF,+BAA+B,cAEc;IAAzC,mQAAS,wCAA8B,KAAC;IACxC,wBAA0C;IAC1C,gCAA8B;IAAA,YAAgB;IAAA,iBAAO;IACrD,gCAA6B;IAC3B,wBAAgC;IAChC,YACF;IAEJ,AADE,AADE,iBAAO,EACH,EACF;;;IAN4B,eAAgB;IAAhB,qCAAgB;IAG5C,eACF;IADE,8DACF;;;IAVR,+BAA+B;IAC7B,sKAYC;IACH,iBAAM;;;IAbJ,cAYC;IAZD,0CAYC;;;IAIH,qCAC+C;;;;IAezC,AADF,+BAA+B,cAEgB;IAA3C,mQAAS,0CAAgC,KAAC;IAC1C,wBAA0C;IAC1C,gCAA8B;IAAA,YAAkB;IAAA,iBAAO;IACvD,gCAA6B;IAC3B,wBAAgC;IAChC,YACF;IAEJ,AADE,AADE,iBAAO,EACH,EACF;;;IAN4B,eAAkB;IAAlB,uCAAkB;IAG9C,eACF;IADE,8DACF;;;IAVR,+BAA+B;IAC7B,sKAYC;IACH,iBAAM;;;IAbJ,cAYC;IAZD,uCAYC;;;IAIH,qCACyD;;;IAhE7D,+BAA2B;IACzB,wBAA6C;IAE3C,AADF,+BAAgC,aACL;IAAA,YAAuB;IAAA,iBAAK;IACrD,gCAA4B;IAAA,YAA6B;IAE7D,AADE,AAD2D,iBAAO,EAC5D,EACF;IAGJ,AADF,+BAAkC,cACJ;IAC1B,wBAAsE;IACtE,2BAAI;IAAA,8BAAa;IAAA,iBAAK;IACtB,iCAA4B;IAAA,aAA+B;IAC7D,AAD6D,iBAAO,EAC9D;IACN,8BAAwB;IAAA,6DAA4C;IAAA,+BAAQ;IAAA,aAAuB;IAAS,AAAT,iBAAS,EAAI;IAChH,sIAAuC;IAiBvC,iJAAyC;IAI3C,iBAAM;IAGJ,AADF,gCAAkC,eACJ;IAC1B,yBAAiE;IACjE,2BAAI;IAAA,2BAAU;IAAA,iBAAK;IACnB,iCAA4B;IAAA,aAA4B;IAC1D,AAD0D,iBAAO,EAC3D;IACkB,AAAxB,8BAAwB,cAAQ;IAAA,aAAuB;IAAA,iBAAS;IAAC,6DAA2C;IAAA,iBAAI;IAChH,sIAAoC;IAiBpC,iJAAsC;IAIxC,iBAAM;;;IA/DuB,eAAuB;IAAvB,gDAAuB;IACpB,eAA6B;IAA7B,sDAA6B;IAQ7B,eAA+B;IAA/B,wDAA+B;IAEe,eAAuB;IAAvB,gDAAuB;IACnG,cAgBC;IAhBD,kEAgBC;IACD,cAGC;IAHD,oEAGC;IAO6B,eAA4B;IAA5B,qDAA4B;IAE1B,eAAuB;IAAvB,gDAAuB;IACvD,eAgBC;IAhBD,+DAgBC;IACD,cAGC;IAHD,iEAGC;;;IAGH,qCAEsF;;;IAtGxF,AADF,AAFF,+BAA0B,cAEO,cACG;IAC9B,yIAqBC;IACD,iIAAqC;IAKzC,AADE,iBAAM,EACF;IAEN,+BAAiC;IAqE7B,AApEF,6GAAsB,2GAoEb;IAMb,AADE,iBAAM,EACF;;;IAxGA,eAqBC;IArBD,sCAqBC;IACD,eAGC;IAHD,+DAGC;IAKH,eAwEC;IAxED,+CAwEC;;ADxGF,IAAM,oCAAoC,GAA1C,MAAM,oCAAqC,SAAQ,qBAAqB;;IA0BvD;IAzBb,SAAS,GAAG,IAAI,CAAC;IAExB,iBAAiB;IACV,WAAW,GAAiB,EAAE,CAAC;IAC/B,gBAAgB,GAAiB,EAAE,CAAC;IACpC,UAAU,GAAG,EAAE,CAAC;IAChB,YAAY,GAAG,EAAE,CAAC;IAClB,gBAAgB,GAAa,EAAE,CAAC;IAEvC,yBAAyB;IAClB,cAAc,GAAsB,IAAI,CAAC;IACzC,kBAAkB,GAAsB,IAAI,CAAC;IAC7C,oBAAoB,GAAuB,EAAE,CAAC;IAC9C,iBAAiB,GAAuB,EAAE,CAAC;IAElD,QAAQ;IACD,aAAa,GAAG,CAAC,CAAC;IAClB,sBAAsB,GAAG,CAAC,CAAC;IAC3B,kBAAkB,GAAG,CAAC,CAAC;IAEtB,MAAM,CAAU,SAAS,GAAG,sCAAsC,CAAC;IACnE,iBAAiB,GAAG,KAAK,CAAC;IAC1B,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC;IACnB,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAElD,YAAoB,GAAsB;QACtC,KAAK,EAAE,CAAC;QADQ,QAAG,GAAH,GAAG,CAAmB;IAE1C,CAAC;IAED,QAAQ;QACJ,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,WAAW;QACP,KAAK,CAAC,WAAW,EAAE,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,eAAe;QACX,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,wBAAwB,EAAE,CAAC;IACpC,CAAC;IAED,2CAA2C;IAC3C,kCAAkC;IAClC,EAAE;IACF,6EAA6E;IAC7E,8EAA8E;IAC9E,2EAA2E;IAC3E,4EAA4E;IAC5E,kDAAkD;IAClD,2CAA2C;IAE3C;;;;;OAKG;IACK,mBAAmB;QACvB,MAAM,OAAO,GAAG,oCAAoC,CAAC;YACjD,kBAAkB,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,IAAI,IAAI;YACrD,gBAAgB,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,IAAI;YACjD,qBAAqB,EAAE,IAAI,CAAC,0BAA0B,EAAE;YACxD,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;YACnD,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;YAC3C,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,kBAAkB,EAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM;YAChD,kBAAkB,EAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1D,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SAC1C,CAAC,CAAC;QACH,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;OAKG;IACK,0BAA0B;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC;QACjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO;YACH,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,iBAAiB,EAAE,IAAI,CAAC,oBAAoB,CAAC,MAAM;YACnD,cAAc,EAAE,IAAI,CAAC,iBAAiB,CAAC,MAAM;YAC7C,uBAAuB,EAAE,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;YACvE,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;SACtE,CAAC;IACN,CAAC;IAED;;;;;;;;;;;OAWG;IACK,wBAAwB;QAC5B,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,IAAI,EAAE;YAC7C;gBACI,IAAI,EAAE,+BAA+B;gBACrC,WAAW,EAAE,oOAAoO;gBACjP,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE;gBAChJ,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;aACpF;YACD;gBACI,IAAI,EAAE,wBAAwB;gBAC9B,WAAW,EAAE,6FAA6F;gBAC1G,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE;gBACrG,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;aACtF;YACD;gBACI,IAAI,EAAE,gBAAgB;gBACtB,WAAW,EAAE,+FAA+F;gBAC5G,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;gBACjG,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;aACtF;SACJ,CAAC,CAAC;IACP,CAAC;IAED;;;OAGG;IACK,gBAAgB,CAAC,MAA+B;QACpD,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACb,OAAO,MAAM,CAAC,MAAM,CAAC;QACzB,CAAC;QACD,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACtE,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,gBAAgB,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,kBAAkB,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;IAC3H,CAAC;IAED,iFAAiF;IACzE,kBAAkB,CAAC,MAA+B;QACtD,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACb,OAAO,MAAM,CAAC,MAAM,CAAC;QACzB,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAClD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,KAAK,0CAA0C,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3I,CAAC;QACD,iFAAiF;QACjF,iFAAiF;QACjF,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,kBAAkB,EAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC;IAC1H,CAAC;IAED,0CAA0C;IAClC,kBAAkB,CAAC,MAA+B;QACtD,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACb,OAAO,MAAM,CAAC,MAAM,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,kBAAkB,EAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC;IACtH,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,IAAkB;QAC3C,OAAO,kBAAkB,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,IAAkB;QACzC,OAAO,6BAA6B,CAAC;IACzC,CAAC;IAEM,QAAQ;QACX,IAAI,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAExC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAClC,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,WAAW,EAAE,CAAC,CAAC,iBAAiB;gBAChC,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBAC5C,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;gBACtC,UAAU,EAAE,KAAK;aACpB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YAE/D,iCAAiC;YACjC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;YAErD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;YAC7C,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YAC3F,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;YAE5F,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;IAED,qGAAqG;IAC7F,iBAAiB,CAAC,MAAkB;QACxC,OAAO,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACrC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,aAAa;YAC7C,CAAC,CAAC,aAAa,KAAK,MAAM,CAAC,IAAI,CAClC,CAAC,MAAM,CAAC;IACb,CAAC;IAED,6FAA6F;IACrF,cAAc,CAAC,MAAkB;QACrC,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACrC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI;YACtB,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CACvB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,aAAa;gBAC7C,CAAC,CAAC,aAAa,KAAK,MAAM,CAAC,IAAI,CAClC,CACJ,CAAC,MAAM,CAAC;IACb,CAAC;IAEM,cAAc,CAAC,IAAY;QAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;IAEM,oBAAoB,CAAC,MAAc;QACtC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/D,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC9B,CAAC;IAEO,mBAAmB;QACvB,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,sCAAoC,CAAC,SAAS,CAAC,CAAC;YAC/F,IAAI,GAAG,EAAE,CAAC;gBACN,MAAM,KAAK,GAA4B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACvD,IAAI,KAAK,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;oBAC7B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;gBAC3C,CAAC;YACL,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;YACzD,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAClC,CAAC;IAEO,kBAAkB;QACtB,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAAE,OAAO;QACpC,MAAM,KAAK,GAA4B;YACnC,YAAY,EAAE,IAAI,CAAC,YAAY;SAClC,CAAC;QACF,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CAAC,sCAAoC,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACvH,CAAC;IAEO,WAAW;QACf,IAAI,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;QAE9B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,YAAY,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;YAC7C,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACvH,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC;QAC/B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,YAAY,CAAC,UAAsB;QACtC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,IAAI,CAAC,cAAc,CAAC,UAAU,GAAG,KAAK,CAAC;QAC3C,CAAC;QAED,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC;QAEjC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACrF,IAAI,CAAC,kBAAkB,GAAG,UAAU,IAAI,IAAI,CAAC;QAE7C,IAAI,UAAU,EAAE,CAAC;YACb,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;YACnE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;YAC/B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAChC,CAAC;QAED,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,oFAAoF;IAC5E,qBAAqB,CAAC,UAAsB;QAChD,OAAO,UAAU,CAAC,eAAe;aAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,CACR,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,aAAa;YAC7C,CAAC,CAAC,aAAa,KAAK,UAAU,CAAC,IAAI,CACtC;aACA,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACP,UAAU,EAAE,UAAU,CAAC,IAAI;YAC3B,QAAQ,EAAE,CAAC,CAAC,aAAa;YACzB,sBAAsB,EAAE,CAAC,CAAC,sBAAsB;YAChD,IAAI,EAAE,CAAC,CAAC,IAAI;SACf,CAAC,CAAC;aACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,+EAA+E;IACvE,kBAAkB,CAAC,UAAsB;QAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ;aACxB,MAAM,CAAC,CAAC,CAAC,EAAE,CACR,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI;YAC1B,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CACvB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,aAAa;gBAC7C,CAAC,CAAC,aAAa,KAAK,UAAU,CAAC,IAAI,CACtC,CACJ;aACA,GAAG,CAAC,CAAC,CAAC,EAAE;YACL,MAAM,GAAG,GAAG,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CACnC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,aAAa;gBAC7C,CAAC,CAAC,aAAa,KAAK,UAAU,CAAC,IAAI,CACrC,CAAC;YACH,OAAO;gBACH,UAAU,EAAE,CAAC,CAAC,IAAI;gBAClB,QAAQ,EAAE,UAAU,CAAC,IAAI;gBACzB,sBAAsB,EAAE,GAAG,CAAC,sBAAsB;gBAClD,IAAI,EAAE,GAAG,CAAC,IAAI;aACjB,CAAC;QACN,CAAC,CAAC;aACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IAClE,CAAC;IAEM,gBAAgB,CAAC,UAAkB;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAC/D,IAAI,IAAI,EAAE,CAAC;YACP,+CAA+C;YAC/C,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC7D,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;gBACvB,IAAI,CAAC,WAAW,EAAE,CAAC;YACvB,CAAC;YACD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACL,CAAC;IAEM,kBAAkB,CAAC,KAAa;QACnC,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,YAAY,CAAC;QACrC,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,WAAW,CAAC;QACnC,IAAI,KAAK,IAAI,EAAE;YAAE,OAAO,cAAc,CAAC;QACvC,OAAO,YAAY,CAAC;IACxB,CAAC;IAEM,oBAAoB,CAAC,MAAc;QACtC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACxE,CAAC;IAEM,OAAO;QACV,IAAI,CAAC,QAAQ,EAAE,CAAC;IACpB,CAAC;8HAvYQ,oCAAoC;6DAApC,oCAAoC;YCpC7C,AAJF,AADF,sCAAgB,wBAI+D,aACjE;YAGR,AADA,AADA,mCAAiG,uBAC0B,uBACC;YAC9H,iBAAM;YAEJ,AADF,8BAAa,2BACoD;YAAtB,gIAAW,aAAS,IAAC;YAChE,AADiE,iBAAoB,EAC/E;YAEJ,AADF,8BAAa,wBAI8B;YAAvC,2IAAe,0BAAsB,IAAC;YACxC,iBAAiB;YACjB,8FAAmC;YAWvC,AADE,iBAAM,EACS;YAEjB,wCAA4B;YAC5B,gHAAiB;YAIjB,yGAAkB;YAiHpB,AADE,iBAAe,EACA;;YAhJ6B,eAAuB;YAAvB,yCAAuB;YACb,cAAgC;YAAhC,kDAAgC;YACzB,cAA4B;YAA5B,8CAA4B;YAGlE,eAAqB;YAArB,uCAAqB;YAKtC,eAAoB;YAApB,sCAAoB;YAGtB,cASC;YATD,2DASC;YAIS,cAAa;YAAb,2BAAa;YAC3B,cAEC;YAFD,yCAEC;YAED,cA+GC;YA/GD,0CA+GC;;;AD3GU,oCAAoC;IARhD,aAAa,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;GAQvD,oCAAoC,CAwYhD;;iFAxYY,oCAAoC;cAPhD,SAAS;6BACI,KAAK,YACL,mCAAmC,mBAG5B,uBAAuB,CAAC,MAAM;;kFAEtC,oCAAoC","sourcesContent":["import { Component, OnInit, OnDestroy, AfterViewInit, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { Metadata, EntityInfo } from '@memberjunction/core';\nimport { ResourceData, UserInfoEngine } from '@memberjunction/core-entities';\nimport { AgentToolResult, validateStringParam } from '../../shared/agent-tool-validation';\nimport {\n buildVersionHistoryGraphAgentContext,\n resolveGraphEntity,\n VersionHistoryGraphSelectedEntitySummary,\n} from '../version-history-graph-agent-context';\n\ninterface VersionGraphPreferences {\n SchemaFilter: string;\n}\ninterface EntityNode {\n Name: string;\n DisplayName: string;\n ID: string;\n SchemaName: string;\n ReferencedByCount: number;\n DependsOnCount: number;\n IsSelected: boolean;\n}\n\ninterface RelationshipEdge {\n FromEntity: string;\n ToEntity: string;\n RelatedEntityJoinField: string;\n Type: string;\n}\n\n@RegisterClass(BaseResourceComponent, 'VersionHistoryGraphResource')\n@Component({\n standalone: false,\n selector: 'mj-version-history-graph-resource',\n templateUrl: './graph-resource.component.html',\n styleUrls: ['./graph-resource.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class VersionHistoryGraphResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy, AfterViewInit {\n public IsLoading = true;\n\n // Entity browser\n public AllEntities: EntityNode[] = [];\n public FilteredEntities: EntityNode[] = [];\n public SearchText = '';\n public SchemaFilter = '';\n public AvailableSchemas: string[] = [];\n\n // Selected entity detail\n public SelectedEntity: EntityNode | null = null;\n public SelectedEntityInfo: EntityInfo | null = null;\n public ReferencedByEntities: RelationshipEdge[] = [];\n public DependsOnEntities: RelationshipEdge[] = [];\n\n // Stats\n public TotalEntities = 0;\n public EntitiesWithDependents = 0;\n public TotalRelationships = 0;\n\n private static readonly PREFS_KEY = 'VersionHistory.Graph.UserPreferences';\n private preferencesLoaded = false;\n private metadata = this.ProviderToUse;\n protected override destroy$ = new Subject<void>();\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n ngOnInit(): void {\n super.ngOnInit();\n this.loadUserPreferences();\n this.LoadData();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * After the view initializes, publish the initial agent context and register\n * the client tools the AI agent can invoke against this surface. The ongoing\n * context re-emit happens in {@link applyFilter} and {@link SelectEntity}.\n */\n ngAfterViewInit(): void {\n this.publishAgentContext();\n this.registerAgentClientTools();\n }\n\n // ========================================\n // AI AGENT CONTEXT & CLIENT TOOLS\n //\n // 🔒 SAFETY BOUNDARY: This surface is a read-only browse/filter/inspect view\n // over entity-relationship metadata. It exposes ONLY select / filter / search\n // tools to the agent — NO mutation of any kind (no schema edits, no entity\n // changes, no restore/rollback, no deletion). Every tool below only changes\n // what the user is LOOKING at; none changes data.\n // ========================================\n\n /**\n * Publish the current Dependency-Graph state to the AI agent via\n * NavigationService. Shaping lives in the pure\n * {@link buildVersionHistoryGraphAgentContext} helper so it stays\n * unit-testable. Called on load, on filter changes, and on entity selection.\n */\n private publishAgentContext(): void {\n const context = buildVersionHistoryGraphAgentContext({\n SelectedEntityName: this.SelectedEntity?.Name ?? null,\n SelectedEntityId: this.SelectedEntity?.ID ?? null,\n SelectedEntitySummary: this.buildSelectedEntitySummary(),\n TotalEntities: this.TotalEntities,\n EntitiesWithDependents: this.EntitiesWithDependents,\n TotalRelationships: this.TotalRelationships,\n SearchText: this.SearchText,\n SchemaFilter: this.SchemaFilter,\n VisibleEntityCount: this.FilteredEntities.length,\n VisibleEntityNames: this.FilteredEntities.map(e => e.Name),\n AvailableSchemas: this.AvailableSchemas,\n });\n this.navigationService.SetAgentContext(this, context);\n }\n\n /**\n * Build the selected entity's dependency summary for the agent context, or\n * null when no entity is selected. Reads the already-derived ReferencedBy /\n * DependsOn relationship lists so the co-agent can describe the entity's place\n * in the graph and suggest neighbours as next selections.\n */\n private buildSelectedEntitySummary(): VersionHistoryGraphSelectedEntitySummary | null {\n const node = this.SelectedEntity;\n if (!node) {\n return null;\n }\n return {\n ID: node.ID,\n Name: node.Name,\n SchemaName: node.SchemaName,\n ReferencedByCount: this.ReferencedByEntities.length,\n DependsOnCount: this.DependsOnEntities.length,\n ReferencedByEntityNames: this.ReferencedByEntities.map(r => r.ToEntity),\n DependsOnEntityNames: this.DependsOnEntities.map(r => r.FromEntity),\n };\n }\n\n /**\n * Register the read-only client tools the AI agent can invoke against the\n * Dependency Graph. Each handler is tolerant — it never throws and returns a\n * typed `{ Success, Data?, ErrorMessage? }` result.\n *\n * Tools:\n * - SelectEntityForDependencyView: select an entity by name to inspect its\n * dependencies (delegates to {@link NavigateToEntity}, which clears any\n * schema filter so the entity is reachable).\n * - FilterEntitiesBySchema: filter the entity list to a single schema.\n * - SearchEntities: filter the entity list by an entity-name substring.\n */\n private registerAgentClientTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'SelectEntityForDependencyView',\n Description: 'Select an entity by its ID or name to inspect what references it and what it depends on. Resolution: exact ID, then exact name, then a name-contains match. Clears any active schema filter so the entity is reachable. View-only.',\n ParameterSchema: { type: 'object', properties: { entityName: { type: 'string', description: 'Entity ID or name.' } }, required: ['entityName'] },\n Handler: async (params: Record<string, unknown>) => this.toolSelectEntity(params),\n },\n {\n Name: 'FilterEntitiesBySchema',\n Description: 'Filter the entity list to a single schema. Pass an empty string to clear the schema filter.',\n ParameterSchema: { type: 'object', properties: { schema: { type: 'string' } }, required: ['schema'] },\n Handler: async (params: Record<string, unknown>) => this.toolFilterBySchema(params),\n },\n {\n Name: 'SearchEntities',\n Description: 'Filter the entity list by an entity-name substring. Pass an empty string to clear the search.',\n ParameterSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] },\n Handler: async (params: Record<string, unknown>) => this.toolSearchEntities(params),\n },\n ]);\n }\n\n /**\n * Resolve an entity by ID or name (exact ID → exact name → name-contains) and\n * select it for the dependency view. View-only.\n */\n private toolSelectEntity(params: Record<string, unknown>): AgentToolResult & { Data?: Record<string, unknown> } {\n const parsed = validateStringParam(params['entityName'], 'entityName');\n if (!parsed.ok) {\n return parsed.result;\n }\n const resolution = resolveGraphEntity(parsed.value, this.AllEntities);\n if (!resolution.ok) {\n return { Success: false, ErrorMessage: resolution.error };\n }\n this.NavigateToEntity(resolution.entity.Name);\n return { Success: true, Data: { SelectedEntityId: resolution.entity.ID, SelectedEntityName: resolution.entity.Name } };\n }\n\n /** Apply a schema filter deterministically (no toggle), validating it exists. */\n private toolFilterBySchema(params: Record<string, unknown>): AgentToolResult & { Data?: Record<string, unknown> } {\n const parsed = validateStringParam(params['schema'], 'schema');\n if (!parsed.ok) {\n return parsed.result;\n }\n const value = parsed.value.trim();\n if (value && !this.AvailableSchemas.includes(value)) {\n return { Success: false, ErrorMessage: `Schema \"${value}\" is not available. Available schemas: ${this.AvailableSchemas.join(', ')}.` };\n }\n // Set deterministically rather than via OnSchemaFilterChange's toggle semantics,\n // so the agent always lands on the requested filter regardless of current state.\n this.SchemaFilter = value;\n this.applyFilter();\n this.persistPreferences();\n return { Success: true, Data: { SchemaFilter: this.SchemaFilter, VisibleEntityCount: this.FilteredEntities.length } };\n }\n\n /** Apply an entity-name search filter. */\n private toolSearchEntities(params: Record<string, unknown>): AgentToolResult & { Data?: Record<string, unknown> } {\n const parsed = validateStringParam(params['text'], 'text');\n if (!parsed.ok) {\n return parsed.result;\n }\n this.OnSearchChange(parsed.value);\n return { Success: true, Data: { SearchText: this.SearchText, VisibleEntityCount: this.FilteredEntities.length } };\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Dependency Graph';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-diagram-project';\n }\n\n public LoadData(): void {\n try {\n this.IsLoading = true;\n this.cdr.markForCheck();\n\n const entities = this.metadata.Entities;\n\n this.AllEntities = entities.map(e => ({\n Name: e.Name,\n DisplayName: e.DisplayNameOrName,\n ID: e.ID,\n SchemaName: e.SchemaName,\n ReferencedByCount: this.countReferencedBy(e),\n DependsOnCount: this.countDependsOn(e),\n IsSelected: false\n })).sort((a, b) => a.DisplayName.localeCompare(b.DisplayName));\n\n // Extract unique schemas, sorted\n const schemaSet = new Set(this.AllEntities.map(e => e.SchemaName));\n this.AvailableSchemas = Array.from(schemaSet).sort();\n\n this.TotalEntities = this.AllEntities.length;\n this.EntitiesWithDependents = this.AllEntities.filter(e => e.ReferencedByCount > 0).length;\n this.TotalRelationships = this.AllEntities.reduce((sum, e) => sum + e.ReferencedByCount, 0);\n\n this.applyFilter();\n } catch (error) {\n console.error('Error loading dependency graph data:', error);\n } finally {\n this.IsLoading = false;\n this.NotifyLoadComplete();\n this.publishAgentContext();\n this.cdr.markForCheck();\n }\n }\n\n /** Count entities that reference this entity (have FKs pointing to it), excluding self-references */\n private countReferencedBy(entity: EntityInfo): number {\n return entity.RelatedEntities.filter(r =>\n r.Type.trim().toUpperCase() === 'ONE TO MANY' &&\n r.RelatedEntity !== entity.Name\n ).length;\n }\n\n /** Count entities this entity depends on (has FKs pointing to), excluding self-references */\n private countDependsOn(entity: EntityInfo): number {\n return this.metadata.Entities.filter(e =>\n e.Name !== entity.Name &&\n e.RelatedEntities.some(r =>\n r.Type.trim().toUpperCase() === 'ONE TO MANY' &&\n r.RelatedEntity === entity.Name\n )\n ).length;\n }\n\n public OnSearchChange(text: string): void {\n this.SearchText = text;\n this.applyFilter();\n }\n\n public OnSchemaFilterChange(schema: string): void {\n this.SchemaFilter = this.SchemaFilter === schema ? '' : schema;\n this.applyFilter();\n this.persistPreferences();\n }\n\n private loadUserPreferences(): void {\n try {\n const raw = UserInfoEngine.Instance.GetSetting(VersionHistoryGraphResourceComponent.PREFS_KEY);\n if (raw) {\n const prefs: VersionGraphPreferences = JSON.parse(raw);\n if (prefs.SchemaFilter != null) {\n this.SchemaFilter = prefs.SchemaFilter;\n }\n }\n } catch (error) {\n console.error('Error loading graph preferences:', error);\n this.SchemaFilter = '';\n }\n this.preferencesLoaded = true;\n }\n\n private persistPreferences(): void {\n if (!this.preferencesLoaded) return;\n const prefs: VersionGraphPreferences = {\n SchemaFilter: this.SchemaFilter\n };\n UserInfoEngine.Instance.SetSettingDebounced(VersionHistoryGraphResourceComponent.PREFS_KEY, JSON.stringify(prefs));\n }\n\n private applyFilter(): void {\n let result = this.AllEntities;\n\n if (this.SchemaFilter) {\n result = result.filter(e => e.SchemaName === this.SchemaFilter);\n }\n\n if (this.SearchText) {\n const search = this.SearchText.toLowerCase();\n result = result.filter(e => e.DisplayName.toLowerCase().includes(search) || e.Name.toLowerCase().includes(search));\n }\n\n this.FilteredEntities = result;\n this.publishAgentContext();\n this.cdr.markForCheck();\n }\n\n public SelectEntity(entityNode: EntityNode): void {\n if (this.SelectedEntity) {\n this.SelectedEntity.IsSelected = false;\n }\n\n entityNode.IsSelected = true;\n this.SelectedEntity = entityNode;\n\n const entityInfo = this.metadata.Entities.find(e => UUIDsEqual(e.ID, entityNode.ID));\n this.SelectedEntityInfo = entityInfo ?? null;\n\n if (entityInfo) {\n this.ReferencedByEntities = this.buildReferencedByList(entityInfo);\n this.DependsOnEntities = this.buildDependsOnList(entityInfo);\n } else {\n this.ReferencedByEntities = [];\n this.DependsOnEntities = [];\n }\n\n this.publishAgentContext();\n this.cdr.markForCheck();\n }\n\n /** Entities that have FKs pointing TO the selected entity (it is the \"one\" side) */\n private buildReferencedByList(entityInfo: EntityInfo): RelationshipEdge[] {\n return entityInfo.RelatedEntities\n .filter(r =>\n r.Type.trim().toUpperCase() === 'ONE TO MANY' &&\n r.RelatedEntity !== entityInfo.Name\n )\n .map(r => ({\n FromEntity: entityInfo.Name,\n ToEntity: r.RelatedEntity,\n RelatedEntityJoinField: r.RelatedEntityJoinField,\n Type: r.Type\n }))\n .sort((a, b) => a.ToEntity.localeCompare(b.ToEntity));\n }\n\n /** Entities the selected entity has FKs pointing to (it is the \"many\" side) */\n private buildDependsOnList(entityInfo: EntityInfo): RelationshipEdge[] {\n return this.metadata.Entities\n .filter(e =>\n e.Name !== entityInfo.Name &&\n e.RelatedEntities.some(r =>\n r.Type.trim().toUpperCase() === 'ONE TO MANY' &&\n r.RelatedEntity === entityInfo.Name\n )\n )\n .map(e => {\n const rel = e.RelatedEntities.find(r =>\n r.Type.trim().toUpperCase() === 'ONE TO MANY' &&\n r.RelatedEntity === entityInfo.Name\n )!;\n return {\n FromEntity: e.Name,\n ToEntity: entityInfo.Name,\n RelatedEntityJoinField: rel.RelatedEntityJoinField,\n Type: rel.Type\n };\n })\n .sort((a, b) => a.FromEntity.localeCompare(b.FromEntity));\n }\n\n public NavigateToEntity(entityName: string): void {\n const node = this.AllEntities.find(e => e.Name === entityName);\n if (node) {\n // Clear schema filter so the entity is visible\n if (this.SchemaFilter && node.SchemaName !== this.SchemaFilter) {\n this.SchemaFilter = '';\n this.applyFilter();\n }\n this.SelectEntity(node);\n }\n }\n\n public GetDependencyLevel(count: number): string {\n if (count === 0) return 'level-none';\n if (count <= 3) return 'level-low';\n if (count <= 10) return 'level-medium';\n return 'level-high';\n }\n\n public GetSchemaEntityCount(schema: string): number {\n return this.AllEntities.filter(e => e.SchemaName === schema).length;\n }\n\n public Refresh(): void {\n this.LoadData();\n }\n}\n","<mj-page-layout>\n <mj-page-header\n Title=\"Entity Dependency Graph\"\n Icon=\"fa-solid fa-diagram-project\"\n Subtitle=\"Explore entity relationships used by the version history system\">\n <div meta>\n <mj-stat-badge Icon=\"fa-solid fa-table\" [Count]=\"TotalEntities\" Label=\"entities\"></mj-stat-badge>\n <mj-stat-badge Icon=\"fa-solid fa-diagram-project\" [Count]=\"EntitiesWithDependents\" Label=\"with dependents\"></mj-stat-badge>\n <mj-stat-badge Icon=\"fa-solid fa-arrow-right-arrow-left\" [Count]=\"TotalRelationships\" Label=\"relationships\"></mj-stat-badge>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"Refresh()\"></mj-refresh-button>\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Filter entities...\"\n [Value]=\"SearchText\"\n (ValueChange)=\"OnSearchChange($event)\">\n </mj-page-search>\n @if (AvailableSchemas.length > 1) {\n @for (schema of AvailableSchemas; track schema) {\n <mj-filter-chip\n [Label]=\"schema\"\n [Count]=\"GetSchemaEntityCount(schema)\"\n [Active]=\"SchemaFilter === schema\"\n (Clicked)=\"OnSchemaFilterChange(schema)\">\n </mj-filter-chip>\n }\n }\n </div>\n </mj-page-header>\n\n <mj-page-body [Flex]=\"true\">\n @if (IsLoading) {\n <mj-loading text=\"Loading dependency graph...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Main Layout: Entity List + Detail -->\n <div class=\"graph-layout\">\n <!-- Entity List — page-header [toolbar] owns search + schema chips -->\n <div class=\"entity-list-panel\">\n <div class=\"entity-scroll-list\">\n @for (entity of FilteredEntities; track entity) {\n <div class=\"entity-list-item\"\n [class.selected]=\"entity.IsSelected\"\n (click)=\"SelectEntity(entity)\">\n <div class=\"entity-list-name\">{{entity.DisplayName}}</div>\n <div class=\"entity-list-badges\">\n @if (entity.ReferencedByCount > 0) {\n <span class=\"dep-badge\"\n [ngClass]=\"GetDependencyLevel(entity.ReferencedByCount)\"\n title=\"Referenced by (entities with FKs to this)\">\n {{entity.ReferencedByCount}} <i class=\"fa-solid fa-arrow-down\"></i>\n </span>\n }\n @if (entity.DependsOnCount > 0) {\n <span class=\"dep-badge level-depends-on\"\n title=\"Depends on (entities this has FKs to)\">\n {{entity.DependsOnCount}} <i class=\"fa-solid fa-arrow-up\"></i>\n </span>\n }\n </div>\n </div>\n }\n @if (FilteredEntities.length === 0) {\n <mj-empty-state Variant=\"no-results\" Size=\"compact\"\n Title=\"No entities match your search.\" />\n }\n </div>\n </div>\n <!-- Detail Panel -->\n <div class=\"entity-detail-panel\">\n @if (SelectedEntity) {\n <div class=\"detail-header\">\n <i class=\"fa-solid fa-table detail-icon\"></i>\n <div class=\"detail-header-text\">\n <h3 class=\"detail-title\">{{SelectedEntity.Name}}</h3>\n <span class=\"detail-schema\">{{SelectedEntity.SchemaName}}</span>\n </div>\n </div>\n <!-- Referenced By (entities that have FKs pointing to this entity) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-down section-icon referenced-by-icon\"></i>\n <h4>Referenced By</h4>\n <span class=\"section-count\">{{ReferencedByEntities.length}}</span>\n </div>\n <p class=\"section-hint\">Entities that have foreign keys pointing to <strong>{{SelectedEntity.Name}}</strong></p>\n @if (ReferencedByEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of ReferencedByEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.ToEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.ToEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (ReferencedByEntities.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-link-slash\"\n Title=\"No entities reference this entity.\" />\n }\n </div>\n <!-- Depends On (entities this entity has FKs to) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-up section-icon depends-on-icon\"></i>\n <h4>Depends On</h4>\n <span class=\"section-count\">{{DependsOnEntities.length}}</span>\n </div>\n <p class=\"section-hint\"><strong>{{SelectedEntity.Name}}</strong> has foreign keys pointing to these entities</p>\n @if (DependsOnEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of DependsOnEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.FromEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.FromEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (DependsOnEntities.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-link-slash\"\n Title=\"This entity has no foreign key dependencies.\" />\n }\n </div>\n } @else {\n <mj-empty-state class=\"graph-detail-empty\" Icon=\"fa-solid fa-diagram-project\"\n Title=\"Select an Entity\"\n Message=\"Choose an entity from the list to explore its dependency relationships.\" />\n }\n </div>\n </div>\n }\n </mj-page-body>\n</mj-page-layout>\n"]}
|
|
@@ -7,13 +7,15 @@ import * as i5 from "@angular/forms";
|
|
|
7
7
|
import * as i6 from "@memberjunction/ng-ui-components";
|
|
8
8
|
import * as i7 from "@memberjunction/ng-shared-generic";
|
|
9
9
|
import * as i8 from "@memberjunction/ng-conversations";
|
|
10
|
-
import * as i9 from "
|
|
11
|
-
import * as i10 from "./PredictiveStudio/components/ps-
|
|
12
|
-
import * as i11 from "./PredictiveStudio/components/ps-
|
|
13
|
-
import * as i12 from "./PredictiveStudio/components/ps-
|
|
14
|
-
import * as i13 from "./PredictiveStudio/components/ps-
|
|
15
|
-
import * as i14 from "./PredictiveStudio/components/ps-
|
|
16
|
-
import * as i15 from "./PredictiveStudio/components/ps-
|
|
10
|
+
import * as i9 from "angular-split";
|
|
11
|
+
import * as i10 from "./PredictiveStudio/components/ps-home.component";
|
|
12
|
+
import * as i11 from "./PredictiveStudio/components/ps-catalog.component";
|
|
13
|
+
import * as i12 from "./PredictiveStudio/components/ps-pipelines.component";
|
|
14
|
+
import * as i13 from "./PredictiveStudio/components/ps-experiments.component";
|
|
15
|
+
import * as i14 from "./PredictiveStudio/components/ps-registry.component";
|
|
16
|
+
import * as i15 from "./PredictiveStudio/components/ps-compare.component";
|
|
17
|
+
import * as i16 from "./PredictiveStudio/components/ps-production.component";
|
|
18
|
+
import * as i17 from "./PredictiveStudio/components/ps-predictions-grid.component";
|
|
17
19
|
/**
|
|
18
20
|
* PredictiveStudioDashboardsModule — the lazy-loadable feature chunk for the Predictive Studio app.
|
|
19
21
|
* Exported via a subpath in package.json (`./predictive-studio-dashboards.module`) so the lazy-config
|
|
@@ -32,7 +34,7 @@ import * as i15 from "./PredictiveStudio/components/ps-production.component";
|
|
|
32
34
|
*/
|
|
33
35
|
export declare class PredictiveStudioDashboardsModule {
|
|
34
36
|
static ɵfac: i0.ɵɵFactoryDeclaration<PredictiveStudioDashboardsModule, never>;
|
|
35
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<PredictiveStudioDashboardsModule, [typeof i1.PSPredictionsResourceComponent, typeof i2.PSStudioResourceComponent, typeof i3.PSModelsResourceComponent], [typeof i4.CommonModule, typeof i5.FormsModule, typeof i6.MJButtonDirective, typeof i6.MJPageLayoutComponent, typeof i6.MJPageHeaderComponent, typeof i6.MJPageHeaderInteriorComponent, typeof i6.MJPageBodyComponent, typeof i6.MJPageBodyInteriorComponent, typeof i6.MJStatBadgeComponent, typeof i7.SharedGenericModule, typeof i8.ConversationsModule, typeof i9.
|
|
37
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<PredictiveStudioDashboardsModule, [typeof i1.PSPredictionsResourceComponent, typeof i2.PSStudioResourceComponent, typeof i3.PSModelsResourceComponent], [typeof i4.CommonModule, typeof i5.FormsModule, typeof i6.MJButtonDirective, typeof i6.MJPageLayoutComponent, typeof i6.MJPageHeaderComponent, typeof i6.MJPageHeaderInteriorComponent, typeof i6.MJPageBodyComponent, typeof i6.MJPageBodyInteriorComponent, typeof i6.MJStatBadgeComponent, typeof i7.SharedGenericModule, typeof i8.ConversationsModule, typeof i9.AngularSplitModule, typeof i10.PSHomeComponent, typeof i11.PSCatalogComponent, typeof i12.PSPipelinesComponent, typeof i13.PSExperimentsComponent, typeof i14.PSRegistryComponent, typeof i15.PSCompareComponent, typeof i16.PSProductionComponent, typeof i17.PSPredictionsGridComponent], [typeof i1.PSPredictionsResourceComponent, typeof i2.PSStudioResourceComponent, typeof i3.PSModelsResourceComponent, typeof i17.PSPredictionsGridComponent]>;
|
|
36
38
|
static ɵinj: i0.ɵɵInjectorDeclaration<PredictiveStudioDashboardsModule>;
|
|
37
39
|
}
|
|
38
40
|
export { PSPredictionsResourceComponent, LoadPSPredictionsResource } from './PredictiveStudio/resources/ps-predictions-resource.component';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"predictive-studio-dashboards.module.d.ts","sourceRoot":"","sources":["../src/predictive-studio-dashboards.module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"predictive-studio-dashboards.module.d.ts","sourceRoot":"","sources":["../src/predictive-studio-dashboards.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AA6BA;;;;;;;;;;;;;;;GAeG;AACH,qBAmCa,gCAAgC;yCAAhC,gCAAgC;0CAAhC,gCAAgC;0CAAhC,gCAAgC;CAAG;AAKhD,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,MAAM,gEAAgE,CAAC;AAC3I,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,2DAA2D,CAAC;AAC5H,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,2DAA2D,CAAC"}
|