@memberjunction/ng-dashboards 5.44.0 → 5.45.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/autotagging/tabs/sources-tab.component.d.ts +1 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/tabs/sources-tab.component.js +5 -3
- package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +4 -2
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +13 -11
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.d.ts +3 -1
- package/dist/AI/components/prompts/prompt-version-control.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +12 -10
- package/dist/AI/components/prompts/prompt-version-control.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +1 -0
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.js +10 -8
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +2 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts +1 -0
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +5 -3
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts +3 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +11 -5
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts +3 -2
- package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +23 -9
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.d.ts +3 -2
- package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +10 -4
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/DatabaseDesigner/components/modify/database-modify.component.d.ts +2 -1
- package/dist/DatabaseDesigner/components/modify/database-modify.component.d.ts.map +1 -1
- package/dist/DatabaseDesigner/components/modify/database-modify.component.js +13 -6
- package/dist/DatabaseDesigner/components/modify/database-modify.component.js.map +1 -1
- package/dist/FormBuilder/form-builder-resource.component.d.ts +2 -1
- package/dist/FormBuilder/form-builder-resource.component.d.ts.map +1 -1
- package/dist/FormBuilder/form-builder-resource.component.js +10 -8
- package/dist/FormBuilder/form-builder-resource.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.d.ts +3 -1
- package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +32 -14
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts +4 -2
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +15 -13
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/UserRoutines/user-routines-agent-context.d.ts +44 -0
- package/dist/UserRoutines/user-routines-agent-context.d.ts.map +1 -0
- package/dist/UserRoutines/user-routines-agent-context.js +81 -0
- package/dist/UserRoutines/user-routines-agent-context.js.map +1 -0
- package/dist/UserRoutines/user-routines-resource.component.d.ts +60 -0
- package/dist/UserRoutines/user-routines-resource.component.d.ts.map +1 -0
- package/dist/UserRoutines/user-routines-resource.component.js +328 -0
- package/dist/UserRoutines/user-routines-resource.component.js.map +1 -0
- package/dist/module.d.ts +16 -15
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +7 -0
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -1
- package/dist/routines-dashboards.module.d.ts +17 -0
- package/dist/routines-dashboards.module.d.ts.map +1 -0
- package/dist/routines-dashboards.module.js +65 -0
- package/dist/routines-dashboards.module.js.map +1 -0
- package/package.json +63 -58
|
@@ -4,7 +4,8 @@ import type { UserInfo } from '@memberjunction/core';
|
|
|
4
4
|
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
5
5
|
import type { MJConversationEntity, MJTaskEntity } from '@memberjunction/core-entities';
|
|
6
6
|
import type { AppContextSnapshot } from '@memberjunction/ai-core-plus';
|
|
7
|
-
import type { NavigationRequest
|
|
7
|
+
import type { NavigationRequest } from '@memberjunction/ng-conversations';
|
|
8
|
+
import type { PendingAttachment } from '@memberjunction/ng-composer';
|
|
8
9
|
import { ComponentStudioStateService } from '../../services/component-studio-state.service';
|
|
9
10
|
import * as i0 from "@angular/core";
|
|
10
11
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-assistant-panel.component.d.ts","sourceRoot":"","sources":["../../../../src/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,SAAS,EACT,MAAM,EAET,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAY,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGrE,OAAO,KAAK,EACR,oBAAoB,EACpB,YAAY,EACf,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ai-assistant-panel.component.d.ts","sourceRoot":"","sources":["../../../../src/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -301,5 +301,5 @@ export class AIAssistantPanelComponent extends BaseAngularComponent {
|
|
|
301
301
|
type: Component,
|
|
302
302
|
args: [{ standalone: false, selector: 'mj-ai-assistant-panel', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ai-assistant-panel\">\n <!-- Header: title + collapse. Style + classes match the prior bespoke\n chat so the panel chrome lines up with the rest of the cockpit. -->\n <div class=\"panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-robot\"></i>\n <span>AI Assistant</span>\n </div>\n <button class=\"collapse-btn\" (click)=\"OnCollapsePanel()\" title=\"Collapse panel\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n\n <!-- Quick Actions: clicking a button stuffs the canned prompt into\n `PendingMessage`, which the chat-area below picks up on its next\n render cycle and sends as if the user typed it. Same mechanism the\n SendErrorToAI handler uses. \"Fix Errors\" disables until an error\n has actually been observed in the runtime preview. -->\n <div class=\"quick-actions\">\n @for (action of QuickActions; track action.Label) {\n <button\n class=\"quick-action-btn\"\n [class.disabled]=\"!IsQuickActionEnabled(action)\"\n [disabled]=\"!IsQuickActionEnabled(action)\"\n (click)=\"OnQuickAction(action)\"\n [title]=\"action.Label\">\n <i class=\"fa-solid {{ action.Icon }}\"></i>\n <span>{{ action.Label }}</span>\n </button>\n }\n </div>\n\n <!-- Embedded chat-area \u2014 same primitive the main Chat app and the Form\n Builder cockpit use. Conversations here are scoped to the\n Component Studio app so they don't pollute main chat; the default\n agent is Codesmith (resolved at init from the AIEngineBase cache);\n and the conversation-header agent picker stays enabled so the user\n can switch on the fly. -->\n <div class=\"chat-host\">\n @if (CurrentUser) {\n <mj-conversation-chat-area\n [Provider]=\"Provider\"\n [environmentId]=\"EnvironmentId\"\n [currentUser]=\"CurrentUser\"\n [conversationId]=\"ChatConversationId\"\n [conversation]=\"ChatConversation\"\n [isNewConversation]=\"ChatIsNewConversation\"\n [pendingMessage]=\"PendingMessage\"\n [pendingAttachments]=\"PendingAttachments\"\n [threadId]=\"ChatThreadId\"\n [pendingArtifactId]=\"ChatPendingArtifactId\"\n [pendingArtifactVersionNumber]=\"ChatPendingArtifactVersionNumber\"\n [overlayMode]=\"true\"\n [showExportButton]=\"false\"\n [showShareButton]=\"false\"\n [showArtifactIndicator]=\"false\"\n [appContext]=\"$any(ChatAppContext)\"\n [defaultAgentId]=\"CodesmithAgentId\"\n [applicationScope]=\"'Application'\"\n [applicationId]=\"CockpitApplicationId\"\n [linkedEntityId]=\"ComponentsEntityID\"\n [linkedRecordId]=\"LinkedComponentID\"\n [emptyStateGreeting]=\"'How can I help with this component?'\"\n (conversationCreated)=\"OnConversationCreated($event)\"\n (pendingMessageConsumed)=\"OnPendingMessageConsumed()\"\n (openEntityRecord)=\"OnOpenEntityRecord($event)\"\n (navigationRequest)=\"OnNavigationRequest($event)\"\n (taskClicked)=\"OnTaskClicked($event)\"\n (artifactLinkClicked)=\"OnArtifactLinkClicked($event)\"\n (conversationRenamed)=\"OnConversationRenamed($event)\"\n (threadOpened)=\"OnThreadOpened($event)\"\n (threadClosed)=\"OnThreadClosed()\"\n (pendingArtifactConsumed)=\"OnPendingArtifactConsumed()\">\n </mj-conversation-chat-area>\n } @else {\n <div class=\"chat-host__empty\">Loading\u2026</div>\n }\n </div>\n</div>\n", styles: [":host {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.ai-assistant-panel {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface);\n overflow: hidden;\n}\n\n/* ============================================================ */\n/* HEADER */\n/* ============================================================ */\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n}\n\n.panel-header .header-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.panel-header .header-title i {\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.panel-header .collapse-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n border-radius: 4px;\n cursor: pointer;\n transition: background 0.15s, color 0.15s;\n}\n\n.panel-header .collapse-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n/* ============================================================ */\n/* QUICK ACTIONS */\n/* ============================================================ */\n\n.quick-actions {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 10px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.quick-action-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border-radius: 4px;\n font-size: 12px;\n cursor: pointer;\n transition: background 0.15s, border-color 0.15s;\n}\n\n.quick-action-btn i {\n color: var(--mj-brand-primary);\n font-size: 11px;\n}\n\n.quick-action-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n}\n\n.quick-action-btn:disabled,\n.quick-action-btn.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* ============================================================ */\n/* CHAT HOST */\n/* ============================================================ */\n\n.chat-host {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.chat-host mj-conversation-chat-area {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.chat-host__empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n"] }]
|
|
303
303
|
}], () => [{ type: i1.ComponentStudioStateService }], null); })();
|
|
304
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAssistantPanelComponent, { className: "AIAssistantPanelComponent", filePath: "src/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.ts", lineNumber:
|
|
304
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAssistantPanelComponent, { className: "AIAssistantPanelComponent", filePath: "src/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.ts", lineNumber: 72 }); })();
|
|
305
305
|
//# sourceMappingURL=ai-assistant-panel.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-assistant-panel.component.js","sourceRoot":"","sources":["../../../../src/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.ts","../../../../src/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n OnDestroy,\n OnInit,\n inject,\n} from '@angular/core';\nimport { CompositeKey, LogError } from '@memberjunction/core';\nimport type { UserInfo } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { Subject, Subscription, takeUntil } from 'rxjs';\nimport { MJEnvironmentEntityExtended } from '@memberjunction/core-entities';\nimport type {\n MJConversationEntity,\n MJTaskEntity,\n} from '@memberjunction/core-entities';\nimport type { AppContextSnapshot } from '@memberjunction/ai-core-plus';\nimport { NavigationService } from '@memberjunction/ng-shared';\nimport type { NavigationRequest, PendingAttachment } from '@memberjunction/ng-conversations';\nimport { ComponentStudioStateService, ComponentError } from '../../services/component-studio-state.service';\n\n/**\n * Quick-action shortcut surfaced above the embedded chat. Clicking a\n * shortcut prefills the chat input via the pendingMessage handoff — the\n * same mechanism the empty-state uses to send the first message.\n */\ninterface QuickAction {\n Label: string;\n Icon: string;\n Prompt: string;\n /** When true, the button is disabled unless `state.CurrentError` is set. */\n RequiresError: boolean;\n}\n\n/**\n * Component Studio's right-pane AI assistant.\n *\n * Previously this was a 880-line bespoke chat stub that emitted \"AI\n * assistant coming soon\" — no agent was actually called. This version\n * thin-wraps `<mj-conversation-chat-area>` (the same primitive the main\n * Chat app and the Form Builder cockpit use) so the assistant becomes\n * fully functional with zero duplicated chat plumbing.\n *\n * Domain integration preserved from the old stub:\n * - **Quick-actions bar** (Fix Errors / Improve / Generate / Explain)\n * above the chat — clicking sets `PendingMessage` which the chat-area\n * consumes on the next render, mirroring the empty-state handoff.\n * - **`SendErrorToAI` channel** — when the runtime preview throws, the\n * state service emits a `ComponentError`. We listen and shove a\n * \"Fix this error: …\" message into the same pendingMessage pipe so\n * the user doesn't have to copy/paste error text.\n *\n * Scoping:\n * - `[applicationScope]=\"'Application'\"` + Component Studio app ID →\n * conversations stay out of main chat (per the migration scoping work).\n * - `[defaultAgentId]` → Codesmith Agent so messages route to the code\n * specialist instead of Sage by default. User can still @mention any\n * agent, override via the per-conversation pin, or pick a different\n * agent through the chat header's picker.\n */\n@Component({\n standalone: false,\n selector: 'mj-ai-assistant-panel',\n templateUrl: './ai-assistant-panel.component.html',\n styleUrls: ['./ai-assistant-panel.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AIAssistantPanelComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n\n /** Quick actions surfaced as buttons above the embedded chat. */\n public QuickActions: QuickAction[] = [\n { Label: 'Fix Errors', Icon: 'fa-bug', Prompt: 'Fix this error: ', RequiresError: true },\n { Label: 'Improve Code', Icon: 'fa-magic', Prompt: 'Review and improve the current component code. Suggest optimizations, better patterns, and cleaner structure.', RequiresError: false },\n { Label: 'Generate Code', Icon: 'fa-code', Prompt: 'Generate code for the current component based on its specification.', RequiresError: false },\n { Label: 'Explain', Icon: 'fa-question-circle', Prompt: 'Explain what the current component does, including its structure, data flow, and key behaviors.', RequiresError: false },\n ];\n\n /** Embedded chat state — same shape the Form Builder cockpit uses. */\n public ChatConversation: MJConversationEntity | null = null;\n public ChatConversationId: string | null = null;\n public ChatIsNewConversation = true;\n public PendingMessage: string | null = null;\n public PendingAttachments: PendingAttachment[] | null = null;\n public ChatThreadId: string | null = null;\n public ChatPendingArtifactId: string | null = null;\n public ChatPendingArtifactVersionNumber: number | null = null;\n\n /** Snapshot from NavigationService — drives the agent's app context. */\n public ChatAppContext: AppContextSnapshot | null = null;\n\n /** Codesmith Agent ID resolved from AIEngineBase cache (no RunView). */\n public CodesmithAgentId: string | null = null;\n\n /** Component Studio's Application ID — resolved from Metadata cache. */\n public CockpitApplicationId: string | null = null;\n\n /**\n * EntityID for `MJ: Components`. Stamped on every conversation\n * created from this panel as the `LinkedEntityID`, paired with the\n * currently-selected Component's ID. Enables \"show prior conversations\n * about THIS component\" later. In-memory Metadata lookup; no RunView.\n */\n public ComponentsEntityID: string | null = null;\n\n /**\n * The DB-backed Component ID currently selected — null when the\n * panel has nothing selected, or when the selection is a\n * file-loaded (transient) component that has no persistent DB row\n * to link conversations to. Used as `[linkedRecordId]` on the\n * embedded chat-area. Pairs with {@link ComponentsEntityID}.\n */\n public get LinkedComponentID(): string | null {\n const sel = this.State.SelectedComponent;\n if (!sel) return null;\n // FileLoadedComponent has `isFileLoaded === true` and a lower-case\n // `id`; DbComponentSummary has the canonical `ID`. Discriminate by\n // the flag rather than property presence to keep TS happy.\n if ('isFileLoaded' in sel && sel.isFileLoaded === true) return null;\n return (sel as { ID: string }).ID ?? null;\n }\n\n private static readonly CODESMITH_AGENT_NAME = 'Codesmith Agent';\n private static readonly COCKPIT_APP_NAME = 'Component Studio';\n\n private readonly destroy$ = new Subject<void>();\n private appContextSubscription: Subscription | null = null;\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly navigationService = inject(NavigationService);\n\n constructor(public State: ComponentStudioStateService) {\n super();\n }\n\n public get EnvironmentId(): string {\n return MJEnvironmentEntityExtended.DefaultEnvironmentID;\n }\n\n public get CurrentUser(): UserInfo | null {\n return this.ProviderToUse?.CurrentUser ?? null;\n }\n\n public async ngOnInit(): Promise<void> {\n try {\n // Resolve default agent + cockpit app ID from in-memory caches\n // (no RunView round-trips). Both fall back to null cleanly:\n // missing agent → routes through Sage; missing app → safety\n // guard in chat-area demotes scope to 'Global'.\n await AIEngineBase.Instance.Config(false);\n const codesmith = AIEngineBase.Instance.Agents\n ?.find(a => a.Name?.trim().toLowerCase() === AIAssistantPanelComponent.CODESMITH_AGENT_NAME.toLowerCase());\n this.CodesmithAgentId = codesmith?.ID ?? null;\n if (!codesmith) {\n LogError(`AIAssistantPanel: '${AIAssistantPanelComponent.CODESMITH_AGENT_NAME}' not found in AIEngineBase cache`);\n }\n\n const md = this.ProviderToUse;\n const app = md.Applications?.find(\n a => a.Name?.trim().toLowerCase() === AIAssistantPanelComponent.COCKPIT_APP_NAME.toLowerCase()\n );\n this.CockpitApplicationId = app?.ID ?? null;\n // Resolve MJ: Components entity ID for conversation linkage.\n const componentsEntity = md.EntityByName?.('MJ: Components');\n if (!componentsEntity) {\n LogError(`AIAssistantPanel: Entity 'MJ: Components' not found in Metadata cache — conversation linkage will be skipped.`);\n }\n this.ComponentsEntityID = componentsEntity?.ID ?? null;\n\n // Subscribe to the Explorer shell's app-context publisher so\n // the agent sees the same snapshot the floating overlay sees.\n this.appContextSubscription = this.navigationService.AppContextSnapshot$\n .subscribe(snapshot => {\n this.ChatAppContext = snapshot;\n this.cdr.markForCheck();\n });\n\n // Wire the SendErrorToAI channel — when the runtime preview\n // hits an error, push a canned \"Fix this error: …\" message\n // into the chat-area's pendingMessage pipe so the user\n // doesn't have to manually copy the error text.\n this.State.SendErrorToAI\n .pipe(takeUntil(this.destroy$))\n .subscribe(err => this.handleIncomingError(err));\n this.cdr.markForCheck();\n } catch (err) {\n LogError(`AIAssistantPanel.ngOnInit: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n public ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n this.appContextSubscription?.unsubscribe();\n this.appContextSubscription = null;\n }\n\n /** Collapse the right pane (delegated to the parent dashboard). */\n public OnCollapsePanel(): void {\n this.State.IsAIPanelCollapsed = true;\n this.State.StateChanged.emit();\n }\n\n /** Quick-action click — prefill the chat with the canned prompt. */\n public OnQuickAction(action: QuickAction): void {\n if (action.RequiresError && !this.State.CurrentError) return;\n let prompt = action.Prompt;\n if (action.RequiresError && this.State.CurrentError) {\n prompt += `${this.State.CurrentError.type} - ${this.State.CurrentError.message}`;\n }\n this.PendingMessage = prompt;\n this.PendingAttachments = null;\n this.cdr.markForCheck();\n }\n\n public IsQuickActionEnabled(action: QuickAction): boolean {\n return !action.RequiresError || this.State.CurrentError != null;\n }\n\n /** Runtime preview surfaced an error — auto-send \"Fix this error: …\". */\n private handleIncomingError(error: ComponentError): void {\n const details = error.technicalDetails\n ? (typeof error.technicalDetails === 'string'\n ? error.technicalDetails\n : JSON.stringify(error.technicalDetails, null, 2))\n : '';\n this.PendingMessage = `Fix this error: ${error.type} - ${error.message}${details ? '\\n\\nDetails:\\n' + details : ''}`;\n this.PendingAttachments = null;\n this.cdr.markForCheck();\n }\n\n // ── chat-area event wiring ───────────────────────────────────────\n\n public OnConversationCreated(event: {\n conversation: MJConversationEntity;\n pendingMessage?: string;\n pendingAttachments?: PendingAttachment[];\n }): void {\n this.PendingMessage = event.pendingMessage ?? null;\n this.PendingAttachments = (event.pendingAttachments ?? null) as PendingAttachment[] | null;\n this.ChatConversation = event.conversation;\n this.ChatConversationId = event.conversation.ID;\n this.ChatIsNewConversation = false;\n this.cdr.markForCheck();\n }\n\n public OnPendingMessageConsumed(): void {\n this.PendingMessage = null;\n this.PendingAttachments = null;\n this.cdr.markForCheck();\n }\n\n public OnOpenEntityRecord(event: { entityName: string; compositeKey: CompositeKey }): void {\n try {\n this.navigationService.OpenEntityRecord(event.entityName, event.compositeKey);\n } catch (err) {\n LogError(`AIAssistantPanel.OnOpenEntityRecord: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n public OnNavigationRequest(event: NavigationRequest): void {\n void this.navigationService.OpenNavItemByName(event.navItemName, event.params, event.appId);\n }\n\n public OnTaskClicked(task: MJTaskEntity): void {\n try {\n const key = CompositeKey.FromID(task.ID);\n this.navigationService.OpenEntityRecord('MJ: Tasks', key);\n } catch (err) {\n LogError(`AIAssistantPanel.OnTaskClicked: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n public OnArtifactLinkClicked(event: { type: 'conversation' | 'collection'; id: string }): void {\n const navItemName = event.type === 'conversation' ? 'Conversations' : 'Collections';\n const paramKey = event.type === 'conversation' ? 'conversationId' : 'collectionId';\n void this.navigationService.OpenNavItemByName(navItemName, { [paramKey]: event.id });\n }\n\n public OnConversationRenamed(event: { conversationId: string; name: string; description: string }): void {\n if (this.ChatConversation && UUIDsEqual(this.ChatConversation.ID, event.conversationId)) {\n this.ChatConversation.Name = event.name;\n if (event.description !== undefined) {\n this.ChatConversation.Description = event.description;\n }\n this.cdr.markForCheck();\n }\n }\n\n public OnThreadOpened(threadId: string): void {\n this.ChatThreadId = threadId;\n this.cdr.markForCheck();\n }\n\n public OnThreadClosed(): void {\n this.ChatThreadId = null;\n this.cdr.markForCheck();\n }\n\n public OnPendingArtifactConsumed(): void {\n this.ChatPendingArtifactId = null;\n this.ChatPendingArtifactVersionNumber = null;\n this.cdr.markForCheck();\n }\n}\n","<div class=\"ai-assistant-panel\">\n <!-- Header: title + collapse. Style + classes match the prior bespoke\n chat so the panel chrome lines up with the rest of the cockpit. -->\n <div class=\"panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-robot\"></i>\n <span>AI Assistant</span>\n </div>\n <button class=\"collapse-btn\" (click)=\"OnCollapsePanel()\" title=\"Collapse panel\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n\n <!-- Quick Actions: clicking a button stuffs the canned prompt into\n `PendingMessage`, which the chat-area below picks up on its next\n render cycle and sends as if the user typed it. Same mechanism the\n SendErrorToAI handler uses. \"Fix Errors\" disables until an error\n has actually been observed in the runtime preview. -->\n <div class=\"quick-actions\">\n @for (action of QuickActions; track action.Label) {\n <button\n class=\"quick-action-btn\"\n [class.disabled]=\"!IsQuickActionEnabled(action)\"\n [disabled]=\"!IsQuickActionEnabled(action)\"\n (click)=\"OnQuickAction(action)\"\n [title]=\"action.Label\">\n <i class=\"fa-solid {{ action.Icon }}\"></i>\n <span>{{ action.Label }}</span>\n </button>\n }\n </div>\n\n <!-- Embedded chat-area — same primitive the main Chat app and the Form\n Builder cockpit use. Conversations here are scoped to the\n Component Studio app so they don't pollute main chat; the default\n agent is Codesmith (resolved at init from the AIEngineBase cache);\n and the conversation-header agent picker stays enabled so the user\n can switch on the fly. -->\n <div class=\"chat-host\">\n @if (CurrentUser) {\n <mj-conversation-chat-area\n [Provider]=\"Provider\"\n [environmentId]=\"EnvironmentId\"\n [currentUser]=\"CurrentUser\"\n [conversationId]=\"ChatConversationId\"\n [conversation]=\"ChatConversation\"\n [isNewConversation]=\"ChatIsNewConversation\"\n [pendingMessage]=\"PendingMessage\"\n [pendingAttachments]=\"PendingAttachments\"\n [threadId]=\"ChatThreadId\"\n [pendingArtifactId]=\"ChatPendingArtifactId\"\n [pendingArtifactVersionNumber]=\"ChatPendingArtifactVersionNumber\"\n [overlayMode]=\"true\"\n [showExportButton]=\"false\"\n [showShareButton]=\"false\"\n [showArtifactIndicator]=\"false\"\n [appContext]=\"$any(ChatAppContext)\"\n [defaultAgentId]=\"CodesmithAgentId\"\n [applicationScope]=\"'Application'\"\n [applicationId]=\"CockpitApplicationId\"\n [linkedEntityId]=\"ComponentsEntityID\"\n [linkedRecordId]=\"LinkedComponentID\"\n [emptyStateGreeting]=\"'How can I help with this component?'\"\n (conversationCreated)=\"OnConversationCreated($event)\"\n (pendingMessageConsumed)=\"OnPendingMessageConsumed()\"\n (openEntityRecord)=\"OnOpenEntityRecord($event)\"\n (navigationRequest)=\"OnNavigationRequest($event)\"\n (taskClicked)=\"OnTaskClicked($event)\"\n (artifactLinkClicked)=\"OnArtifactLinkClicked($event)\"\n (conversationRenamed)=\"OnConversationRenamed($event)\"\n (threadOpened)=\"OnThreadOpened($event)\"\n (threadClosed)=\"OnThreadClosed()\"\n (pendingArtifactConsumed)=\"OnPendingArtifactConsumed()\">\n </mj-conversation-chat-area>\n } @else {\n <div class=\"chat-host__empty\">Loading…</div>\n }\n </div>\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"ai-assistant-panel.component.js","sourceRoot":"","sources":["../../../../src/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.ts","../../../../src/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n OnDestroy,\n OnInit,\n inject,\n} from '@angular/core';\nimport { CompositeKey, LogError } from '@memberjunction/core';\nimport type { UserInfo } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { Subject, Subscription, takeUntil } from 'rxjs';\nimport { MJEnvironmentEntityExtended } from '@memberjunction/core-entities';\nimport type {\n MJConversationEntity,\n MJTaskEntity,\n} from '@memberjunction/core-entities';\nimport type { AppContextSnapshot } from '@memberjunction/ai-core-plus';\nimport { NavigationService } from '@memberjunction/ng-shared';\nimport type { NavigationRequest } from '@memberjunction/ng-conversations';\nimport type { PendingAttachment } from '@memberjunction/ng-composer';\nimport { ComponentStudioStateService, ComponentError } from '../../services/component-studio-state.service';\n\n/**\n * Quick-action shortcut surfaced above the embedded chat. Clicking a\n * shortcut prefills the chat input via the pendingMessage handoff — the\n * same mechanism the empty-state uses to send the first message.\n */\ninterface QuickAction {\n Label: string;\n Icon: string;\n Prompt: string;\n /** When true, the button is disabled unless `state.CurrentError` is set. */\n RequiresError: boolean;\n}\n\n/**\n * Component Studio's right-pane AI assistant.\n *\n * Previously this was a 880-line bespoke chat stub that emitted \"AI\n * assistant coming soon\" — no agent was actually called. This version\n * thin-wraps `<mj-conversation-chat-area>` (the same primitive the main\n * Chat app and the Form Builder cockpit use) so the assistant becomes\n * fully functional with zero duplicated chat plumbing.\n *\n * Domain integration preserved from the old stub:\n * - **Quick-actions bar** (Fix Errors / Improve / Generate / Explain)\n * above the chat — clicking sets `PendingMessage` which the chat-area\n * consumes on the next render, mirroring the empty-state handoff.\n * - **`SendErrorToAI` channel** — when the runtime preview throws, the\n * state service emits a `ComponentError`. We listen and shove a\n * \"Fix this error: …\" message into the same pendingMessage pipe so\n * the user doesn't have to copy/paste error text.\n *\n * Scoping:\n * - `[applicationScope]=\"'Application'\"` + Component Studio app ID →\n * conversations stay out of main chat (per the migration scoping work).\n * - `[defaultAgentId]` → Codesmith Agent so messages route to the code\n * specialist instead of Sage by default. User can still @mention any\n * agent, override via the per-conversation pin, or pick a different\n * agent through the chat header's picker.\n */\n@Component({\n standalone: false,\n selector: 'mj-ai-assistant-panel',\n templateUrl: './ai-assistant-panel.component.html',\n styleUrls: ['./ai-assistant-panel.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AIAssistantPanelComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n\n /** Quick actions surfaced as buttons above the embedded chat. */\n public QuickActions: QuickAction[] = [\n { Label: 'Fix Errors', Icon: 'fa-bug', Prompt: 'Fix this error: ', RequiresError: true },\n { Label: 'Improve Code', Icon: 'fa-magic', Prompt: 'Review and improve the current component code. Suggest optimizations, better patterns, and cleaner structure.', RequiresError: false },\n { Label: 'Generate Code', Icon: 'fa-code', Prompt: 'Generate code for the current component based on its specification.', RequiresError: false },\n { Label: 'Explain', Icon: 'fa-question-circle', Prompt: 'Explain what the current component does, including its structure, data flow, and key behaviors.', RequiresError: false },\n ];\n\n /** Embedded chat state — same shape the Form Builder cockpit uses. */\n public ChatConversation: MJConversationEntity | null = null;\n public ChatConversationId: string | null = null;\n public ChatIsNewConversation = true;\n public PendingMessage: string | null = null;\n public PendingAttachments: PendingAttachment[] | null = null;\n public ChatThreadId: string | null = null;\n public ChatPendingArtifactId: string | null = null;\n public ChatPendingArtifactVersionNumber: number | null = null;\n\n /** Snapshot from NavigationService — drives the agent's app context. */\n public ChatAppContext: AppContextSnapshot | null = null;\n\n /** Codesmith Agent ID resolved from AIEngineBase cache (no RunView). */\n public CodesmithAgentId: string | null = null;\n\n /** Component Studio's Application ID — resolved from Metadata cache. */\n public CockpitApplicationId: string | null = null;\n\n /**\n * EntityID for `MJ: Components`. Stamped on every conversation\n * created from this panel as the `LinkedEntityID`, paired with the\n * currently-selected Component's ID. Enables \"show prior conversations\n * about THIS component\" later. In-memory Metadata lookup; no RunView.\n */\n public ComponentsEntityID: string | null = null;\n\n /**\n * The DB-backed Component ID currently selected — null when the\n * panel has nothing selected, or when the selection is a\n * file-loaded (transient) component that has no persistent DB row\n * to link conversations to. Used as `[linkedRecordId]` on the\n * embedded chat-area. Pairs with {@link ComponentsEntityID}.\n */\n public get LinkedComponentID(): string | null {\n const sel = this.State.SelectedComponent;\n if (!sel) return null;\n // FileLoadedComponent has `isFileLoaded === true` and a lower-case\n // `id`; DbComponentSummary has the canonical `ID`. Discriminate by\n // the flag rather than property presence to keep TS happy.\n if ('isFileLoaded' in sel && sel.isFileLoaded === true) return null;\n return (sel as { ID: string }).ID ?? null;\n }\n\n private static readonly CODESMITH_AGENT_NAME = 'Codesmith Agent';\n private static readonly COCKPIT_APP_NAME = 'Component Studio';\n\n private readonly destroy$ = new Subject<void>();\n private appContextSubscription: Subscription | null = null;\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly navigationService = inject(NavigationService);\n\n constructor(public State: ComponentStudioStateService) {\n super();\n }\n\n public get EnvironmentId(): string {\n return MJEnvironmentEntityExtended.DefaultEnvironmentID;\n }\n\n public get CurrentUser(): UserInfo | null {\n return this.ProviderToUse?.CurrentUser ?? null;\n }\n\n public async ngOnInit(): Promise<void> {\n try {\n // Resolve default agent + cockpit app ID from in-memory caches\n // (no RunView round-trips). Both fall back to null cleanly:\n // missing agent → routes through Sage; missing app → safety\n // guard in chat-area demotes scope to 'Global'.\n await AIEngineBase.Instance.Config(false);\n const codesmith = AIEngineBase.Instance.Agents\n ?.find(a => a.Name?.trim().toLowerCase() === AIAssistantPanelComponent.CODESMITH_AGENT_NAME.toLowerCase());\n this.CodesmithAgentId = codesmith?.ID ?? null;\n if (!codesmith) {\n LogError(`AIAssistantPanel: '${AIAssistantPanelComponent.CODESMITH_AGENT_NAME}' not found in AIEngineBase cache`);\n }\n\n const md = this.ProviderToUse;\n const app = md.Applications?.find(\n a => a.Name?.trim().toLowerCase() === AIAssistantPanelComponent.COCKPIT_APP_NAME.toLowerCase()\n );\n this.CockpitApplicationId = app?.ID ?? null;\n // Resolve MJ: Components entity ID for conversation linkage.\n const componentsEntity = md.EntityByName?.('MJ: Components');\n if (!componentsEntity) {\n LogError(`AIAssistantPanel: Entity 'MJ: Components' not found in Metadata cache — conversation linkage will be skipped.`);\n }\n this.ComponentsEntityID = componentsEntity?.ID ?? null;\n\n // Subscribe to the Explorer shell's app-context publisher so\n // the agent sees the same snapshot the floating overlay sees.\n this.appContextSubscription = this.navigationService.AppContextSnapshot$\n .subscribe(snapshot => {\n this.ChatAppContext = snapshot;\n this.cdr.markForCheck();\n });\n\n // Wire the SendErrorToAI channel — when the runtime preview\n // hits an error, push a canned \"Fix this error: …\" message\n // into the chat-area's pendingMessage pipe so the user\n // doesn't have to manually copy the error text.\n this.State.SendErrorToAI\n .pipe(takeUntil(this.destroy$))\n .subscribe(err => this.handleIncomingError(err));\n this.cdr.markForCheck();\n } catch (err) {\n LogError(`AIAssistantPanel.ngOnInit: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n public ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n this.appContextSubscription?.unsubscribe();\n this.appContextSubscription = null;\n }\n\n /** Collapse the right pane (delegated to the parent dashboard). */\n public OnCollapsePanel(): void {\n this.State.IsAIPanelCollapsed = true;\n this.State.StateChanged.emit();\n }\n\n /** Quick-action click — prefill the chat with the canned prompt. */\n public OnQuickAction(action: QuickAction): void {\n if (action.RequiresError && !this.State.CurrentError) return;\n let prompt = action.Prompt;\n if (action.RequiresError && this.State.CurrentError) {\n prompt += `${this.State.CurrentError.type} - ${this.State.CurrentError.message}`;\n }\n this.PendingMessage = prompt;\n this.PendingAttachments = null;\n this.cdr.markForCheck();\n }\n\n public IsQuickActionEnabled(action: QuickAction): boolean {\n return !action.RequiresError || this.State.CurrentError != null;\n }\n\n /** Runtime preview surfaced an error — auto-send \"Fix this error: …\". */\n private handleIncomingError(error: ComponentError): void {\n const details = error.technicalDetails\n ? (typeof error.technicalDetails === 'string'\n ? error.technicalDetails\n : JSON.stringify(error.technicalDetails, null, 2))\n : '';\n this.PendingMessage = `Fix this error: ${error.type} - ${error.message}${details ? '\\n\\nDetails:\\n' + details : ''}`;\n this.PendingAttachments = null;\n this.cdr.markForCheck();\n }\n\n // ── chat-area event wiring ───────────────────────────────────────\n\n public OnConversationCreated(event: {\n conversation: MJConversationEntity;\n pendingMessage?: string;\n pendingAttachments?: PendingAttachment[];\n }): void {\n this.PendingMessage = event.pendingMessage ?? null;\n this.PendingAttachments = (event.pendingAttachments ?? null) as PendingAttachment[] | null;\n this.ChatConversation = event.conversation;\n this.ChatConversationId = event.conversation.ID;\n this.ChatIsNewConversation = false;\n this.cdr.markForCheck();\n }\n\n public OnPendingMessageConsumed(): void {\n this.PendingMessage = null;\n this.PendingAttachments = null;\n this.cdr.markForCheck();\n }\n\n public OnOpenEntityRecord(event: { entityName: string; compositeKey: CompositeKey }): void {\n try {\n this.navigationService.OpenEntityRecord(event.entityName, event.compositeKey);\n } catch (err) {\n LogError(`AIAssistantPanel.OnOpenEntityRecord: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n public OnNavigationRequest(event: NavigationRequest): void {\n void this.navigationService.OpenNavItemByName(event.navItemName, event.params, event.appId);\n }\n\n public OnTaskClicked(task: MJTaskEntity): void {\n try {\n const key = CompositeKey.FromID(task.ID);\n this.navigationService.OpenEntityRecord('MJ: Tasks', key);\n } catch (err) {\n LogError(`AIAssistantPanel.OnTaskClicked: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n public OnArtifactLinkClicked(event: { type: 'conversation' | 'collection'; id: string }): void {\n const navItemName = event.type === 'conversation' ? 'Conversations' : 'Collections';\n const paramKey = event.type === 'conversation' ? 'conversationId' : 'collectionId';\n void this.navigationService.OpenNavItemByName(navItemName, { [paramKey]: event.id });\n }\n\n public OnConversationRenamed(event: { conversationId: string; name: string; description: string }): void {\n if (this.ChatConversation && UUIDsEqual(this.ChatConversation.ID, event.conversationId)) {\n this.ChatConversation.Name = event.name;\n if (event.description !== undefined) {\n this.ChatConversation.Description = event.description;\n }\n this.cdr.markForCheck();\n }\n }\n\n public OnThreadOpened(threadId: string): void {\n this.ChatThreadId = threadId;\n this.cdr.markForCheck();\n }\n\n public OnThreadClosed(): void {\n this.ChatThreadId = null;\n this.cdr.markForCheck();\n }\n\n public OnPendingArtifactConsumed(): void {\n this.ChatPendingArtifactId = null;\n this.ChatPendingArtifactVersionNumber = null;\n this.cdr.markForCheck();\n }\n}\n","<div class=\"ai-assistant-panel\">\n <!-- Header: title + collapse. Style + classes match the prior bespoke\n chat so the panel chrome lines up with the rest of the cockpit. -->\n <div class=\"panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-robot\"></i>\n <span>AI Assistant</span>\n </div>\n <button class=\"collapse-btn\" (click)=\"OnCollapsePanel()\" title=\"Collapse panel\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n\n <!-- Quick Actions: clicking a button stuffs the canned prompt into\n `PendingMessage`, which the chat-area below picks up on its next\n render cycle and sends as if the user typed it. Same mechanism the\n SendErrorToAI handler uses. \"Fix Errors\" disables until an error\n has actually been observed in the runtime preview. -->\n <div class=\"quick-actions\">\n @for (action of QuickActions; track action.Label) {\n <button\n class=\"quick-action-btn\"\n [class.disabled]=\"!IsQuickActionEnabled(action)\"\n [disabled]=\"!IsQuickActionEnabled(action)\"\n (click)=\"OnQuickAction(action)\"\n [title]=\"action.Label\">\n <i class=\"fa-solid {{ action.Icon }}\"></i>\n <span>{{ action.Label }}</span>\n </button>\n }\n </div>\n\n <!-- Embedded chat-area — same primitive the main Chat app and the Form\n Builder cockpit use. Conversations here are scoped to the\n Component Studio app so they don't pollute main chat; the default\n agent is Codesmith (resolved at init from the AIEngineBase cache);\n and the conversation-header agent picker stays enabled so the user\n can switch on the fly. -->\n <div class=\"chat-host\">\n @if (CurrentUser) {\n <mj-conversation-chat-area\n [Provider]=\"Provider\"\n [environmentId]=\"EnvironmentId\"\n [currentUser]=\"CurrentUser\"\n [conversationId]=\"ChatConversationId\"\n [conversation]=\"ChatConversation\"\n [isNewConversation]=\"ChatIsNewConversation\"\n [pendingMessage]=\"PendingMessage\"\n [pendingAttachments]=\"PendingAttachments\"\n [threadId]=\"ChatThreadId\"\n [pendingArtifactId]=\"ChatPendingArtifactId\"\n [pendingArtifactVersionNumber]=\"ChatPendingArtifactVersionNumber\"\n [overlayMode]=\"true\"\n [showExportButton]=\"false\"\n [showShareButton]=\"false\"\n [showArtifactIndicator]=\"false\"\n [appContext]=\"$any(ChatAppContext)\"\n [defaultAgentId]=\"CodesmithAgentId\"\n [applicationScope]=\"'Application'\"\n [applicationId]=\"CockpitApplicationId\"\n [linkedEntityId]=\"ComponentsEntityID\"\n [linkedRecordId]=\"LinkedComponentID\"\n [emptyStateGreeting]=\"'How can I help with this component?'\"\n (conversationCreated)=\"OnConversationCreated($event)\"\n (pendingMessageConsumed)=\"OnPendingMessageConsumed()\"\n (openEntityRecord)=\"OnOpenEntityRecord($event)\"\n (navigationRequest)=\"OnNavigationRequest($event)\"\n (taskClicked)=\"OnTaskClicked($event)\"\n (artifactLinkClicked)=\"OnArtifactLinkClicked($event)\"\n (conversationRenamed)=\"OnConversationRenamed($event)\"\n (threadOpened)=\"OnThreadOpened($event)\"\n (threadClosed)=\"OnThreadClosed()\"\n (pendingArtifactConsumed)=\"OnPendingArtifactConsumed()\">\n </mj-conversation-chat-area>\n } @else {\n <div class=\"chat-host__empty\">Loading…</div>\n }\n </div>\n</div>\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-selection-dialog.component.d.ts","sourceRoot":"","sources":["../../../src/ComponentStudio/components/artifact-selection-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAiB,YAAY,EAA6B,MAAM,eAAe,CAAC;AAErH,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"artifact-selection-dialog.component.d.ts","sourceRoot":"","sources":["../../../src/ComponentStudio/components/artifact-selection-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAiB,YAAY,EAA6B,MAAM,eAAe,CAAC;AAErH,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAM1F,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAErE,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,aAAa,GAAG,gBAAgB,CAAC;IACzC,eAAe,CAAC,EAAE,uBAAuB,CAAC;CAC3C;AAED,qBAMa,gCAAiC,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAC5F,OAAO,UAAS;IACf,KAAK,oDAA2D;IAG1E,SAAS,EAAE,gBAAgB,EAAE,CAAM;IACnC,gBAAgB,EAAE,uBAAuB,EAAE,CAAM;IAGjD,WAAW,SAAK;IAChB,QAAQ,SAAM;IACd,cAAc,SAAK;IACnB,YAAY,UAAS;IAGrB,SAAS,UAAQ;IACjB,UAAU,SAAM;IAChB,SAAS,SAAM;IACf,oBAAoB,SAAM;IAC1B,mBAAmB,UAAS;IAC5B,sBAAsB,UAAS;IAI/B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IACjD,eAAe,EAAE,uBAAuB,GAAG,IAAI,CAAQ;IACvD,aAAa,EAAE,KAAK,GAAG,QAAQ,CAAS;IAGxC,eAAe,SAAM;IACrB,sBAAsB,SAAM;IAE5B,OAAO,KAAK,QAAQ,GAAiC;IACrD,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,aAAa,CAAyB;IAE9C,OAAO,CAAC,mBAAmB,CAAiC;IAC5D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,GAAG,CAA6B;IAElC,QAAQ;IAad,WAAW;IAKL,aAAa;IAmCnB,OAAO,CAAC,eAAe,CAAgC;IAC1C,eAAe;IA+B5B,eAAe;IAMT,cAAc,CAAC,QAAQ,EAAE,gBAAgB;IAWzC,YAAY,CAAC,UAAU,EAAE,MAAM;IAqBrC,oBAAoB,IAAI,MAAM;IAMxB,QAAQ;IAOR,YAAY;IAOlB,SAAS,IAAI,OAAO;IAIpB,aAAa,IAAI,OAAO;IAIxB,aAAa,IAAI,MAAM;IAIvB,iBAAiB;IAIjB,aAAa;IAIb,oBAAoB;IAQpB,oBAAoB,IAAI,MAAM;IAQ9B,OAAO,IAAI,OAAO;IAclB,iBAAiB,IAAI,MAAM;IAY3B,MAAM;IAIA,IAAI;YAkCI,iBAAiB;IAqD/B,0FAA0F;IAC1F,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO;IAIvD,uFAAuF;IACvF,iBAAiB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO;yCAvVjD,gCAAgC;2CAAhC,gCAAgC;CA0V5C"}
|
|
@@ -4,6 +4,7 @@ import { UUIDsEqual } from '@memberjunction/global';
|
|
|
4
4
|
import { Subject, debounceTime, distinctUntilChanged } from 'rxjs';
|
|
5
5
|
import { takeUntil } from 'rxjs/operators';
|
|
6
6
|
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
7
|
+
import { MJConfirmService } from '@memberjunction/ng-ui-components';
|
|
7
8
|
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
8
9
|
import * as i0 from "@angular/core";
|
|
9
10
|
import * as i1 from "@angular/forms";
|
|
@@ -270,6 +271,7 @@ export class ArtifactSelectionDialogComponent extends BaseAngularComponent {
|
|
|
270
271
|
destroy$ = new Subject();
|
|
271
272
|
searchSubject = new Subject();
|
|
272
273
|
notificationService = inject(MJNotificationService);
|
|
274
|
+
confirmService = inject(MJConfirmService);
|
|
273
275
|
cdr = inject(ChangeDetectorRef);
|
|
274
276
|
async ngOnInit() {
|
|
275
277
|
// Setup search debouncing
|
|
@@ -471,8 +473,8 @@ export class ArtifactSelectionDialogComponent extends BaseAngularComponent {
|
|
|
471
473
|
};
|
|
472
474
|
// If updating, show confirmation
|
|
473
475
|
if (this.versionAction === 'update') {
|
|
474
|
-
const
|
|
475
|
-
if (!
|
|
476
|
+
const confirmed = await this.confirmService.Confirm({ title: 'Overwrite version', message: `Overwrite version ${this.selectedVersion.VersionNumber}?`, detail: 'This action cannot be undone.' });
|
|
477
|
+
if (!confirmed)
|
|
476
478
|
return;
|
|
477
479
|
}
|
|
478
480
|
this.Close.emit(result);
|
|
@@ -613,5 +615,5 @@ export class ArtifactSelectionDialogComponent extends BaseAngularComponent {
|
|
|
613
615
|
}], Close: [{
|
|
614
616
|
type: Output
|
|
615
617
|
}] }); })();
|
|
616
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactSelectionDialogComponent, { className: "ArtifactSelectionDialogComponent", filePath: "src/ComponentStudio/components/artifact-selection-dialog.component.ts", lineNumber:
|
|
618
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactSelectionDialogComponent, { className: "ArtifactSelectionDialogComponent", filePath: "src/ComponentStudio/components/artifact-selection-dialog.component.ts", lineNumber: 23 }); })();
|
|
617
619
|
//# sourceMappingURL=artifact-selection-dialog.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-selection-dialog.component.js","sourceRoot":"","sources":["../../../src/ComponentStudio/components/artifact-selection-dialog.component.ts","../../../src/ComponentStudio/components/artifact-selection-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, ChangeDetectorRef, inject } from '@angular/core';\nimport { RunView, UserInfo } from '@memberjunction/core';\nimport { MJArtifactEntity, MJArtifactVersionEntity } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { Subject, debounceTime, distinctUntilChanged } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\nexport interface ArtifactSelectionResult {\n artifact: MJArtifactEntity;\n action: 'new-version' | 'update-version';\n versionToUpdate?: MJArtifactVersionEntity;\n}\n\n@Component({\n standalone: false,\n selector: 'app-artifact-selection-dialog',\n templateUrl: './artifact-selection-dialog.component.html',\n styleUrl: './artifact-selection-dialog.component.css'\n})\nexport class ArtifactSelectionDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n @Input() Visible = false;\n @Output() Close = new EventEmitter<ArtifactSelectionResult | undefined>();\n\n // Data\n artifacts: MJArtifactEntity[] = [];\n artifactVersions: MJArtifactVersionEntity[] = [];\n\n // Paging State\n currentPage = 0;\n pageSize = 25;\n totalArtifacts = 0;\n hasMorePages = false;\n\n // UI State\n isLoading = true;\n searchTerm = '';\n userEmail = '';\n selectedArtifactType = '';\n showNewArtifactForm = false;\n isFilterPanelCollapsed = false;\n\n\n // Selection State\n selectedArtifact: MJArtifactEntity | null = null;\n selectedVersion: MJArtifactVersionEntity | null = null;\n versionAction: 'new' | 'update' = 'new';\n \n // New Artifact Form\n newArtifactName = '';\n newArtifactDescription = '';\n \n private get metadata() { return this.ProviderToUse; }\n private currentUser: UserInfo | null = null;\n private destroy$ = new Subject<void>();\n private searchSubject = new Subject<string>();\n\n private notificationService = inject(MJNotificationService);\n private cdr = inject(ChangeDetectorRef);\n\n async ngOnInit() {\n // Setup search debouncing\n this.searchSubject.pipe(\n debounceTime(300),\n distinctUntilChanged(),\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.filterArtifacts();\n });\n \n await this.filterArtifacts();\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n async loadArtifacts() {\n this.isLoading = true;\n this.cdr.detectChanges();\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n // Calculate StartRow for server-side paging\n const startRow = this.currentPage * this.pageSize;\n\n // Load artifacts with paging\n const result = await rv.RunView<MJArtifactEntity>({\n ExtraFilter: this._artifactFilter,\n EntityName: 'MJ: Artifacts',\n OrderBy: '__mj_UpdatedAt DESC',\n MaxRows: this.pageSize,\n StartRow: startRow,\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.artifacts = result.Results;\n\n // Calculate total pages using TotalRowCount from server\n this.totalArtifacts = result.TotalRowCount || 0;\n const totalPages = Math.ceil(this.totalArtifacts / this.pageSize);\n this.hasMorePages = this.currentPage < totalPages - 1;\n }\n } catch (error) {\n console.error('Error loading artifacts:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private _artifactFilter: string | undefined= undefined;\n public async filterArtifacts() {\n // Reset to first page when filters change\n this.currentPage = 0;\n \n const filters: string[] = [];\n \n // Filter by search term\n if (this.searchTerm?.trim()) {\n const term = this.searchTerm.toLowerCase();\n filters.push(`(Name LIKE '%${term}%' OR Description LIKE '%${term}%')`);\n }\n \n // Filter by artifact type\n if (this.selectedArtifactType) {\n filters.push(`ArtifactTypeID IN (SELECT ID FROM __mj.vwArtifactTypes WHERE Name = '${this.selectedArtifactType}')`);\n }\n \n // Filter by user email if provided\n if (this.userEmail?.trim()) {\n const md = this.ProviderToUse;\n const schemaName = md.EntityByName(\"MJ: Users\")?.SchemaName || \"__mj\";\n const userFilter = `UserID IN (SELECT ID FROM ${schemaName}.vwUsers WHERE Email LIKE '%${this.userEmail.trim()}%')`;\n filters.push(userFilter);\n }\n \n // Combine all filters\n this._artifactFilter = filters.length > 0 ? filters.join(' AND ') : undefined;\n\n await this.loadArtifacts();\n }\n\n selectCreateNew() {\n this.showNewArtifactForm = true;\n this.selectedArtifact = null;\n this.selectedVersion = null;\n }\n\n async selectArtifact(artifact: MJArtifactEntity) {\n this.selectedArtifact = artifact;\n this.showNewArtifactForm = false;\n this.versionAction = 'new';\n this.selectedVersion = null;\n this.cdr.detectChanges();\n\n // Load versions for this artifact\n await this.loadVersions(artifact.ID);\n }\n\n async loadVersions(artifactId: string) {\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJArtifactVersionEntity>({\n EntityName: 'MJ: Artifact Versions',\n ExtraFilter: `ArtifactID = '${artifactId}'`,\n OrderBy: 'VersionNumber DESC',\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.artifactVersions = result.Results;\n }\n } catch (error) {\n console.error('Error loading versions:', error);\n this.artifactVersions = [];\n } finally {\n this.cdr.detectChanges();\n }\n }\n\n getNextVersionNumber(): number {\n if (this.artifactVersions.length === 0) return 1;\n return Math.max(...this.artifactVersions.map(v => v.VersionNumber)) + 1;\n }\n\n // Paging methods\n async nextPage() {\n if (this.hasMorePages) {\n this.currentPage++;\n await this.loadArtifacts();\n }\n }\n\n async previousPage() {\n if (this.currentPage > 0) {\n this.currentPage--;\n await this.loadArtifacts();\n }\n }\n\n canGoNext(): boolean {\n return this.hasMorePages;\n }\n\n canGoPrevious(): boolean {\n return this.currentPage > 0;\n }\n\n getTotalPages(): number {\n return Math.ceil(this.totalArtifacts / this.pageSize);\n }\n\n toggleFilterPanel() {\n this.isFilterPanelCollapsed = !this.isFilterPanelCollapsed;\n }\n\n onSearchInput() {\n this.searchSubject.next(this.searchTerm);\n }\n\n onArtifactTypeChange() {\n // Clear selected artifact when type changes\n this.selectedArtifact = null;\n this.selectedVersion = null;\n this.artifactVersions = [];\n this.filterArtifacts();\n }\n\n getActiveFilterCount(): number {\n let count = 0;\n if (this.searchTerm?.trim()) count++;\n if (this.selectedArtifactType) count++;\n if (this.userEmail?.trim()) count++;\n return count;\n }\n\n canSave(): boolean {\n if (this.showNewArtifactForm) {\n return this.newArtifactName.trim().length > 0;\n }\n \n if (!this.selectedArtifact) return false;\n \n if (this.versionAction === 'update') {\n return this.selectedVersion !== null;\n }\n \n return true;\n }\n\n getSaveButtonText(): string {\n if (this.showNewArtifactForm) {\n return 'Create & Save';\n }\n\n if (this.versionAction === 'update' && this.selectedVersion) {\n return `Update Version ${this.selectedVersion.VersionNumber}`;\n }\n\n return `Save as Version ${this.getNextVersionNumber()}`;\n }\n\n cancel() {\n this.Close.emit(undefined);\n }\n\n async save() {\n if (!this.canSave()) return;\n \n // Handle new artifact creation\n if (this.showNewArtifactForm) {\n const newArtifact = await this.createNewArtifact();\n if (newArtifact) {\n const result: ArtifactSelectionResult = {\n artifact: newArtifact,\n action: 'new-version'\n };\n this.Close.emit(result);\n }\n return;\n }\n \n // Handle existing artifact selection\n if (this.selectedArtifact) {\n const result: ArtifactSelectionResult = {\n artifact: this.selectedArtifact,\n action: this.versionAction === 'update' ? 'update-version' : 'new-version',\n versionToUpdate: this.versionAction === 'update' ? this.selectedVersion! : undefined\n };\n \n // If updating, show confirmation\n if (this.versionAction === 'update') {\n const confirm = window.confirm(\n `Are you sure you want to overwrite version ${this.selectedVersion!.VersionNumber}? This action cannot be undone.`\n );\n\n if (!confirm) return;\n }\n\n this.Close.emit(result);\n }\n }\n\n private async createNewArtifact(): Promise<MJArtifactEntity | null> {\n try {\n const artifact = await this.metadata.GetEntityObject<MJArtifactEntity>('MJ: Artifacts');\n artifact.Name = this.newArtifactName;\n artifact.Description = this.newArtifactDescription || null;\n\n // Get Component artifact type\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const typeResult = await rv.RunView({\n EntityName: 'MJ: Artifact Types',\n ExtraFilter: `Name = 'Component'`,\n MaxRows: 1\n });\n\n if (typeResult.Success && typeResult.Results?.length > 0) {\n artifact.TypeID = typeResult.Results[0].ID;\n }\n\n // Set default environment if available from current user\n // Environment ID is optional - will be set by server if not provided\n const envId = (this.metadata.CurrentUser as any)?.EnvironmentID;\n if (envId) {\n artifact.EnvironmentID = envId;\n }\n\n artifact.Comments = 'Created from Component Studio';\n\n const saveResult = await artifact.Save();\n if (saveResult) {\n this.notificationService.CreateSimpleNotification(\n `Artifact \"${artifact.Name}\" created successfully`,\n 'success',\n 3000\n );\n return artifact;\n } else {\n console.error('Failed to create artifact - Full LatestResult:', artifact.LatestResult);\n this.notificationService.CreateSimpleNotification(\n 'Failed to create artifact',\n 'error'\n );\n return null;\n }\n } catch (error) {\n console.error('Error creating artifact:', error);\n this.notificationService.CreateSimpleNotification(\n 'Error creating artifact',\n 'error'\n );\n return null;\n }\n }\n\n /** Case-insensitive UUID check whether an artifact is the currently selected artifact. */\n IsArtifactSelected(artifact: MJArtifactEntity): boolean {\n return UUIDsEqual(this.selectedArtifact?.ID, artifact.ID);\n }\n\n /** Case-insensitive UUID check whether a version is the currently selected version. */\n IsVersionSelected(version: MJArtifactVersionEntity): boolean {\n return UUIDsEqual(this.selectedVersion?.ID, version.ID);\n }\n}","<mj-dialog [Visible]=\"true\" Title=\"Save Component to Artifact\" (Close)=\"cancel()\" [Width]=\"1200\" [MinWidth]=\"600\">\n <div class=\"artifact-selection-content\">\n <!-- Left Filter Panel -->\n <div class=\"filter-panel\" [style.width]=\"isFilterPanelCollapsed ? '40px' : '280px'\">\n <!-- Panel Header -->\n <div class=\"panel-header\">\n @if (!isFilterPanelCollapsed) {\n <span>Filters</span>\n }\n <button mjButton (click)=\"toggleFilterPanel()\"\n variant=\"flat\"\n [class.filter-active]=\"getActiveFilterCount() > 0\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (isFilterPanelCollapsed && getActiveFilterCount() > 0) {\n <span class=\"filter-count\">{{ getActiveFilterCount() }}</span>\n }\n </button>\n </div>\n\n @if (!isFilterPanelCollapsed) {\n <div class=\"filter-content\">\n <!-- Search -->\n <div class=\"filter-group\">\n <label>Search</label>\n <input type=\"text\" \n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchInput()\"\n placeholder=\"Name or description...\"\n class=\"filter-input\">\n </div>\n\n <!-- Artifact Type -->\n <div class=\"filter-group\">\n <label>Artifact Type</label>\n <select [(ngModel)]=\"selectedArtifactType\" \n (change)=\"onArtifactTypeChange()\"\n class=\"filter-select\">\n <option value=\"\">All Types</option>\n <option value=\"Component\">Component</option>\n <option value=\"Report\">Report</option>\n <option value=\"Dashboard\">Dashboard</option>\n </select>\n </div>\n \n <!-- User Email -->\n <div class=\"filter-group\">\n <label>Filter by User</label>\n <input type=\"text\" \n [(ngModel)]=\"userEmail\"\n (input)=\"filterArtifacts()\"\n placeholder=\"Enter user email...\"\n class=\"filter-input\">\n </div>\n </div>\n }\n </div>\n\n <!-- Main Content Area -->\n <div class=\"main-content\">\n <!-- Paging Controls -->\n <div class=\"paging-controls\">\n <button mjButton\n (click)=\"previousPage()\"\n [disabled]=\"!canGoPrevious()\">\n <i class=\"fa-solid fa-chevron-left\"></i> Previous\n </button>\n <span class=\"page-info\">\n Page {{ currentPage + 1 }} of {{ getTotalPages() }}\n ({{ totalArtifacts }} total items)\n </span>\n <button mjButton\n (click)=\"nextPage()\"\n [disabled]=\"!canGoNext()\">\n Next <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n\n <!-- Existing Artifacts -->\n <div class=\"artifacts-list\">\n @if (isLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading artifacts...\" size=\"small\"></mj-loading>\n </div>\n } \n @else if (artifacts.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-inbox\"\n Title=\"No artifacts found\" />\n } \n @else {\n @for (artifact of artifacts; track artifact.ID) {\n <div class=\"artifact-item\" \n [class.selected]=\"IsArtifactSelected(artifact)\"\n (click)=\"selectArtifact(artifact)\">\n <div class=\"artifact-content\">\n <div class=\"artifact-main\">\n <div class=\"artifact-name\">\n <i class=\"fa-solid fa-file-code\"></i>\n <span>{{ artifact.Name }}</span>\n </div>\n @if (artifact.Description) {\n <div class=\"artifact-description\">\n {{ artifact.Description }}\n </div>\n }\n </div>\n <div class=\"artifact-meta\">\n <div>{{ artifact.Type }}</div>\n <div>{{ artifact.__mj_UpdatedAt | date:'short' }}</div>\n </div>\n </div>\n </div>\n }\n }\n </div>\n \n <!-- Create New Artifact Section (at bottom) -->\n <div class=\"create-section\">\n <div class=\"divider\">OR CREATE NEW ARTIFACT</div>\n \n <button mjButton\n (click)=\"selectCreateNew()\"\n variant=\"primary\"\n class=\"create-btn\">\n <i class=\"fa-solid fa-plus\"></i> Create New Artifact\n </button>\n \n @if (showNewArtifactForm) {\n <div class=\"new-artifact-form\">\n <input class=\"mj-input\"\n [(ngModel)]=\"newArtifactName\"\n placeholder=\"Artifact name...\">\n <textarea class=\"mj-textarea\"\n [(ngModel)]=\"newArtifactDescription\"\n placeholder=\"Description (optional)...\">\n </textarea>\n </div>\n }\n </div>\n </div>\n\n <!-- Right Version Panel (only show when artifact selected) -->\n @if (selectedArtifact) {\n <div class=\"version-panel\">\n <div class=\"panel-header\">\n <h4><i class=\"fa-solid fa-code-branch\"></i> Version</h4>\n </div>\n \n @if (artifactVersions.length > 0) {\n <div class=\"version-content\">\n <div class=\"version-actions\">\n <label>Action</label>\n <label class=\"radio-label\">\n <input type=\"radio\" \n name=\"versionAction\" \n value=\"new\"\n [(ngModel)]=\"versionAction\"\n (change)=\"selectedVersion = null\">\n <span>Create New Version (v{{ getNextVersionNumber() }})</span>\n </label>\n \n <label class=\"radio-label\">\n <input type=\"radio\" \n name=\"versionAction\" \n value=\"update\"\n [(ngModel)]=\"versionAction\">\n <span>Update Existing Version</span>\n </label>\n </div>\n \n @if (versionAction === 'update') {\n <div class=\"version-selection\">\n <label>Select Version</label>\n @for (version of artifactVersions; track version.ID) {\n <label class=\"version-item\" \n [class.selected]=\"IsVersionSelected(version)\">\n <input type=\"radio\"\n name=\"selectedVersion\"\n [value]=\"version\"\n [(ngModel)]=\"selectedVersion\">\n <div class=\"version-info\">\n <div class=\"version-number\">Version {{ version.VersionNumber }}</div>\n <div class=\"version-date\">{{ version.__mj_UpdatedAt | date:'short' }}</div>\n </div>\n </label>\n }\n </div>\n \n @if (selectedVersion) {\n <div class=\"warning\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>Warning: This will overwrite version {{ selectedVersion.VersionNumber }}</span>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"info-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No versions available for this artifact.</p>\n <p>A new version will be created.</p>\n </div>\n }\n </div>\n }\n </div>\n\n <mj-dialog-actions>\n <button mjButton\n [variant]=\"versionAction === 'update' && selectedVersion ? 'warning' : 'primary'\"\n (click)=\"save()\"\n [disabled]=\"!canSave()\">\n <i class=\"fa-solid fa-save\"></i>\n {{ getSaveButtonText() }}\n </button>\n <button mjButton (click)=\"cancel()\">Cancel</button>\n </mj-dialog-actions>\n</mj-dialog>\n"]}
|
|
1
|
+
{"version":3,"file":"artifact-selection-dialog.component.js","sourceRoot":"","sources":["../../../src/ComponentStudio/components/artifact-selection-dialog.component.ts","../../../src/ComponentStudio/components/artifact-selection-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, ChangeDetectorRef, inject } from '@angular/core';\nimport { RunView, UserInfo } from '@memberjunction/core';\nimport { MJArtifactEntity, MJArtifactVersionEntity } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { Subject, debounceTime, distinctUntilChanged } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { MJConfirmService } from '@memberjunction/ng-ui-components';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\nexport interface ArtifactSelectionResult {\n artifact: MJArtifactEntity;\n action: 'new-version' | 'update-version';\n versionToUpdate?: MJArtifactVersionEntity;\n}\n\n@Component({\n standalone: false,\n selector: 'app-artifact-selection-dialog',\n templateUrl: './artifact-selection-dialog.component.html',\n styleUrl: './artifact-selection-dialog.component.css'\n})\nexport class ArtifactSelectionDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n @Input() Visible = false;\n @Output() Close = new EventEmitter<ArtifactSelectionResult | undefined>();\n\n // Data\n artifacts: MJArtifactEntity[] = [];\n artifactVersions: MJArtifactVersionEntity[] = [];\n\n // Paging State\n currentPage = 0;\n pageSize = 25;\n totalArtifacts = 0;\n hasMorePages = false;\n\n // UI State\n isLoading = true;\n searchTerm = '';\n userEmail = '';\n selectedArtifactType = '';\n showNewArtifactForm = false;\n isFilterPanelCollapsed = false;\n\n\n // Selection State\n selectedArtifact: MJArtifactEntity | null = null;\n selectedVersion: MJArtifactVersionEntity | null = null;\n versionAction: 'new' | 'update' = 'new';\n \n // New Artifact Form\n newArtifactName = '';\n newArtifactDescription = '';\n \n private get metadata() { return this.ProviderToUse; }\n private currentUser: UserInfo | null = null;\n private destroy$ = new Subject<void>();\n private searchSubject = new Subject<string>();\n\n private notificationService = inject(MJNotificationService);\n private confirmService = inject(MJConfirmService);\n private cdr = inject(ChangeDetectorRef);\n\n async ngOnInit() {\n // Setup search debouncing\n this.searchSubject.pipe(\n debounceTime(300),\n distinctUntilChanged(),\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.filterArtifacts();\n });\n \n await this.filterArtifacts();\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n async loadArtifacts() {\n this.isLoading = true;\n this.cdr.detectChanges();\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n // Calculate StartRow for server-side paging\n const startRow = this.currentPage * this.pageSize;\n\n // Load artifacts with paging\n const result = await rv.RunView<MJArtifactEntity>({\n ExtraFilter: this._artifactFilter,\n EntityName: 'MJ: Artifacts',\n OrderBy: '__mj_UpdatedAt DESC',\n MaxRows: this.pageSize,\n StartRow: startRow,\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.artifacts = result.Results;\n\n // Calculate total pages using TotalRowCount from server\n this.totalArtifacts = result.TotalRowCount || 0;\n const totalPages = Math.ceil(this.totalArtifacts / this.pageSize);\n this.hasMorePages = this.currentPage < totalPages - 1;\n }\n } catch (error) {\n console.error('Error loading artifacts:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private _artifactFilter: string | undefined= undefined;\n public async filterArtifacts() {\n // Reset to first page when filters change\n this.currentPage = 0;\n \n const filters: string[] = [];\n \n // Filter by search term\n if (this.searchTerm?.trim()) {\n const term = this.searchTerm.toLowerCase();\n filters.push(`(Name LIKE '%${term}%' OR Description LIKE '%${term}%')`);\n }\n \n // Filter by artifact type\n if (this.selectedArtifactType) {\n filters.push(`ArtifactTypeID IN (SELECT ID FROM __mj.vwArtifactTypes WHERE Name = '${this.selectedArtifactType}')`);\n }\n \n // Filter by user email if provided\n if (this.userEmail?.trim()) {\n const md = this.ProviderToUse;\n const schemaName = md.EntityByName(\"MJ: Users\")?.SchemaName || \"__mj\";\n const userFilter = `UserID IN (SELECT ID FROM ${schemaName}.vwUsers WHERE Email LIKE '%${this.userEmail.trim()}%')`;\n filters.push(userFilter);\n }\n \n // Combine all filters\n this._artifactFilter = filters.length > 0 ? filters.join(' AND ') : undefined;\n\n await this.loadArtifacts();\n }\n\n selectCreateNew() {\n this.showNewArtifactForm = true;\n this.selectedArtifact = null;\n this.selectedVersion = null;\n }\n\n async selectArtifact(artifact: MJArtifactEntity) {\n this.selectedArtifact = artifact;\n this.showNewArtifactForm = false;\n this.versionAction = 'new';\n this.selectedVersion = null;\n this.cdr.detectChanges();\n\n // Load versions for this artifact\n await this.loadVersions(artifact.ID);\n }\n\n async loadVersions(artifactId: string) {\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJArtifactVersionEntity>({\n EntityName: 'MJ: Artifact Versions',\n ExtraFilter: `ArtifactID = '${artifactId}'`,\n OrderBy: 'VersionNumber DESC',\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.artifactVersions = result.Results;\n }\n } catch (error) {\n console.error('Error loading versions:', error);\n this.artifactVersions = [];\n } finally {\n this.cdr.detectChanges();\n }\n }\n\n getNextVersionNumber(): number {\n if (this.artifactVersions.length === 0) return 1;\n return Math.max(...this.artifactVersions.map(v => v.VersionNumber)) + 1;\n }\n\n // Paging methods\n async nextPage() {\n if (this.hasMorePages) {\n this.currentPage++;\n await this.loadArtifacts();\n }\n }\n\n async previousPage() {\n if (this.currentPage > 0) {\n this.currentPage--;\n await this.loadArtifacts();\n }\n }\n\n canGoNext(): boolean {\n return this.hasMorePages;\n }\n\n canGoPrevious(): boolean {\n return this.currentPage > 0;\n }\n\n getTotalPages(): number {\n return Math.ceil(this.totalArtifacts / this.pageSize);\n }\n\n toggleFilterPanel() {\n this.isFilterPanelCollapsed = !this.isFilterPanelCollapsed;\n }\n\n onSearchInput() {\n this.searchSubject.next(this.searchTerm);\n }\n\n onArtifactTypeChange() {\n // Clear selected artifact when type changes\n this.selectedArtifact = null;\n this.selectedVersion = null;\n this.artifactVersions = [];\n this.filterArtifacts();\n }\n\n getActiveFilterCount(): number {\n let count = 0;\n if (this.searchTerm?.trim()) count++;\n if (this.selectedArtifactType) count++;\n if (this.userEmail?.trim()) count++;\n return count;\n }\n\n canSave(): boolean {\n if (this.showNewArtifactForm) {\n return this.newArtifactName.trim().length > 0;\n }\n \n if (!this.selectedArtifact) return false;\n \n if (this.versionAction === 'update') {\n return this.selectedVersion !== null;\n }\n \n return true;\n }\n\n getSaveButtonText(): string {\n if (this.showNewArtifactForm) {\n return 'Create & Save';\n }\n\n if (this.versionAction === 'update' && this.selectedVersion) {\n return `Update Version ${this.selectedVersion.VersionNumber}`;\n }\n\n return `Save as Version ${this.getNextVersionNumber()}`;\n }\n\n cancel() {\n this.Close.emit(undefined);\n }\n\n async save() {\n if (!this.canSave()) return;\n \n // Handle new artifact creation\n if (this.showNewArtifactForm) {\n const newArtifact = await this.createNewArtifact();\n if (newArtifact) {\n const result: ArtifactSelectionResult = {\n artifact: newArtifact,\n action: 'new-version'\n };\n this.Close.emit(result);\n }\n return;\n }\n \n // Handle existing artifact selection\n if (this.selectedArtifact) {\n const result: ArtifactSelectionResult = {\n artifact: this.selectedArtifact,\n action: this.versionAction === 'update' ? 'update-version' : 'new-version',\n versionToUpdate: this.versionAction === 'update' ? this.selectedVersion! : undefined\n };\n \n // If updating, show confirmation\n if (this.versionAction === 'update') {\n const confirmed = await this.confirmService.Confirm({ title: 'Overwrite version', message: `Overwrite version ${this.selectedVersion!.VersionNumber}?`, detail: 'This action cannot be undone.' });\n if (!confirmed) return;\n }\n\n this.Close.emit(result);\n }\n }\n\n private async createNewArtifact(): Promise<MJArtifactEntity | null> {\n try {\n const artifact = await this.metadata.GetEntityObject<MJArtifactEntity>('MJ: Artifacts');\n artifact.Name = this.newArtifactName;\n artifact.Description = this.newArtifactDescription || null;\n\n // Get Component artifact type\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const typeResult = await rv.RunView({\n EntityName: 'MJ: Artifact Types',\n ExtraFilter: `Name = 'Component'`,\n MaxRows: 1\n });\n\n if (typeResult.Success && typeResult.Results?.length > 0) {\n artifact.TypeID = typeResult.Results[0].ID;\n }\n\n // Set default environment if available from current user\n // Environment ID is optional - will be set by server if not provided\n const envId = (this.metadata.CurrentUser as any)?.EnvironmentID;\n if (envId) {\n artifact.EnvironmentID = envId;\n }\n\n artifact.Comments = 'Created from Component Studio';\n\n const saveResult = await artifact.Save();\n if (saveResult) {\n this.notificationService.CreateSimpleNotification(\n `Artifact \"${artifact.Name}\" created successfully`,\n 'success',\n 3000\n );\n return artifact;\n } else {\n console.error('Failed to create artifact - Full LatestResult:', artifact.LatestResult);\n this.notificationService.CreateSimpleNotification(\n 'Failed to create artifact',\n 'error'\n );\n return null;\n }\n } catch (error) {\n console.error('Error creating artifact:', error);\n this.notificationService.CreateSimpleNotification(\n 'Error creating artifact',\n 'error'\n );\n return null;\n }\n }\n\n /** Case-insensitive UUID check whether an artifact is the currently selected artifact. */\n IsArtifactSelected(artifact: MJArtifactEntity): boolean {\n return UUIDsEqual(this.selectedArtifact?.ID, artifact.ID);\n }\n\n /** Case-insensitive UUID check whether a version is the currently selected version. */\n IsVersionSelected(version: MJArtifactVersionEntity): boolean {\n return UUIDsEqual(this.selectedVersion?.ID, version.ID);\n }\n}","<mj-dialog [Visible]=\"true\" Title=\"Save Component to Artifact\" (Close)=\"cancel()\" [Width]=\"1200\" [MinWidth]=\"600\">\n <div class=\"artifact-selection-content\">\n <!-- Left Filter Panel -->\n <div class=\"filter-panel\" [style.width]=\"isFilterPanelCollapsed ? '40px' : '280px'\">\n <!-- Panel Header -->\n <div class=\"panel-header\">\n @if (!isFilterPanelCollapsed) {\n <span>Filters</span>\n }\n <button mjButton (click)=\"toggleFilterPanel()\"\n variant=\"flat\"\n [class.filter-active]=\"getActiveFilterCount() > 0\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (isFilterPanelCollapsed && getActiveFilterCount() > 0) {\n <span class=\"filter-count\">{{ getActiveFilterCount() }}</span>\n }\n </button>\n </div>\n\n @if (!isFilterPanelCollapsed) {\n <div class=\"filter-content\">\n <!-- Search -->\n <div class=\"filter-group\">\n <label>Search</label>\n <input type=\"text\" \n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchInput()\"\n placeholder=\"Name or description...\"\n class=\"filter-input\">\n </div>\n\n <!-- Artifact Type -->\n <div class=\"filter-group\">\n <label>Artifact Type</label>\n <select [(ngModel)]=\"selectedArtifactType\" \n (change)=\"onArtifactTypeChange()\"\n class=\"filter-select\">\n <option value=\"\">All Types</option>\n <option value=\"Component\">Component</option>\n <option value=\"Report\">Report</option>\n <option value=\"Dashboard\">Dashboard</option>\n </select>\n </div>\n \n <!-- User Email -->\n <div class=\"filter-group\">\n <label>Filter by User</label>\n <input type=\"text\" \n [(ngModel)]=\"userEmail\"\n (input)=\"filterArtifacts()\"\n placeholder=\"Enter user email...\"\n class=\"filter-input\">\n </div>\n </div>\n }\n </div>\n\n <!-- Main Content Area -->\n <div class=\"main-content\">\n <!-- Paging Controls -->\n <div class=\"paging-controls\">\n <button mjButton\n (click)=\"previousPage()\"\n [disabled]=\"!canGoPrevious()\">\n <i class=\"fa-solid fa-chevron-left\"></i> Previous\n </button>\n <span class=\"page-info\">\n Page {{ currentPage + 1 }} of {{ getTotalPages() }}\n ({{ totalArtifacts }} total items)\n </span>\n <button mjButton\n (click)=\"nextPage()\"\n [disabled]=\"!canGoNext()\">\n Next <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n\n <!-- Existing Artifacts -->\n <div class=\"artifacts-list\">\n @if (isLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading artifacts...\" size=\"small\"></mj-loading>\n </div>\n } \n @else if (artifacts.length === 0) {\n <mj-empty-state Size=\"compact\" Icon=\"fa-solid fa-inbox\"\n Title=\"No artifacts found\" />\n } \n @else {\n @for (artifact of artifacts; track artifact.ID) {\n <div class=\"artifact-item\" \n [class.selected]=\"IsArtifactSelected(artifact)\"\n (click)=\"selectArtifact(artifact)\">\n <div class=\"artifact-content\">\n <div class=\"artifact-main\">\n <div class=\"artifact-name\">\n <i class=\"fa-solid fa-file-code\"></i>\n <span>{{ artifact.Name }}</span>\n </div>\n @if (artifact.Description) {\n <div class=\"artifact-description\">\n {{ artifact.Description }}\n </div>\n }\n </div>\n <div class=\"artifact-meta\">\n <div>{{ artifact.Type }}</div>\n <div>{{ artifact.__mj_UpdatedAt | date:'short' }}</div>\n </div>\n </div>\n </div>\n }\n }\n </div>\n \n <!-- Create New Artifact Section (at bottom) -->\n <div class=\"create-section\">\n <div class=\"divider\">OR CREATE NEW ARTIFACT</div>\n \n <button mjButton\n (click)=\"selectCreateNew()\"\n variant=\"primary\"\n class=\"create-btn\">\n <i class=\"fa-solid fa-plus\"></i> Create New Artifact\n </button>\n \n @if (showNewArtifactForm) {\n <div class=\"new-artifact-form\">\n <input class=\"mj-input\"\n [(ngModel)]=\"newArtifactName\"\n placeholder=\"Artifact name...\">\n <textarea class=\"mj-textarea\"\n [(ngModel)]=\"newArtifactDescription\"\n placeholder=\"Description (optional)...\">\n </textarea>\n </div>\n }\n </div>\n </div>\n\n <!-- Right Version Panel (only show when artifact selected) -->\n @if (selectedArtifact) {\n <div class=\"version-panel\">\n <div class=\"panel-header\">\n <h4><i class=\"fa-solid fa-code-branch\"></i> Version</h4>\n </div>\n \n @if (artifactVersions.length > 0) {\n <div class=\"version-content\">\n <div class=\"version-actions\">\n <label>Action</label>\n <label class=\"radio-label\">\n <input type=\"radio\" \n name=\"versionAction\" \n value=\"new\"\n [(ngModel)]=\"versionAction\"\n (change)=\"selectedVersion = null\">\n <span>Create New Version (v{{ getNextVersionNumber() }})</span>\n </label>\n \n <label class=\"radio-label\">\n <input type=\"radio\" \n name=\"versionAction\" \n value=\"update\"\n [(ngModel)]=\"versionAction\">\n <span>Update Existing Version</span>\n </label>\n </div>\n \n @if (versionAction === 'update') {\n <div class=\"version-selection\">\n <label>Select Version</label>\n @for (version of artifactVersions; track version.ID) {\n <label class=\"version-item\" \n [class.selected]=\"IsVersionSelected(version)\">\n <input type=\"radio\"\n name=\"selectedVersion\"\n [value]=\"version\"\n [(ngModel)]=\"selectedVersion\">\n <div class=\"version-info\">\n <div class=\"version-number\">Version {{ version.VersionNumber }}</div>\n <div class=\"version-date\">{{ version.__mj_UpdatedAt | date:'short' }}</div>\n </div>\n </label>\n }\n </div>\n \n @if (selectedVersion) {\n <div class=\"warning\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>Warning: This will overwrite version {{ selectedVersion.VersionNumber }}</span>\n </div>\n }\n }\n </div>\n } @else {\n <div class=\"info-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No versions available for this artifact.</p>\n <p>A new version will be created.</p>\n </div>\n }\n </div>\n }\n </div>\n\n <mj-dialog-actions>\n <button mjButton\n [variant]=\"versionAction === 'update' && selectedVersion ? 'warning' : 'primary'\"\n (click)=\"save()\"\n [disabled]=\"!canSave()\">\n <i class=\"fa-solid fa-save\"></i>\n {{ getSaveButtonText() }}\n </button>\n <button mjButton (click)=\"cancel()\">Cancel</button>\n </mj-dialog-actions>\n</mj-dialog>\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
|
2
2
|
import { ResourceData, MJCredentialCategoryEntity, MJCredentialTypeEntity } from '@memberjunction/core-entities';
|
|
3
3
|
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
4
|
+
import { MJConfirmService } from '@memberjunction/ng-ui-components';
|
|
4
5
|
import { CredentialCategoryEditPanelComponent } from '@memberjunction/ng-credentials';
|
|
5
6
|
import * as i0 from "@angular/core";
|
|
6
7
|
interface CategoryNode {
|
|
@@ -12,6 +13,7 @@ interface CategoryNode {
|
|
|
12
13
|
}
|
|
13
14
|
export declare class CredentialsCategoriesResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {
|
|
14
15
|
private cdr;
|
|
16
|
+
private confirm;
|
|
15
17
|
isLoading: boolean;
|
|
16
18
|
categories: MJCredentialCategoryEntity[];
|
|
17
19
|
categoryTree: CategoryNode[];
|
|
@@ -21,7 +23,7 @@ export declare class CredentialsCategoriesResourceComponent extends BaseResource
|
|
|
21
23
|
private _metadata;
|
|
22
24
|
private _permissionCache;
|
|
23
25
|
categoryEditPanel: CredentialCategoryEditPanelComponent;
|
|
24
|
-
constructor(cdr: ChangeDetectorRef);
|
|
26
|
+
constructor(cdr: ChangeDetectorRef, confirm: MJConfirmService);
|
|
25
27
|
ngOnInit(): void;
|
|
26
28
|
ngOnDestroy(): void;
|
|
27
29
|
GetResourceDisplayName(data: ResourceData): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials-categories-resource.component.d.ts","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-categories-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAsC,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAEjH,OAAO,EAAE,qBAAqB,EAAqB,MAAM,2BAA2B,CAAC;AAGrF,OAAO,EAAE,oCAAoC,EAAE,MAAM,gCAAgC,CAAC;;AACtF,UAAU,YAAY;IAClB,QAAQ,EAAE,0BAA0B,CAAC;IACrC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,qBAQa,sCAAuC,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS;IAetG,OAAO,CAAC,GAAG;
|
|
1
|
+
{"version":3,"file":"credentials-categories-resource.component.d.ts","sourceRoot":"","sources":["../../../src/Credentials/components/credentials-categories-resource.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -359,6 +359,7 @@ function CredentialsCategoriesResourceComponent_Conditional_17_Template(rf, ctx)
|
|
|
359
359
|
} }
|
|
360
360
|
let CredentialsCategoriesResourceComponent = class CredentialsCategoriesResourceComponent extends BaseResourceComponent {
|
|
361
361
|
cdr;
|
|
362
|
+
confirm;
|
|
362
363
|
isLoading = true;
|
|
363
364
|
categories = [];
|
|
364
365
|
categoryTree = [];
|
|
@@ -369,9 +370,10 @@ let CredentialsCategoriesResourceComponent = class CredentialsCategoriesResource
|
|
|
369
370
|
_metadata = this.ProviderToUse;
|
|
370
371
|
_permissionCache = new Map();
|
|
371
372
|
categoryEditPanel;
|
|
372
|
-
constructor(cdr) {
|
|
373
|
+
constructor(cdr, confirm) {
|
|
373
374
|
super();
|
|
374
375
|
this.cdr = cdr;
|
|
376
|
+
this.confirm = confirm;
|
|
375
377
|
}
|
|
376
378
|
ngOnInit() {
|
|
377
379
|
super.ngOnInit();
|
|
@@ -545,7 +547,11 @@ let CredentialsCategoriesResourceComponent = class CredentialsCategoriesResource
|
|
|
545
547
|
MJNotificationService.Instance.CreateSimpleNotification(`Cannot delete "${node.category.Name}" - it has ${node.typeCount} credential type(s) using it`, 'warning', 4000);
|
|
546
548
|
return;
|
|
547
549
|
}
|
|
548
|
-
const confirmed = confirm(
|
|
550
|
+
const confirmed = await this.confirm.ConfirmDelete({
|
|
551
|
+
title: 'Delete category',
|
|
552
|
+
message: `Delete "${node.category.Name}"?`,
|
|
553
|
+
detail: 'This action cannot be undone.',
|
|
554
|
+
});
|
|
549
555
|
if (!confirmed)
|
|
550
556
|
return;
|
|
551
557
|
try {
|
|
@@ -713,7 +719,7 @@ let CredentialsCategoriesResourceComponent = class CredentialsCategoriesResource
|
|
|
713
719
|
this.selectedNode = null;
|
|
714
720
|
this.loadData();
|
|
715
721
|
}
|
|
716
|
-
static ɵfac = function CredentialsCategoriesResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CredentialsCategoriesResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
722
|
+
static ɵfac = function CredentialsCategoriesResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CredentialsCategoriesResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.MJConfirmService)); };
|
|
717
723
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CredentialsCategoriesResourceComponent, selectors: [["mj-credentials-categories-resource"]], viewQuery: function CredentialsCategoriesResourceComponent_Query(rf, ctx) { if (rf & 1) {
|
|
718
724
|
i0.ɵɵviewQuery(_c0, 5);
|
|
719
725
|
} if (rf & 2) {
|
|
@@ -768,9 +774,9 @@ export { CredentialsCategoriesResourceComponent };
|
|
|
768
774
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CredentialsCategoriesResourceComponent, [{
|
|
769
775
|
type: Component,
|
|
770
776
|
args: [{ standalone: false, selector: 'mj-credentials-categories-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<mj-page-layout>\n <mj-page-header\n Title=\"Categories\"\n Icon=\"fa-solid fa-folder-tree\">\n <!-- [meta] intentionally omitted \u2014 chrome slot discipline audit Task B.\n The categories count mirrored the visible tree; the cross-entity\n types count belongs on the Types page, not here. -->\n\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"expandAll()\" title=\"Expand all\">\n <i class=\"fa-solid fa-expand\"></i> <span class=\"action-btn-label\">Expand</span>\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"collapseAll()\" title=\"Collapse all\">\n <i class=\"fa-solid fa-compress\"></i> <span class=\"action-btn-label\">Collapse</span>\n </button>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"refresh()\"></mj-refresh-button>\n @if (UserCanCreate) {\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"createNewCategory()\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"action-btn-label\">New Category</span>\n </button>\n }\n </div>\n <div toolbar>\n <mj-page-search\n Placeholder=\"Search categories...\"\n [Value]=\"searchText\"\n (ValueChange)=\"onSearchChange($event)\">\n </mj-page-search>\n </div>\n </mj-page-header>\n\n <mj-page-body>\n @if (isLoading) {\n <mj-loading text=\"Loading categories...\"></mj-loading>\n }\n\n @if (!isLoading) {\n <div class=\"categories-layout\">\n <!-- Tree Container -->\n <div class=\"tree-panel\">\n @if (categoryTree.length > 0) {\n <div class=\"tree-container\">\n @for (node of getFlattenedNodes(); track node; let i = $index) {\n <div\n class=\"tree-node\"\n [class.selected]=\"IsNodeSelected(node)\"\n [style.padding-left.px]=\"12 + (node.level * 20)\"\n (click)=\"selectNode(node)\"\n >\n <div class=\"node-content\">\n @if (node.children.length > 0) {\n <button\n class=\"expand-btn\"\n (click)=\"toggleExpand(node, $event)\"\n >\n <i [class]=\"node.expanded ? 'fa-solid fa-chevron-down' : 'fa-solid fa-chevron-right'\"></i>\n </button>\n }\n @if (node.children.length === 0) {\n <span class=\"expand-placeholder\"></span>\n }\n <div class=\"node-icon\" [style.backgroundColor]=\"getCategoryColor(i) + '15'\" [style.color]=\"getCategoryColor(i)\">\n <i [class]=\"node.category.IconClass || 'fa-solid fa-folder'\"></i>\n </div>\n <div class=\"node-info\">\n <div class=\"node-name\">{{node.category.Name}}</div>\n @if (node.category.Description) {\n <div class=\"node-description\">\n {{node.category.Description | slice:0:50}}{{node.category.Description.length > 50 ? '...' : ''}}\n </div>\n }\n </div>\n <div class=\"node-badges\">\n @if (node.typeCount > 0) {\n <span class=\"badge types\">\n <i class=\"fa-solid fa-shapes\"></i>\n {{node.typeCount}}\n </span>\n }\n @if (node.children.length > 0) {\n <span class=\"badge children\">\n <i class=\"fa-solid fa-folder\"></i>\n {{node.children.length}}\n </span>\n }\n </div>\n <div class=\"node-actions\">\n @if (UserCanUpdate) {\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editCategory(node, $event)\"\n title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n @if (UserCanDelete && node.children.length === 0 && node.typeCount === 0) {\n <button mjButton variant=\"danger\" size=\"sm\"\n (click)=\"deleteCategory(node, $event)\"\n title=\"Delete\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (categoryTree.length === 0) {\n <mj-empty-state\n [Variant]=\"searchText ? 'no-results' : 'empty'\"\n Icon=\"fa-solid fa-folder-open\"\n Title=\"No Categories\"\n [Message]=\"searchText ? 'No categories match your search.' : 'Get started by creating your first category.'\"\n [ActionText]=\"searchText ? 'Clear search' : (UserCanCreate ? 'Create Category' : '')\"\n [ActionIcon]=\"searchText ? 'fa-solid fa-rotate-left' : 'fa-solid fa-plus'\"\n (Action)=\"onEmptyStateAction()\" />\n }\n </div>\n <!-- Detail Panel -->\n @if (selectedNode) {\n <div class=\"detail-panel\">\n <div class=\"detail-header\">\n <div class=\"detail-icon\" [style.backgroundColor]=\"getCategoryColor(0) + '15'\" [style.color]=\"getCategoryColor(0)\">\n <i [class]=\"selectedNode.category.IconClass || 'fa-solid fa-folder'\"></i>\n </div>\n <div class=\"detail-title\">\n <h2>{{selectedNode.category.Name}}</h2>\n @if (selectedNode.level > 0) {\n <span class=\"level-badge\">\n Level {{selectedNode.level + 1}}\n </span>\n }\n </div>\n <div class=\"detail-actions\">\n @if (UserCanUpdate) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"editCategory(selectedNode)\" title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n <button class=\"close-btn\" (click)=\"selectedNode = null\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"detail-body\">\n <!-- Stats -->\n <div class=\"detail-stats\">\n <div class=\"detail-stat\">\n <div class=\"stat-value\">{{selectedNode.typeCount}}</div>\n <div class=\"stat-label\">Credential Types</div>\n </div>\n <div class=\"detail-stat\">\n <div class=\"stat-value\">{{selectedNode.children.length}}</div>\n <div class=\"stat-label\">Subcategories</div>\n </div>\n </div>\n <!-- Description -->\n @if (selectedNode.category.Description) {\n <div class=\"description-section\">\n <h3>\n <i class=\"fa-solid fa-align-left\"></i>\n Description\n </h3>\n <p class=\"description\">{{selectedNode.category.Description}}</p>\n </div>\n }\n <!-- Types in Category -->\n @if (selectedNode.typeCount > 0) {\n <div class=\"types-section\">\n <h3>\n <i class=\"fa-solid fa-shapes\"></i>\n Credential Types\n </h3>\n <div class=\"type-list\">\n @for (type of getTypesForCategory(selectedNode.category.Name); track type) {\n <div class=\"type-item\">\n <div class=\"type-icon\">\n <i [class]=\"type.IconClass || 'fa-solid fa-key'\"></i>\n </div>\n <div class=\"type-info\">\n <div class=\"type-name\">{{type.Name}}</div>\n @if (type.Description) {\n <div class=\"type-desc\">{{type.Description | slice:0:60}}</div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Subcategories -->\n @if (selectedNode.children.length > 0) {\n <div class=\"subcategories-section\">\n <h3>\n <i class=\"fa-solid fa-folder-tree\"></i>\n Subcategories\n </h3>\n <div class=\"subcategory-list\">\n @for (child of selectedNode.children; track child) {\n <div class=\"subcategory-item\" (click)=\"selectNode(child)\">\n <i [class]=\"child.category.IconClass || 'fa-solid fa-folder'\"></i>\n <span>{{child.category.Name}}</span>\n @if (child.typeCount > 0) {\n <span class=\"sub-type-count\">{{child.typeCount}} types</span>\n }\n </div>\n }\n </div>\n </div>\n }\n <!-- Quick Actions -->\n <div class=\"detail-quick-actions\">\n @if (selectedNode.typeCount > 0) {\n <button\n class=\"btn-secondary\"\n (click)=\"viewTypesForCategory(selectedNode.category.Name)\"\n >\n <i class=\"fa-solid fa-shapes\"></i>\n View Types\n </button>\n }\n <button\n class=\"btn-primary\"\n (click)=\"createCredentialWithCategory(selectedNode.category.ID)\"\n >\n <i class=\"fa-solid fa-plus\"></i>\n Create Credential\n </button>\n </div>\n </div>\n </div>\n }\n <!-- No Selection -->\n @if (!selectedNode && categoryTree.length > 0) {\n <mj-empty-state Icon=\"fa-solid fa-hand-pointer\"\n Title=\"Select a Category\"\n Message=\"Click on a category to view its details and credential types\" />\n }\n </div>\n }\n </mj-page-body>\n\n <!-- Category Edit Panel -->\n <mj-credential-category-edit-panel\n #categoryEditPanel\n (saved)=\"onCategorySaved($any($event))\"\n (deleted)=\"onCategoryDeleted($any($event))\"\n ></mj-credential-category-edit-panel>\n</mj-page-layout>\n", styles: ["/* Layout */\n.categories-layout {\n display: grid;\n grid-template-columns: 1fr 380px;\n gap: 20px;\n min-height: 500px;\n}\n\n/* Tree Panel */\n.tree-panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow: hidden;\n}\n\n.tree-container {\n max-height: calc(100vh - 300px);\n overflow-y: auto;\n}\n\n/* Tree Node */\n.tree-node {\n display: flex;\n align-items: center;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.tree-node:last-child {\n border-bottom: none;\n}\n\n.tree-node:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.tree-node.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.node-content {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n width: 100%;\n gap: 8px;\n}\n\n/* Expand Button */\n.expand-btn {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-disabled);\n border-radius: 4px;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.expand-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.expand-btn i {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.expand-placeholder {\n width: 24px;\n flex-shrink: 0;\n}\n\n/* Node Icon */\n.node-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.node-icon i {\n font-size: 14px;\n}\n\n/* Node Info */\n.node-info {\n flex: 1;\n min-width: 0;\n}\n\n.node-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n line-height: 1.3;\n}\n\n.node-description {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Node Badges */\n.node-badges {\n display: flex;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.badge {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.badge.types {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.badge.children {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.badge i {\n font-size: 10px;\n}\n\n/* Node Actions */\n.node-actions {\n display: flex;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.2s ease;\n flex-shrink: 0;\n}\n\n.tree-node:hover .node-actions {\n opacity: 1;\n}\n\n.action-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-radius: 6px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.action-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.action-btn.danger:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n.action-btn i {\n font-size: 12px;\n}\n\n/* Detail Panel */\n.detail-panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.detail-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 20px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.detail-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 12px;\n flex-shrink: 0;\n}\n\n.detail-icon i {\n font-size: 20px;\n}\n\n.detail-title {\n flex: 1;\n min-width: 0;\n}\n\n.detail-title h2 {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n line-height: 1.3;\n}\n\n.level-badge {\n display: inline-block;\n margin-top: 4px;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.detail-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.close-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n/* Detail Body */\n.detail-body {\n padding: 20px;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Detail Stats */\n.detail-stats {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.detail-stat {\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n padding: 16px;\n text-align: center;\n}\n\n.detail-stat .stat-value {\n font-size: 28px;\n font-weight: 700;\n color: var(--mj-brand-primary);\n line-height: 1;\n}\n\n.detail-stat .stat-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n}\n\n/* Description Section */\n.description-section {\n margin-bottom: 20px;\n}\n\n.description-section h3,\n.types-section h3,\n.subcategories-section h3 {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin: 0 0 12px 0;\n}\n\n.description-section h3 i,\n.types-section h3 i,\n.subcategories-section h3 i {\n font-size: 12px;\n}\n\n.description {\n font-size: 14px;\n color: var(--mj-text-primary);\n line-height: 1.6;\n margin: 0;\n}\n\n/* Types Section */\n.types-section {\n margin-bottom: 20px;\n}\n\n.type-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.type-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n.type-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.type-icon {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-radius: 6px;\n flex-shrink: 0;\n}\n\n.type-icon i {\n font-size: 12px;\n color: var(--mj-brand-primary);\n}\n\n.type-info {\n flex: 1;\n min-width: 0;\n}\n\n.type-name {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.type-desc {\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Subcategories Section */\n.subcategories-section {\n margin-bottom: 20px;\n}\n\n.subcategory-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.subcategory-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.subcategory-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.subcategory-item i {\n font-size: 14px;\n color: var(--mj-brand-primary);\n}\n\n.subcategory-item span {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.sub-type-count {\n font-size: 11px;\n color: var(--mj-text-secondary);\n background: var(--mj-border-default);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n/* Quick Actions */\n.detail-quick-actions {\n margin-top: auto;\n padding-top: 16px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n display: flex;\n gap: 8px;\n}\n\n.detail-quick-actions .btn-secondary,\n.detail-quick-actions .btn-primary {\n flex: 1;\n}\n\n.btn-secondary {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-secondary:hover {\n background: var(--mj-border-default);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .categories-layout {\n grid-template-columns: 1fr;\n }\n\n .detail-panel {\n display: none;\n }\n}\n\n@media (max-width: 768px) {\n .categories-container {\n padding: 16px;\n }\n\n .categories-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 16px;\n }\n\n .toolbar {\n flex-direction: column;\n gap: 12px;\n }\n\n .toolbar-left,\n .toolbar-right {\n width: 100%;\n }\n\n .search-container {\n max-width: none;\n }\n\n .toolbar-right {\n justify-content: flex-end;\n }\n}\n"] }]
|
|
771
|
-
}], () => [{ type: i0.ChangeDetectorRef }], { categoryEditPanel: [{
|
|
777
|
+
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.MJConfirmService }], { categoryEditPanel: [{
|
|
772
778
|
type: ViewChild,
|
|
773
779
|
args: ['categoryEditPanel']
|
|
774
780
|
}] }); })();
|
|
775
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsCategoriesResourceComponent, { className: "CredentialsCategoriesResourceComponent", filePath: "src/Credentials/components/credentials-categories-resource.component.ts", lineNumber:
|
|
781
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CredentialsCategoriesResourceComponent, { className: "CredentialsCategoriesResourceComponent", filePath: "src/Credentials/components/credentials-categories-resource.component.ts", lineNumber: 25 }); })();
|
|
776
782
|
//# sourceMappingURL=credentials-categories-resource.component.js.map
|