@memberjunction/ng-conversations 6.1.0-edge.4 → 6.1.0-edge.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +9 -0
  2. package/dist/lib/components/active-tasks/active-tasks-panel.component.js +1 -1
  3. package/dist/lib/components/agent/active-agent-indicator.component.js +1 -1
  4. package/dist/lib/components/attachment/image-viewer.component.js +1 -1
  5. package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +1 -1
  6. package/dist/lib/components/collection/collection-tree.component.js +55 -56
  7. package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
  8. package/dist/lib/components/collection/collection-view.component.js +1 -1
  9. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  10. package/dist/lib/components/collection/collections-full-view.component.js +1 -1
  11. package/dist/lib/components/composer/ai-composer.component.d.ts +9 -1
  12. package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -1
  13. package/dist/lib/components/composer/ai-composer.component.js +16 -3
  14. package/dist/lib/components/composer/ai-composer.component.js.map +1 -1
  15. package/dist/lib/components/conversation/conversation-agent-picker.component.js +2 -2
  16. package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
  17. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +118 -11
  18. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  19. package/dist/lib/components/conversation/conversation-chat-area.component.js +333 -77
  20. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  21. package/dist/lib/components/conversation/conversation-empty-state.component.js +1 -1
  22. package/dist/lib/components/conversation/conversation-list.component.js +22 -23
  23. package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
  24. package/dist/lib/components/conversation/conversation-mode-picker.component.js +10 -11
  25. package/dist/lib/components/conversation/conversation-mode-picker.component.js.map +1 -1
  26. package/dist/lib/components/conversation/pinned-messages-panel.component.js +1 -1
  27. package/dist/lib/components/dialogs/rating-dialog.component.js +1 -1
  28. package/dist/lib/components/global-tasks/global-tasks-panel.component.js +1 -1
  29. package/dist/lib/components/message/actionable-commands.component.js +1 -1
  30. package/dist/lib/components/message/message-input.component.d.ts +75 -1
  31. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  32. package/dist/lib/components/message/message-input.component.js +260 -73
  33. package/dist/lib/components/message/message-input.component.js.map +1 -1
  34. package/dist/lib/components/message/message-item.component.d.ts +40 -1
  35. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  36. package/dist/lib/components/message/message-item.component.js +222 -117
  37. package/dist/lib/components/message/message-item.component.js.map +1 -1
  38. package/dist/lib/components/message/message-list.component.d.ts +35 -0
  39. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  40. package/dist/lib/components/message/message-list.component.js +107 -23
  41. package/dist/lib/components/message/message-list.component.js.map +1 -1
  42. package/dist/lib/components/message/workflow-plan-card.component.js +1 -1
  43. package/dist/lib/components/navigation/conversation-navigation.component.js +1 -1
  44. package/dist/lib/components/notification/notification-badge.component.js +1 -1
  45. package/dist/lib/components/overlay/chat-overlay.component.js +2 -2
  46. package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
  47. package/dist/lib/components/project/project-form-modal.component.js +1 -1
  48. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js +1 -1
  49. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js +1 -1
  50. package/dist/lib/components/realtime/media/realtime-media-surface.component.js +1 -1
  51. package/dist/lib/components/realtime/realtime-activity-rail.component.js +1 -1
  52. package/dist/lib/components/realtime/realtime-agent-banner.component.js +2 -2
  53. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  54. package/dist/lib/components/realtime/realtime-agent-picker.component.js +6 -6
  55. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
  56. package/dist/lib/components/realtime/realtime-composer.component.js +2 -2
  57. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  58. package/dist/lib/components/realtime/realtime-delegation-card.component.js +1 -1
  59. package/dist/lib/components/realtime/realtime-session-overlay.component.js +1 -1
  60. package/dist/lib/components/realtime/realtime-session-thread.component.js +1 -1
  61. package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +1 -1
  62. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +1 -1
  63. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +65 -1
  64. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
  65. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +134 -41
  66. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
  67. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +1 -1
  68. package/dist/lib/components/search/search-panel.component.js +2 -2
  69. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  70. package/dist/lib/components/sidebar/routines-section.component.js +1 -1
  71. package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
  72. package/dist/lib/components/tasks/tasks-dropdown.component.js +1 -1
  73. package/dist/lib/components/thread/thread-panel.component.js +1 -1
  74. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  75. package/dist/lib/components/workspace/conversation-workspace.component.js +14 -4
  76. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  77. package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts +6 -0
  78. package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts.map +1 -1
  79. package/dist/lib/composer-plugins/base-conversation-mention.provider.js +7 -1
  80. package/dist/lib/composer-plugins/base-conversation-mention.provider.js.map +1 -1
  81. package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
  82. package/dist/lib/services/active-tasks.service.js +9 -7
  83. package/dist/lib/services/active-tasks.service.js.map +1 -1
  84. package/dist/lib/services/composer-draft-store.d.ts.map +1 -1
  85. package/dist/lib/services/composer-draft-store.js +5 -2
  86. package/dist/lib/services/composer-draft-store.js.map +1 -1
  87. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  88. package/dist/lib/services/conversation-agent.service.js +7 -8
  89. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  90. package/dist/lib/services/mention-autocomplete.service.d.ts +16 -2
  91. package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
  92. package/dist/lib/services/mention-autocomplete.service.js +38 -9
  93. package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
  94. package/dist/lib/services/realtime-session.service.d.ts +188 -1
  95. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  96. package/dist/lib/services/realtime-session.service.js +228 -25
  97. package/dist/lib/services/realtime-session.service.js.map +1 -1
  98. package/dist/lib/services/skill-picker-narrowing.d.ts +13 -0
  99. package/dist/lib/services/skill-picker-narrowing.d.ts.map +1 -0
  100. package/dist/lib/services/skill-picker-narrowing.js +13 -0
  101. package/dist/lib/services/skill-picker-narrowing.js.map +1 -0
  102. package/dist/lib/utils/artifact-panel-action.d.ts +89 -0
  103. package/dist/lib/utils/artifact-panel-action.d.ts.map +1 -0
  104. package/dist/lib/utils/artifact-panel-action.js +122 -0
  105. package/dist/lib/utils/artifact-panel-action.js.map +1 -0
  106. package/dist/lib/utils/distinct-artifacts.d.ts +8 -0
  107. package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
  108. package/dist/lib/utils/distinct-artifacts.js +12 -2
  109. package/dist/lib/utils/distinct-artifacts.js.map +1 -1
  110. package/package.json +39 -39
@@ -1 +1 @@
1
- {"version":3,"file":"collection-view.component.js","sourceRoot":"","sources":["../../../../src/lib/components/collection/collection-view.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, OnInit, OnChanges, OnDestroy, SimpleChanges, ChangeDetectorRef } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MJCollectionEntity, MJArtifactEntity, MJArtifactVersionEntity, MJCollectionArtifactEntity } from '@memberjunction/core-entities';\nimport { UserInfo, RunView, Metadata } from '@memberjunction/core';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { MJConfirmService } from '@memberjunction/ng-ui-components';\n\ntype ViewMode = 'grid' | 'list';\ntype SortBy = 'name' | 'date' | 'type';\n\n@Component({\n standalone: false,\n selector: 'mj-collection-view',\n template: `\n <div class=\"collection-view\">\n <div class=\"view-header\">\n <h2>{{ collection.Name || 'Collection' }}</h2>\n <div class=\"header-actions\">\n <div class=\"view-mode-toggle\">\n <button\n class=\"mode-btn\"\n [class.active]=\"viewMode === 'grid'\"\n (click)=\"viewMode = 'grid'\"\n title=\"Grid View\">\n <i class=\"fas fa-grid\"></i>\n </button>\n <button\n class=\"mode-btn\"\n [class.active]=\"viewMode === 'list'\"\n (click)=\"viewMode = 'list'\"\n title=\"List View\">\n <i class=\"fas fa-list\"></i>\n </button>\n </div>\n \n <select\n [(ngModel)]=\"sortBy\"\n (ngModelChange)=\"onSortChange()\"\n class=\"mj-select\"\n style=\"width: 150px;\">\n @for (option of sortOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n \n @if (canEdit) {\n <button class=\"btn-add\" (click)=\"onAddArtifact()\" title=\"Add Artifact\">\n <i class=\"fas fa-plus\"></i> Add\n </button>\n }\n </div>\n </div>\n \n <div class=\"view-content\" [class.grid-mode]=\"viewMode === 'grid'\" [class.list-mode]=\"viewMode === 'list'\">\n @if (artifactVersions.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-folder-open\"\n Title=\"This collection is empty\"\n [ActionText]=\"canEdit ? 'Add Artifact' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"onAddArtifact()\" />\n }\n \n @for (item of artifactVersions; track item.version.ID) {\n <mj-collection-artifact-card\n [artifact]=\"item.artifact\"\n [version]=\"item.version\"\n (selected)=\"onArtifactSelected(item)\"\n (viewed)=\"onViewArtifact(item)\"\n (edited)=\"onEditArtifact(item)\"\n (removed)=\"onRemoveArtifact(item)\">\n </mj-collection-artifact-card>\n }\n </div>\n </div>\n \n <!-- Artifact Viewer Panel -->\n @if (showArtifactViewer && selectedArtifactId) {\n <div class=\"artifact-viewer-overlay\" (click)=\"onCloseArtifactViewer()\">\n <div class=\"artifact-viewer-container\" (click)=\"$event.stopPropagation()\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [versionNumber]=\"selectedVersionNumber\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [viewContext]=\"'collection'\"\n [contextCollectionId]=\"collection.ID\"\n (closed)=\"onCloseArtifactViewer()\">\n </mj-artifact-viewer-panel>\n </div>\n </div>\n }\n `,\n styles: [`\n .collection-view { display: flex; flex-direction: column; height: 100%; background: var(--mj-bg-surface); }\n\n .view-header { padding: 20px 24px; border-bottom: 1px solid var(--mj-border-default); display: flex; justify-content: space-between; align-items: center; }\n .view-header h2 { margin: 0; font-size: 20px; flex: 1; }\n\n .header-actions { display: flex; align-items: center; gap: 12px; }\n\n .view-mode-toggle { display: flex; border: 1px solid var(--mj-border-default); border-radius: 4px; overflow: hidden; }\n .mode-btn { padding: 8px 12px; background: var(--mj-bg-surface); border: none; border-right: 1px solid var(--mj-border-default); cursor: pointer; color: var(--mj-text-muted); transition: all 150ms ease; }\n .mode-btn:last-child { border-right: none; }\n .mode-btn:hover { background: var(--mj-bg-surface-sunken); }\n .mode-btn.active { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n\n .btn-add { padding: 8px 16px; background: var(--mj-brand-primary); color: var(--mj-text-inverse); border: none; border-radius: 4px; cursor: pointer; display: flex; align-items: center; gap: 6px; }\n .btn-add:hover { background: var(--mj-brand-primary-hover); }\n\n .view-content { flex: 1; overflow-y: auto; padding: 24px; }\n .view-content.grid-mode { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }\n .view-content.list-mode { display: flex; flex-direction: column; gap: 12px; }\n\n .artifact-viewer-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: var(--mj-bg-overlay); display: flex; align-items: center; justify-content: center; z-index: 10000; }\n .artifact-viewer-container { width: 90%; max-width: 1200px; height: 90vh; background: var(--mj-bg-surface); border-radius: 12px; overflow: hidden; box-shadow: var(--mj-shadow-lg); }\n `]\n})\nexport class CollectionViewComponent extends BaseAngularComponent implements OnInit, OnChanges, OnDestroy {\n @Input() collection!: MJCollectionEntity;\n @Input() currentUser!: UserInfo;\n @Input() environmentId!: string;\n @Input() canEdit: boolean = true;\n\n // Store versions with parent artifact info for display\n public artifactVersions: Array<{\n version: MJArtifactVersionEntity;\n artifact: MJArtifactEntity;\n }> = [];\n public viewMode: ViewMode = 'grid';\n public sortBy: SortBy = 'date';\n public selectedArtifactId: string | null = null;\n public selectedVersionNumber: number | undefined = undefined;\n public showArtifactViewer = false;\n\n public sortOptions = [\n { label: 'Name', value: 'name' },\n { label: 'Date Modified', value: 'date' },\n { label: 'Type', value: 'type' }\n ];\n\n constructor(private cdr: ChangeDetectorRef, private confirmService: MJConfirmService) {\n super();}\n\n ngOnInit() {\n this.loadArtifacts();\n }\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes['collection'] && !changes['collection'].firstChange) {\n this.loadArtifacts();\n }\n }\n\n ngOnDestroy() {\n // Close artifact viewer when navigating away from collection\n if (this.showArtifactViewer) {\n this.onCloseArtifactViewer();\n }\n }\n\n private async loadArtifacts(): Promise<void> {\n if (!this.collection) return;\n\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const md = this.ProviderToUse;\n\n // Load ALL VERSIONS in this collection (no DISTINCT - each version is separate)\n const versionResult = await rv.RunView<MJArtifactVersionEntity>({\n EntityName: 'MJ: Artifact Versions',\n ExtraFilter: `ID IN (\n SELECT ca.ArtifactVersionID\n FROM [__mj].[vwCollectionArtifacts] ca\n WHERE ca.CollectionID='${this.collection.ID}'\n )`,\n OrderBy: this.getVersionOrderBy(),\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (versionResult.Success && versionResult.Results) {\n // Get unique artifact IDs\n const artifactIds = [...new Set(versionResult.Results.map(v => v.ArtifactID))];\n\n // Load parent artifact info (just for display metadata - no visibility filtering)\n const artifactMap = new Map<string, MJArtifactEntity>();\n if (artifactIds.length > 0) {\n const artifactFilter = artifactIds.map(id => `ID='${id}'`).join(' OR ');\n const artifactResult = await rv.RunView<MJArtifactEntity>({\n EntityName: 'MJ: Artifacts',\n ExtraFilter: artifactFilter,\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (artifactResult.Success && artifactResult.Results) {\n artifactResult.Results.forEach(a => artifactMap.set(a.ID, a));\n }\n }\n\n // Combine version + artifact info\n this.artifactVersions = versionResult.Results\n .map(version => ({\n version,\n artifact: artifactMap.get(version.ArtifactID)!\n }))\n .filter(item => item.artifact != null); // Filter out any without parent artifact\n } else {\n this.artifactVersions = [];\n }\n } catch (error) {\n console.error('Failed to load collection artifacts:', error);\n this.artifactVersions = [];\n }\n }\n\n private getVersionOrderBy(): string {\n switch (this.sortBy) {\n case 'name':\n return 'Name ASC, VersionNumber DESC';\n case 'type':\n // Will sort by parent artifact type (handled in template)\n return 'ArtifactID ASC, VersionNumber DESC';\n case 'date':\n default:\n return '__mj_UpdatedAt DESC';\n }\n }\n\n onSortChange(): void {\n this.loadArtifacts();\n }\n\n onArtifactSelected(item: { version: MJArtifactVersionEntity; artifact: MJArtifactEntity }): void {\n // TODO: Emit event or navigate to artifact detail view\n }\n\n onViewArtifact(item: { version: MJArtifactVersionEntity; artifact: MJArtifactEntity }): void {\n this.selectedArtifactId = item.artifact.ID;\n this.selectedVersionNumber = item.version.VersionNumber;\n // Force change detection to ensure Input bindings propagate before component creation\n this.cdr.detectChanges();\n this.showArtifactViewer = true;\n }\n\n onCloseArtifactViewer(): void {\n this.showArtifactViewer = false;\n this.selectedArtifactId = null;\n this.selectedVersionNumber = undefined;\n }\n\n onEditArtifact(item: { version: MJArtifactVersionEntity; artifact: MJArtifactEntity }): void {\n // TODO: Open artifact editor\n }\n\n async onRemoveArtifact(item: { version: MJArtifactVersionEntity; artifact: MJArtifactEntity }): Promise<void> {\n const versionLabel = `\"${item.artifact.Name}\" v${item.version.VersionNumber}`;\n if (!(await this.confirmService.ConfirmDelete({ title: 'Remove from Collection', message: `Remove ${versionLabel} from this collection?`, confirmText: 'Remove' }))) return;\n\n try {\n // Delete THIS SPECIFIC VERSION from the collection\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView({\n EntityName: 'MJ: Collection Artifacts',\n ExtraFilter: `CollectionID='${this.collection.ID}' AND ArtifactVersionID='${item.version.ID}'`,\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (result.Success && result.Results && result.Results.length > 0) {\n // Delete all version associations atomically\n const md = this.ProviderToUse;\n const tg = await md.CreateTransactionGroup();\n for (const joinRecord of result.Results) {\n joinRecord.TransactionGroup = tg;\n await joinRecord.Delete();\n }\n const success = await tg.Submit();\n if (!success) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Failed to remove ${versionLabel} from collection`,\n 'error'\n );\n return;\n }\n await this.loadArtifacts();\n this.cdr.detectChanges();\n MJNotificationService.Instance.CreateSimpleNotification(\n `Removed ${versionLabel} from collection`,\n 'success',\n 3000\n );\n }\n } catch (error) {\n console.error('Failed to remove artifact version from collection:', error);\n MJNotificationService.Instance.CreateSimpleNotification(\n 'Failed to remove artifact version from collection',\n 'error'\n );\n }\n }\n\n async onAddArtifact(): Promise<void> {\n // TODO: Open artifact picker dialog\n // For now, just show a simple prompt\n const name = prompt('Enter artifact name:');\n if (!name) return;\n\n try {\n // Create new artifact\n const md = this.ProviderToUse;\n const artifact = await md.GetEntityObject<MJArtifactEntity>('MJ: Artifacts', this.currentUser);\n\n artifact.Name = name;\n // Type is read-only, set via TypeID instead\n // For now, skip setting type - it has a default\n\n const saved = await artifact.Save();\n if (saved) {\n // Get the latest version of this artifact to add to collection\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const versionResult = await rv.RunView({\n EntityName: 'MJ: Artifact Versions',\n ExtraFilter: `ArtifactID='${artifact.ID}'`,\n OrderBy: 'VersionNumber DESC',\n MaxRows: 1,\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (!versionResult.Success || !versionResult.Results || versionResult.Results.length === 0) {\n alert('Failed to get artifact version');\n return;\n }\n\n // Add to collection via join table using version ID\n const joinRecord = await md.GetEntityObject<MJCollectionArtifactEntity>('MJ: Collection Artifacts', this.currentUser);\n joinRecord.CollectionID = this.collection.ID;\n joinRecord.ArtifactVersionID = versionResult.Results[0].ID;\n\n await joinRecord.Save();\n await this.loadArtifacts();\n }\n } catch (error) {\n console.error('Failed to add artifact:', error);\n alert('Failed to add artifact');\n }\n }\n}"]}
1
+ {"version":3,"file":"collection-view.component.js","sourceRoot":"","sources":["../../../../src/lib/components/collection/collection-view.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, OnInit, OnChanges, OnDestroy, SimpleChanges, ChangeDetectorRef } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MJCollectionEntity, MJArtifactEntity, MJArtifactVersionEntity, MJCollectionArtifactEntity } from '@memberjunction/core-entities';\nimport { UserInfo, RunView, Metadata } from '@memberjunction/core';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { MJConfirmService } from '@memberjunction/ng-ui-components';\n\ntype ViewMode = 'grid' | 'list';\ntype SortBy = 'name' | 'date' | 'type';\n\n@Component({\n standalone: false,\n selector: 'mj-collection-view',\n template: `\n <div class=\"collection-view\">\n <div class=\"view-header\">\n <h2>{{ collection.Name || 'Collection' }}</h2>\n <div class=\"header-actions\">\n <div class=\"view-mode-toggle\">\n <button\n class=\"mode-btn\"\n [class.active]=\"viewMode === 'grid'\"\n (click)=\"viewMode = 'grid'\"\n title=\"Grid View\">\n <i class=\"fas fa-grid\"></i>\n </button>\n <button\n class=\"mode-btn\"\n [class.active]=\"viewMode === 'list'\"\n (click)=\"viewMode = 'list'\"\n title=\"List View\">\n <i class=\"fas fa-list\"></i>\n </button>\n </div>\n \n <select\n [(ngModel)]=\"sortBy\"\n (ngModelChange)=\"onSortChange()\"\n class=\"mj-select\"\n style=\"width: 150px;\">\n @for (option of sortOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n \n @if (canEdit) {\n <button class=\"btn-add\" (click)=\"onAddArtifact()\" title=\"Add Artifact\">\n <i class=\"fas fa-plus\"></i> Add\n </button>\n }\n </div>\n </div>\n \n <div class=\"view-content\" [class.grid-mode]=\"viewMode === 'grid'\" [class.list-mode]=\"viewMode === 'list'\">\n @if (artifactVersions.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-folder-open\"\n Title=\"This collection is empty\"\n [ActionText]=\"canEdit ? 'Add Artifact' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"onAddArtifact()\" />\n }\n \n @for (item of artifactVersions; track item.version.ID) {\n <mj-collection-artifact-card\n [artifact]=\"item.artifact\"\n [version]=\"item.version\"\n (selected)=\"onArtifactSelected(item)\"\n (viewed)=\"onViewArtifact(item)\"\n (edited)=\"onEditArtifact(item)\"\n (removed)=\"onRemoveArtifact(item)\">\n </mj-collection-artifact-card>\n }\n </div>\n </div>\n \n <!-- Artifact Viewer Panel -->\n @if (showArtifactViewer && selectedArtifactId) {\n <div class=\"artifact-viewer-overlay\" (click)=\"onCloseArtifactViewer()\">\n <div class=\"artifact-viewer-container\" (click)=\"$event.stopPropagation()\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [versionNumber]=\"selectedVersionNumber\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [viewContext]=\"'collection'\"\n [contextCollectionId]=\"collection.ID\"\n (closed)=\"onCloseArtifactViewer()\">\n </mj-artifact-viewer-panel>\n </div>\n </div>\n }\n `,\n styles: [`\n .collection-view { display: flex; flex-direction: column; height: 100%; background: var(--mj-bg-surface); }\n\n .view-header { padding: 20px 24px; border-bottom: 1px solid var(--mj-border-default); display: flex; justify-content: space-between; align-items: center; }\n .view-header h2 { margin: 0; font-size: 20px; flex: 1; }\n\n .header-actions { display: flex; align-items: center; gap: 12px; }\n\n .view-mode-toggle { display: flex; border: 1px solid var(--mj-border-default); border-radius: 4px; overflow: hidden; }\n .mode-btn { padding: 8px 12px; background: var(--mj-bg-surface); border: none; border-right: 1px solid var(--mj-border-default); cursor: pointer; color: var(--mj-text-muted); transition: all 150ms ease; }\n .mode-btn:last-child { border-right: none; }\n .mode-btn:hover { background: var(--mj-bg-surface-sunken); }\n .mode-btn.active { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n\n .btn-add { padding: 8px 16px; background: var(--mj-brand-primary); color: var(--mj-text-inverse); border: none; border-radius: 4px; cursor: pointer; display: flex; align-items: center; gap: 6px; }\n .btn-add:hover { background: var(--mj-brand-primary-hover); }\n\n .view-content { flex: 1; overflow-y: auto; padding: 24px; }\n .view-content.grid-mode { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }\n .view-content.list-mode { display: flex; flex-direction: column; gap: 12px; }\n\n .artifact-viewer-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: var(--mj-bg-overlay); display: flex; align-items: center; justify-content: center; z-index: 10000; }\n .artifact-viewer-container { width: 90%; max-width: 1200px; height: 90vh; background: var(--mj-bg-surface); border-radius: 12px; overflow: hidden; box-shadow: var(--mj-shadow-lg); }\n `]\n})\nexport class CollectionViewComponent extends BaseAngularComponent implements OnInit, OnChanges, OnDestroy {\n @Input() collection!: MJCollectionEntity;\n @Input() currentUser!: UserInfo;\n @Input() environmentId!: string;\n @Input() canEdit: boolean = true;\n\n // Store versions with parent artifact info for display\n public artifactVersions: Array<{\n version: MJArtifactVersionEntity;\n artifact: MJArtifactEntity;\n }> = [];\n public viewMode: ViewMode = 'grid';\n public sortBy: SortBy = 'date';\n public selectedArtifactId: string | null = null;\n public selectedVersionNumber: number | undefined = undefined;\n public showArtifactViewer = false;\n\n public sortOptions = [\n { label: 'Name', value: 'name' },\n { label: 'Date Modified', value: 'date' },\n { label: 'Type', value: 'type' }\n ];\n\n constructor(private cdr: ChangeDetectorRef, private confirmService: MJConfirmService) {\n super();}\n\n ngOnInit() {\n this.loadArtifacts();\n }\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes['collection'] && !changes['collection'].firstChange) {\n this.loadArtifacts();\n }\n }\n\n ngOnDestroy() {\n // Close artifact viewer when navigating away from collection\n if (this.showArtifactViewer) {\n this.onCloseArtifactViewer();\n }\n }\n\n private async loadArtifacts(): Promise<void> {\n if (!this.collection) return;\n\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const md = this.ProviderToUse;\n\n // Load ALL VERSIONS in this collection (no DISTINCT - each version is separate)\n const versionResult = await rv.RunView<MJArtifactVersionEntity>({\n EntityName: 'MJ: Artifact Versions',\n ExtraFilter: `ID IN (\n SELECT ca.ArtifactVersionID\n FROM [__mj].[vwCollectionArtifacts] ca\n WHERE ca.CollectionID='${this.collection.ID}'\n )`,\n OrderBy: this.getVersionOrderBy(),\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (versionResult.Success && versionResult.Results) {\n // Get unique artifact IDs\n const artifactIds = [...new Set(versionResult.Results.map(v => v.ArtifactID))];\n\n // Load parent artifact info (just for display metadata - no visibility filtering)\n const artifactMap = new Map<string, MJArtifactEntity>();\n if (artifactIds.length > 0) {\n const artifactFilter = artifactIds.map(id => `ID='${id}'`).join(' OR ');\n const artifactResult = await rv.RunView<MJArtifactEntity>({\n EntityName: 'MJ: Artifacts',\n ExtraFilter: artifactFilter,\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (artifactResult.Success && artifactResult.Results) {\n artifactResult.Results.forEach(a => artifactMap.set(a.ID, a));\n }\n }\n\n // Combine version + artifact info\n this.artifactVersions = versionResult.Results\n .map(version => ({\n version,\n artifact: artifactMap.get(version.ArtifactID)!\n }))\n .filter(item => item.artifact != null); // Filter out any without parent artifact\n } else {\n this.artifactVersions = [];\n }\n } catch (error) {\n console.error('Failed to load collection artifacts:', error);\n this.artifactVersions = [];\n }\n }\n\n private getVersionOrderBy(): string {\n switch (this.sortBy) {\n case 'name':\n return 'Name ASC, VersionNumber DESC';\n case 'type':\n // Will sort by parent artifact type (handled in template)\n return 'ArtifactID ASC, VersionNumber DESC';\n case 'date':\n default:\n return '__mj_UpdatedAt DESC';\n }\n }\n\n onSortChange(): void {\n this.loadArtifacts();\n }\n\n onArtifactSelected(item: { version: MJArtifactVersionEntity; artifact: MJArtifactEntity }): void {\n // TODO: Emit event or navigate to artifact detail view\n }\n\n onViewArtifact(item: { version: MJArtifactVersionEntity; artifact: MJArtifactEntity }): void {\n this.selectedArtifactId = item.artifact.ID;\n this.selectedVersionNumber = item.version.VersionNumber;\n // Force change detection to ensure Input bindings propagate before component creation\n this.cdr.detectChanges();\n this.showArtifactViewer = true;\n }\n\n onCloseArtifactViewer(): void {\n this.showArtifactViewer = false;\n this.selectedArtifactId = null;\n this.selectedVersionNumber = undefined;\n }\n\n onEditArtifact(item: { version: MJArtifactVersionEntity; artifact: MJArtifactEntity }): void {\n // TODO: Open artifact editor\n }\n\n async onRemoveArtifact(item: { version: MJArtifactVersionEntity; artifact: MJArtifactEntity }): Promise<void> {\n const versionLabel = `\"${item.artifact.Name}\" v${item.version.VersionNumber}`;\n if (!(await this.confirmService.ConfirmDelete({ title: 'Remove from Collection', message: `Remove ${versionLabel} from this collection?`, confirmText: 'Remove' }))) return;\n\n try {\n // Delete THIS SPECIFIC VERSION from the collection\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView({\n EntityName: 'MJ: Collection Artifacts',\n ExtraFilter: `CollectionID='${this.collection.ID}' AND ArtifactVersionID='${item.version.ID}'`,\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (result.Success && result.Results && result.Results.length > 0) {\n // Delete all version associations atomically\n const md = this.ProviderToUse;\n const tg = await md.CreateTransactionGroup();\n for (const joinRecord of result.Results) {\n joinRecord.TransactionGroup = tg;\n await joinRecord.Delete();\n }\n const success = await tg.Submit();\n if (!success) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Failed to remove ${versionLabel} from collection`,\n 'error'\n );\n return;\n }\n await this.loadArtifacts();\n this.cdr.detectChanges();\n MJNotificationService.Instance.CreateSimpleNotification(\n `Removed ${versionLabel} from collection`,\n 'success',\n 3000\n );\n }\n } catch (error) {\n console.error('Failed to remove artifact version from collection:', error);\n MJNotificationService.Instance.CreateSimpleNotification(\n 'Failed to remove artifact version from collection',\n 'error'\n );\n }\n }\n\n async onAddArtifact(): Promise<void> {\n // TODO: Open artifact picker dialog\n // For now, just show a simple prompt\n const name = prompt('Enter artifact name:');\n if (!name) return;\n\n try {\n // Create new artifact\n const md = this.ProviderToUse;\n const artifact = await md.GetEntityObject<MJArtifactEntity>('MJ: Artifacts', this.currentUser);\n\n artifact.Name = name;\n // Type is read-only, set via TypeID instead\n // For now, skip setting type - it has a default\n\n const saved = await artifact.Save();\n if (saved) {\n // Get the latest version of this artifact to add to collection\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const versionResult = await rv.RunView({\n EntityName: 'MJ: Artifact Versions',\n ExtraFilter: `ArtifactID='${artifact.ID}'`,\n OrderBy: 'VersionNumber DESC',\n MaxRows: 1,\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (!versionResult.Success || !versionResult.Results || versionResult.Results.length === 0) {\n alert('Failed to get artifact version');\n return;\n }\n\n // Add to collection via join table using version ID\n const joinRecord = await md.GetEntityObject<MJCollectionArtifactEntity>('MJ: Collection Artifacts', this.currentUser);\n joinRecord.CollectionID = this.collection.ID;\n joinRecord.ArtifactVersionID = versionResult.Results[0].ID;\n\n await joinRecord.Save();\n await this.loadArtifacts();\n }\n } catch (error) {\n console.error('Failed to add artifact:', error);\n alert('Failed to add artifact');\n }\n }\n}"]}
@@ -2742,7 +2742,7 @@ export class CollectionsFullViewComponent extends BaseAngularComponent {
2742
2742
  i0.ɵɵproperty("isOpen", ctx.isArtifactModalOpen)("collectionId", ctx.currentCollectionId || "")("environmentId", ctx.environmentId)("currentUser", ctx.currentUser);
2743
2743
  i0.ɵɵadvance();
2744
2744
  i0.ɵɵproperty("isOpen", ctx.isShareModalOpen)("collection", ctx.sharingCollection)("currentUser", ctx.currentUser)("currentUserPermissions", ctx.sharingCollection ? ctx.userPermissions.get(ctx.sharingCollection.ID) || null : null);
2745
- } }, dependencies: [i6.NgClass, i7.DefaultValueAccessor, i7.NgControlStatus, i7.NgModel, i8.MJEmptyStateComponent, i9.LoadingComponent, i10.CollectionShareModalComponent, i11.CollectionFormModalComponent, i12.ArtifactCreateModalComponent, i6.DatePipe], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n }\n\n \n\n .collections-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n position: relative;\n }\n\n \n\n .collections-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n gap: 16px;\n background: var(--mj-bg-surface);\n }\n\n .collections-breadcrumb[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 1;\n min-width: 0;\n }\n\n .breadcrumb-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .breadcrumb-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 14px;\n }\n\n .breadcrumb-link[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 500;\n cursor: pointer;\n text-decoration: none;\n white-space: nowrap;\n transition: color 150ms ease;\n font-size: 14px;\n }\n\n .breadcrumb-link[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n }\n\n .breadcrumb-link.active[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n cursor: default;\n }\n\n .breadcrumb-path[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n overflow-x: auto;\n }\n\n .breadcrumb-separator[_ngcontent-%COMP%] {\n color: var(--mj-border-strong);\n font-size: 10px;\n }\n\n .collections-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n \n\n .btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 6px;\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 150ms ease;\n }\n\n .btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n }\n\n .btn-primary[_ngcontent-%COMP%] i.fa-chevron-down[_ngcontent-%COMP%] {\n font-size: 10px;\n margin-left: 2px;\n }\n\n .btn-icon[_ngcontent-%COMP%] {\n padding: 6px 10px;\n background: transparent;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 150ms ease;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border-color: var(--mj-text-disabled);\n }\n\n .btn-icon.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n }\n\n .btn-icon.active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n }\n\n \n\n .dropdown-container[_ngcontent-%COMP%] {\n position: relative;\n }\n\n .dropdown-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n min-width: 200px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n padding: 4px;\n z-index: 1000;\n }\n\n .dropdown-menu-right[_ngcontent-%COMP%] {\n left: auto;\n right: 0;\n }\n\n .dropdown-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 100ms ease;\n }\n\n .dropdown-item[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n }\n\n .dropdown-item[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .dropdown-item.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .dropdown-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n width: 16px;\n text-align: center;\n color: var(--mj-text-muted);\n }\n\n .dropdown-item.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .dropdown-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n }\n\n \n\n .search-container[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n min-width: 200px;\n }\n\n .search-container[_ngcontent-%COMP%] i.fa-search[_ngcontent-%COMP%] {\n position: absolute;\n left: 10px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n pointer-events: none;\n }\n\n .search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 6px 32px 6px 32px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 13px;\n outline: none;\n transition: all 150ms ease;\n }\n\n .search-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n .search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 6px;\n padding: 4px;\n background: transparent;\n border: none;\n color: var(--mj-text-disabled);\n cursor: pointer;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .search-clear[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n \n\n .selection-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 20px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n }\n\n .selection-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .selection-count[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n }\n\n .selection-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n }\n\n .btn-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n }\n\n .btn-toolbar[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n }\n\n .btn-toolbar.btn-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface));\n }\n\n .btn-toolbar.btn-danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-color: var(--mj-status-error);\n }\n\n \n\n .collections-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n }\n\n \n\n .loading-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 0;\n color: var(--mj-text-disabled);\n text-align: center;\n padding: 24px;\n }\n\n .collections-content[_ngcontent-%COMP%] mj-empty-state[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n }\n\n .empty-collection-hint[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--mj-text-muted);\n }\n\n \n\n .unified-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n gap: 16px;\n padding: 4px;\n flex-shrink: 0;\n }\n\n .grid-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 12px;\n background: var(--mj-bg-surface);\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: all 150ms ease;\n position: relative;\n user-select: none;\n }\n\n .grid-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n }\n\n .grid-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n }\n\n .grid-item.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n box-shadow: 0 0 0 1px var(--mj-status-warning);\n }\n\n .grid-item.active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n }\n\n \n\n .unified-grid.select-mode[_ngcontent-%COMP%] .grid-item[_ngcontent-%COMP%] {\n cursor: pointer;\n }\n\n .unified-grid.select-mode[_ngcontent-%COMP%] .grid-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n }\n\n .item-checkbox[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: 10;\n }\n\n .item-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-text-disabled);\n transition: color 150ms ease;\n }\n\n .grid-item.selected[_ngcontent-%COMP%] .item-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n .item-checkbox[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .grid-item-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n }\n\n .grid-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n position: relative;\n }\n\n .grid-icon.folder-icon[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n }\n\n \n\n .grid-icon.folder-icon[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--mj-text-inverse);\n }\n\n .grid-icon.artifact-icon[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n }\n\n .grid-icon.artifact-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-text-muted);\n }\n\n .shared-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n right: -6px;\n width: 22px;\n height: 22px;\n background: var(--mj-bg-surface);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n }\n\n .shared-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-brand-primary);\n }\n\n .grid-info[_ngcontent-%COMP%] {\n width: 100%;\n text-align: center;\n }\n\n .grid-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n line-height: 1.3;\n margin-bottom: 4px;\n \n\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n word-break: break-word;\n }\n\n .grid-description[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n line-height: 1.3;\n margin-bottom: 4px;\n \n\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n word-break: break-word;\n }\n\n .grid-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n }\n\n .grid-owner[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n max-width: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .grid-owner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n margin-right: 3px;\n }\n\n .version-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border-radius: 3px;\n font-size: 10px;\n font-weight: 600;\n font-family: monospace;\n margin-right: 4px;\n }\n\n .artifact-type-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n text-transform: uppercase;\n }\n\n \n\n .unified-list[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n flex-shrink: 0;\n }\n\n .list-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n }\n\n .list-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .list-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 10px 16px;\n text-align: left;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .list-table[_ngcontent-%COMP%] th.sortable[_ngcontent-%COMP%] {\n cursor: pointer;\n user-select: none;\n transition: color 150ms ease;\n }\n\n .list-table[_ngcontent-%COMP%] th.sortable[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n }\n\n .list-table[_ngcontent-%COMP%] th.sortable[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-block;\n margin-right: 6px;\n }\n\n .list-table[_ngcontent-%COMP%] th.sortable[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.5;\n }\n\n .list-table[_ngcontent-%COMP%] th.sortable[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n opacity: 1;\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n transition: background 150ms ease;\n cursor: pointer;\n user-select: none;\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-status-warning);\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n }\n\n .list-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n }\n\n .col-checkbox[_ngcontent-%COMP%] {\n width: 40px;\n text-align: center;\n }\n\n .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-text-disabled);\n cursor: pointer;\n transition: color 150ms ease;\n }\n\n .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:hover, \n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.selected[_ngcontent-%COMP%] .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .col-name[_ngcontent-%COMP%] {\n min-width: 300px;\n }\n\n .list-name-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .list-name-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-text-muted);\n width: 20px;\n text-align: center;\n }\n\n .list-name-cell[_ngcontent-%COMP%] .fa-folder[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .shared-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n margin-left: auto;\n padding: 2px 8px;\n border-radius: var(--mj-radius-full);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n font-weight: 600;\n flex-shrink: 0;\n }\n\n \n\n .list-name-cell[_ngcontent-%COMP%] .shared-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n color: inherit;\n width: auto;\n }\n\n .col-type[_ngcontent-%COMP%] {\n width: 150px;\n }\n\n .col-modified[_ngcontent-%COMP%] {\n width: 180px;\n }\n\n .col-owner[_ngcontent-%COMP%] {\n width: 150px;\n }\n\n \n\n .pagination-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n margin-top: 8px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n }\n\n .pagination-info[_ngcontent-%COMP%] {\n white-space: nowrap;\n }\n\n .pagination-controls[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .pagination-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 150ms ease;\n font-size: 12px;\n }\n\n .pagination-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n }\n\n .pagination-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.35;\n cursor: default;\n }\n\n .pagination-page-info[_ngcontent-%COMP%] {\n padding: 0 8px;\n white-space: nowrap;\n font-weight: 500;\n }\n\n \n\n .toolbar-separator[_ngcontent-%COMP%] {\n width: 1px;\n height: 24px;\n background: var(--mj-border-strong);\n margin: 0 4px;\n }\n\n .toolbar-actions-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .btn-icon-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface));\n }\n\n .btn-icon-danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border-color: var(--mj-status-error);\n }\n\n \n\n .context-menu-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 1999;\n }\n\n .context-menu[_ngcontent-%COMP%] {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);\n padding: 4px;\n z-index: 2000;\n }\n\n .context-menu-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 100ms ease;\n }\n\n .context-menu-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .context-menu-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n width: 16px;\n text-align: center;\n color: var(--mj-text-muted);\n }\n\n .context-menu-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .context-menu-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .context-menu-danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n }\n\n .context-menu-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n }\n .submenu-arrow[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 10px;\n opacity: 0.6;\n }\n .move-target-list[_ngcontent-%COMP%] {\n max-height: 240px;\n overflow-y: auto;\n }\n .context-menu-note[_ngcontent-%COMP%] {\n padding: 8px 14px;\n font-size: 12px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n \n\n .collections-body[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: row;\n min-height: 0;\n overflow: hidden;\n }\n .collections-navigator[_ngcontent-%COMP%] {\n width: 240px;\n flex-shrink: 0;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n }\n .nav-header[_ngcontent-%COMP%] {\n padding: 12px 14px 8px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n }\n .nav-list[_ngcontent-%COMP%] { display: flex; flex-direction: column; padding: 0 6px 12px; gap: 1px; }\n .nav-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 10px;\n border: 1px solid transparent;\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: background 0.12s ease;\n }\n .nav-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .nav-row.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n }\n .nav-row.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 22%, transparent);\n border-color: var(--mj-brand-primary);\n }\n .nav-row[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 13px; width: 16px; flex-shrink: 0; }\n .nav-row-name[_ngcontent-%COMP%] { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .nav-toggle.active[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n \n\n .grid-item.dragging[_ngcontent-%COMP%], .list-item.dragging[_ngcontent-%COMP%] { opacity: 0.4; }\n .grid-item.drag-over[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary) !important;\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface)) !important;\n }\n .list-item.drag-over[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n }\n .breadcrumb-item.drag-over[_ngcontent-%COMP%], .breadcrumb-link.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border-radius: 6px;\n outline: 1px solid var(--mj-brand-primary);\n }\n\n \n\n .item-checkbox[_ngcontent-%COMP%] { opacity: 0; transition: opacity 150ms ease; }\n .grid-item[_ngcontent-%COMP%]:hover .item-checkbox[_ngcontent-%COMP%], \n .grid-item.selected[_ngcontent-%COMP%] .item-checkbox[_ngcontent-%COMP%], \n .unified-grid.select-mode[_ngcontent-%COMP%] .item-checkbox[_ngcontent-%COMP%] { opacity: 1; }\n .list-item[_ngcontent-%COMP%] .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { opacity: 0; transition: opacity 150ms ease; }\n .list-item[_ngcontent-%COMP%]:hover .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n .list-item.selected[_ngcontent-%COMP%] .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n .unified-list.select-mode[_ngcontent-%COMP%] .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { opacity: 1; }\n .list-item.selected[_ngcontent-%COMP%] .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n \n\n .bulk-move-backdrop[_ngcontent-%COMP%] {\n position: fixed; inset: 0; z-index: 1000;\n }\n .bulk-move-menu[_ngcontent-%COMP%] {\n max-height: 320px;\n overflow-y: auto;\n z-index: 1001;\n }\n .dropdown-note[_ngcontent-%COMP%] { padding: 10px 14px; font-size: 12px; color: var(--mj-text-muted); }\n\n \n\n .staging-shelf[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 10px 16px;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n box-shadow: 0 -2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .shelf-info[_ngcontent-%COMP%] {\n display: flex; align-items: center; gap: 8px;\n font-weight: 600; font-size: 13px; color: var(--mj-text-primary);\n flex-shrink: 0;\n }\n .shelf-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n .shelf-chips[_ngcontent-%COMP%] {\n flex: 1; min-width: 0;\n display: flex; gap: 6px; overflow-x: auto; padding: 2px 0;\n }\n .shelf-chip[_ngcontent-%COMP%] {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 4px 6px 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n font-size: 12px; color: var(--mj-text-secondary);\n flex-shrink: 0;\n }\n .shelf-chip-name[_ngcontent-%COMP%] { max-width: 120px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .shelf-chip-x[_ngcontent-%COMP%] {\n width: 18px; height: 18px; border: 0; background: transparent;\n color: var(--mj-text-muted); cursor: pointer; border-radius: 50%;\n display: flex; align-items: center; justify-content: center; font-size: 10px;\n }\n .shelf-chip-x[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .shelf-actions[_ngcontent-%COMP%] { display: flex; gap: 8px; flex-shrink: 0; }\n .btn-toolbar.btn-primary-toolbar[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n }\n .btn-toolbar.btn-primary-toolbar[_ngcontent-%COMP%]:hover:not(:disabled) { background: var(--mj-brand-primary-hover); }\n .btn-toolbar[_ngcontent-%COMP%]:disabled { opacity: 0.5; cursor: not-allowed; }"] });
2745
+ } }, dependencies: [i6.NgClass, i7.DefaultValueAccessor, i7.NgControlStatus, i7.NgModel, i8.MJEmptyStateComponent, i9.LoadingComponent, i10.CollectionShareModalComponent, i11.CollectionFormModalComponent, i12.ArtifactCreateModalComponent, i6.DatePipe], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n }\n\n \n .collections-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n position: relative;\n }\n\n \n .collections-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n gap: 16px;\n background: var(--mj-bg-surface);\n }\n\n .collections-breadcrumb[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 1;\n min-width: 0;\n }\n\n .breadcrumb-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .breadcrumb-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 14px;\n }\n\n .breadcrumb-link[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 500;\n cursor: pointer;\n text-decoration: none;\n white-space: nowrap;\n transition: color 150ms ease;\n font-size: 14px;\n }\n\n .breadcrumb-link[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n }\n\n .breadcrumb-link.active[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n cursor: default;\n }\n\n .breadcrumb-path[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n overflow-x: auto;\n }\n\n .breadcrumb-separator[_ngcontent-%COMP%] {\n color: var(--mj-border-strong);\n font-size: 10px;\n }\n\n .collections-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n \n .btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 6px;\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 150ms ease;\n }\n\n .btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n }\n\n .btn-primary[_ngcontent-%COMP%] i.fa-chevron-down[_ngcontent-%COMP%] {\n font-size: 10px;\n margin-left: 2px;\n }\n\n .btn-icon[_ngcontent-%COMP%] {\n padding: 6px 10px;\n background: transparent;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 150ms ease;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border-color: var(--mj-text-disabled);\n }\n\n .btn-icon.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n }\n\n .btn-icon.active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n }\n\n \n .dropdown-container[_ngcontent-%COMP%] {\n position: relative;\n }\n\n .dropdown-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n min-width: 200px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n padding: 4px;\n z-index: 1000;\n }\n\n .dropdown-menu-right[_ngcontent-%COMP%] {\n left: auto;\n right: 0;\n }\n\n .dropdown-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 100ms ease;\n }\n\n .dropdown-item[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n }\n\n .dropdown-item[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .dropdown-item.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .dropdown-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n width: 16px;\n text-align: center;\n color: var(--mj-text-muted);\n }\n\n .dropdown-item.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .dropdown-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n }\n\n \n .search-container[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n min-width: 200px;\n }\n\n .search-container[_ngcontent-%COMP%] i.fa-search[_ngcontent-%COMP%] {\n position: absolute;\n left: 10px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n pointer-events: none;\n }\n\n .search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 6px 32px 6px 32px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 13px;\n outline: none;\n transition: all 150ms ease;\n }\n\n .search-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n }\n\n .search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 6px;\n padding: 4px;\n background: transparent;\n border: none;\n color: var(--mj-text-disabled);\n cursor: pointer;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .search-clear[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n }\n\n \n .selection-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 20px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n }\n\n .selection-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .selection-count[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n }\n\n .selection-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n }\n\n .btn-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n }\n\n .btn-toolbar[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n }\n\n .btn-toolbar.btn-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface));\n }\n\n .btn-toolbar.btn-danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-color: var(--mj-status-error);\n }\n\n \n .collections-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n }\n\n \n .loading-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 0;\n color: var(--mj-text-disabled);\n text-align: center;\n padding: 24px;\n }\n\n .collections-content[_ngcontent-%COMP%] mj-empty-state[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n }\n\n .empty-collection-hint[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--mj-text-muted);\n }\n\n \n .unified-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n gap: 16px;\n padding: 4px;\n flex-shrink: 0;\n }\n\n .grid-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 12px;\n background: var(--mj-bg-surface);\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: all 150ms ease;\n position: relative;\n user-select: none;\n }\n\n .grid-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n }\n\n .grid-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n }\n\n .grid-item.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n box-shadow: 0 0 0 1px var(--mj-status-warning);\n }\n\n .grid-item.active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n }\n\n \n .unified-grid.select-mode[_ngcontent-%COMP%] .grid-item[_ngcontent-%COMP%] {\n cursor: pointer;\n }\n\n .unified-grid.select-mode[_ngcontent-%COMP%] .grid-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-bg-surface));\n }\n\n .item-checkbox[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: 10;\n }\n\n .item-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-text-disabled);\n transition: color 150ms ease;\n }\n\n .grid-item.selected[_ngcontent-%COMP%] .item-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n .item-checkbox[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .grid-item-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n }\n\n .grid-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n position: relative;\n }\n\n .grid-icon.folder-icon[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n }\n\n \n .grid-icon.folder-icon[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--mj-text-inverse);\n }\n\n .grid-icon.artifact-icon[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n }\n\n .grid-icon.artifact-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-text-muted);\n }\n\n .shared-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n right: -6px;\n width: 22px;\n height: 22px;\n background: var(--mj-bg-surface);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n }\n\n .shared-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-brand-primary);\n }\n\n .grid-info[_ngcontent-%COMP%] {\n width: 100%;\n text-align: center;\n }\n\n .grid-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n line-height: 1.3;\n margin-bottom: 4px;\n \n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n word-break: break-word;\n }\n\n .grid-description[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n line-height: 1.3;\n margin-bottom: 4px;\n \n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n word-break: break-word;\n }\n\n .grid-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n }\n\n .grid-owner[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n max-width: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .grid-owner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n margin-right: 3px;\n }\n\n .version-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border-radius: 3px;\n font-size: 10px;\n font-weight: 600;\n font-family: monospace;\n margin-right: 4px;\n }\n\n .artifact-type-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n text-transform: uppercase;\n }\n\n \n .unified-list[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n flex-shrink: 0;\n }\n\n .list-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n }\n\n .list-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .list-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 10px 16px;\n text-align: left;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .list-table[_ngcontent-%COMP%] th.sortable[_ngcontent-%COMP%] {\n cursor: pointer;\n user-select: none;\n transition: color 150ms ease;\n }\n\n .list-table[_ngcontent-%COMP%] th.sortable[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n }\n\n .list-table[_ngcontent-%COMP%] th.sortable[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-block;\n margin-right: 6px;\n }\n\n .list-table[_ngcontent-%COMP%] th.sortable[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.5;\n }\n\n .list-table[_ngcontent-%COMP%] th.sortable[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n opacity: 1;\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n transition: background 150ms ease;\n cursor: pointer;\n user-select: none;\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-status-warning);\n }\n\n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n }\n\n .list-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n }\n\n .col-checkbox[_ngcontent-%COMP%] {\n width: 40px;\n text-align: center;\n }\n\n .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-text-disabled);\n cursor: pointer;\n transition: color 150ms ease;\n }\n\n .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:hover, \n .list-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.selected[_ngcontent-%COMP%] .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .col-name[_ngcontent-%COMP%] {\n min-width: 300px;\n }\n\n .list-name-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .list-name-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-text-muted);\n width: 20px;\n text-align: center;\n }\n\n .list-name-cell[_ngcontent-%COMP%] .fa-folder[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .shared-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n margin-left: auto;\n padding: 2px 8px;\n border-radius: var(--mj-radius-full);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n font-weight: 600;\n flex-shrink: 0;\n }\n\n \n .list-name-cell[_ngcontent-%COMP%] .shared-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n color: inherit;\n width: auto;\n }\n\n .col-type[_ngcontent-%COMP%] {\n width: 150px;\n }\n\n .col-modified[_ngcontent-%COMP%] {\n width: 180px;\n }\n\n .col-owner[_ngcontent-%COMP%] {\n width: 150px;\n }\n\n \n .pagination-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 16px;\n margin-top: 8px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n }\n\n .pagination-info[_ngcontent-%COMP%] {\n white-space: nowrap;\n }\n\n .pagination-controls[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .pagination-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 150ms ease;\n font-size: 12px;\n }\n\n .pagination-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n }\n\n .pagination-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.35;\n cursor: default;\n }\n\n .pagination-page-info[_ngcontent-%COMP%] {\n padding: 0 8px;\n white-space: nowrap;\n font-weight: 500;\n }\n\n \n .toolbar-separator[_ngcontent-%COMP%] {\n width: 1px;\n height: 24px;\n background: var(--mj-border-strong);\n margin: 0 4px;\n }\n\n .toolbar-actions-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .btn-icon-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface));\n }\n\n .btn-icon-danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n border-color: var(--mj-status-error);\n }\n\n \n .context-menu-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 1999;\n }\n\n .context-menu[_ngcontent-%COMP%] {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);\n padding: 4px;\n z-index: 2000;\n }\n\n .context-menu-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 100ms ease;\n }\n\n .context-menu-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .context-menu-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n width: 16px;\n text-align: center;\n color: var(--mj-text-muted);\n }\n\n .context-menu-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .context-menu-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .context-menu-danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n }\n\n .context-menu-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n }\n .submenu-arrow[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 10px;\n opacity: 0.6;\n }\n .move-target-list[_ngcontent-%COMP%] {\n max-height: 240px;\n overflow-y: auto;\n }\n .context-menu-note[_ngcontent-%COMP%] {\n padding: 8px 14px;\n font-size: 12px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n \n .collections-body[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: row;\n min-height: 0;\n overflow: hidden;\n }\n .collections-navigator[_ngcontent-%COMP%] {\n width: 240px;\n flex-shrink: 0;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n }\n .nav-header[_ngcontent-%COMP%] {\n padding: 12px 14px 8px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n }\n .nav-list[_ngcontent-%COMP%] { display: flex; flex-direction: column; padding: 0 6px 12px; gap: 1px; }\n .nav-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 10px;\n border: 1px solid transparent;\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n transition: background 0.12s ease;\n }\n .nav-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .nav-row.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n }\n .nav-row.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 22%, transparent);\n border-color: var(--mj-brand-primary);\n }\n .nav-row[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 13px; width: 16px; flex-shrink: 0; }\n .nav-row-name[_ngcontent-%COMP%] { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .nav-toggle.active[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n \n .grid-item.dragging[_ngcontent-%COMP%], .list-item.dragging[_ngcontent-%COMP%] { opacity: 0.4; }\n .grid-item.drag-over[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary) !important;\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface)) !important;\n }\n .list-item.drag-over[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n }\n .breadcrumb-item.drag-over[_ngcontent-%COMP%], .breadcrumb-link.drag-over[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border-radius: 6px;\n outline: 1px solid var(--mj-brand-primary);\n }\n\n \n .item-checkbox[_ngcontent-%COMP%] { opacity: 0; transition: opacity 150ms ease; }\n .grid-item[_ngcontent-%COMP%]:hover .item-checkbox[_ngcontent-%COMP%], \n .grid-item.selected[_ngcontent-%COMP%] .item-checkbox[_ngcontent-%COMP%], \n .unified-grid.select-mode[_ngcontent-%COMP%] .item-checkbox[_ngcontent-%COMP%] { opacity: 1; }\n .list-item[_ngcontent-%COMP%] .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { opacity: 0; transition: opacity 150ms ease; }\n .list-item[_ngcontent-%COMP%]:hover .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n .list-item.selected[_ngcontent-%COMP%] .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n .unified-list.select-mode[_ngcontent-%COMP%] .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { opacity: 1; }\n .list-item.selected[_ngcontent-%COMP%] .col-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n \n .bulk-move-backdrop[_ngcontent-%COMP%] {\n position: fixed; inset: 0; z-index: 1000;\n }\n .bulk-move-menu[_ngcontent-%COMP%] {\n max-height: 320px;\n overflow-y: auto;\n z-index: 1001;\n }\n .dropdown-note[_ngcontent-%COMP%] { padding: 10px 14px; font-size: 12px; color: var(--mj-text-muted); }\n\n \n .staging-shelf[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 10px 16px;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n box-shadow: 0 -2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .shelf-info[_ngcontent-%COMP%] {\n display: flex; align-items: center; gap: 8px;\n font-weight: 600; font-size: 13px; color: var(--mj-text-primary);\n flex-shrink: 0;\n }\n .shelf-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n .shelf-chips[_ngcontent-%COMP%] {\n flex: 1; min-width: 0;\n display: flex; gap: 6px; overflow-x: auto; padding: 2px 0;\n }\n .shelf-chip[_ngcontent-%COMP%] {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 4px 6px 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n font-size: 12px; color: var(--mj-text-secondary);\n flex-shrink: 0;\n }\n .shelf-chip-name[_ngcontent-%COMP%] { max-width: 120px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .shelf-chip-x[_ngcontent-%COMP%] {\n width: 18px; height: 18px; border: 0; background: transparent;\n color: var(--mj-text-muted); cursor: pointer; border-radius: 50%;\n display: flex; align-items: center; justify-content: center; font-size: 10px;\n }\n .shelf-chip-x[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .shelf-actions[_ngcontent-%COMP%] { display: flex; gap: 8px; flex-shrink: 0; }\n .btn-toolbar.btn-primary-toolbar[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n }\n .btn-toolbar.btn-primary-toolbar[_ngcontent-%COMP%]:hover:not(:disabled) { background: var(--mj-brand-primary-hover); }\n .btn-toolbar[_ngcontent-%COMP%]:disabled { opacity: 0.5; cursor: not-allowed; }"] });
2746
2746
  }
2747
2747
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CollectionsFullViewComponent, [{
2748
2748
  type: Component,
@@ -28,6 +28,14 @@ export declare class AiComposerComponent {
28
28
  private readonly agentMentionProvider;
29
29
  private readonly recordMentionProvider;
30
30
  private readonly skillCommandProvider;
31
+ /**
32
+ * The agent the message is expected to go to, when the host knows it (`mj-message-input` binds an
33
+ * explicit `@agent` chip in the draft, else its resolved continuity/pinned/default agent). Narrows
34
+ * the '/' skill picker to the skills that agent accepts (`AcceptsSkills` + `MJ: AI Agent Skills`
35
+ * grants). Null = unknown, no narrowing — the server's RequestedSkills guard is the backstop.
36
+ */
37
+ set TargetAgentId(value: string | null);
38
+ get TargetAgentId(): string | null;
31
39
  constructor();
32
40
  /** Enables the '@' trigger (agent + user mentions). */
33
41
  set EnableAgentMentions(value: boolean);
@@ -113,6 +121,6 @@ export declare class AiComposerComponent {
113
121
  artifactVersionId?: string;
114
122
  }): PendingAttachment | undefined;
115
123
  static ɵfac: i0.ɵɵFactoryDeclaration<AiComposerComponent, never>;
116
- static ɵcmp: i0.ɵɵComponentDeclaration<AiComposerComponent, "mj-ai-composer", never, { "EnableAgentMentions": { "alias": "EnableAgentMentions"; "required": false; }; "EnableEntityMentions": { "alias": "EnableEntityMentions"; "required": false; }; "EnableSkillCommands": { "alias": "EnableSkillCommands"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "value": { "alias": "value"; "required": false; }; "showCharacterCount": { "alias": "showCharacterCount"; "required": false; }; "enableMentions": { "alias": "enableMentions"; "required": false; }; "Provider": { "alias": "Provider"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "enableAttachments": { "alias": "enableAttachments"; "required": false; }; "maxAttachments": { "alias": "maxAttachments"; "required": false; }; "maxAttachmentSizeBytes": { "alias": "maxAttachmentSizeBytes"; "required": false; }; "acceptedFileTypes": { "alias": "acceptedFileTypes"; "required": false; }; "enableRealtime": { "alias": "enableRealtime"; "required": false; }; "voiceActive": { "alias": "voiceActive"; "required": false; }; "canStartRealtime": { "alias": "canStartRealtime"; "required": false; }; "enablePlanMode": { "alias": "enablePlanMode"; "required": false; }; "planModeActive": { "alias": "planModeActive"; "required": false; }; }, { "textSubmitted": "textSubmitted"; "blurred": "blurred"; "valueChange": "valueChange"; "attachmentsChanged": "attachmentsChanged"; "attachmentError": "attachmentError"; "attachmentClicked": "attachmentClicked"; "voiceRequested": "voiceRequested"; "voiceOptionsRequested": "voiceOptionsRequested"; "planModeToggle": "planModeToggle"; "beforeSkillsOpened": "beforeSkillsOpened"; "afterSkillsOpened": "afterSkillsOpened"; }, never, never, false, never>;
124
+ static ɵcmp: i0.ɵɵComponentDeclaration<AiComposerComponent, "mj-ai-composer", never, { "TargetAgentId": { "alias": "TargetAgentId"; "required": false; }; "EnableAgentMentions": { "alias": "EnableAgentMentions"; "required": false; }; "EnableEntityMentions": { "alias": "EnableEntityMentions"; "required": false; }; "EnableSkillCommands": { "alias": "EnableSkillCommands"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "value": { "alias": "value"; "required": false; }; "showCharacterCount": { "alias": "showCharacterCount"; "required": false; }; "enableMentions": { "alias": "enableMentions"; "required": false; }; "Provider": { "alias": "Provider"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "enableAttachments": { "alias": "enableAttachments"; "required": false; }; "maxAttachments": { "alias": "maxAttachments"; "required": false; }; "maxAttachmentSizeBytes": { "alias": "maxAttachmentSizeBytes"; "required": false; }; "acceptedFileTypes": { "alias": "acceptedFileTypes"; "required": false; }; "enableRealtime": { "alias": "enableRealtime"; "required": false; }; "voiceActive": { "alias": "voiceActive"; "required": false; }; "canStartRealtime": { "alias": "canStartRealtime"; "required": false; }; "enablePlanMode": { "alias": "enablePlanMode"; "required": false; }; "planModeActive": { "alias": "planModeActive"; "required": false; }; }, { "textSubmitted": "textSubmitted"; "blurred": "blurred"; "valueChange": "valueChange"; "attachmentsChanged": "attachmentsChanged"; "attachmentError": "attachmentError"; "attachmentClicked": "attachmentClicked"; "voiceRequested": "voiceRequested"; "voiceOptionsRequested": "voiceOptionsRequested"; "planModeToggle": "planModeToggle"; "beforeSkillsOpened": "beforeSkillsOpened"; "afterSkillsOpened": "afterSkillsOpened"; }, never, never, false, never>;
117
125
  }
118
126
  //# sourceMappingURL=ai-composer.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-composer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/composer/ai-composer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAA4B,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EACxB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,iBAAiB,EACjB,2BAA2B,EAC5B,MAAM,6BAA6B,CAAC;;AAKrC;;;;;;;;;;;;;;;;GAgBG;AACH,qBAuCa,mBAAmB;IACP,QAAQ,CAAC,EAAE,wBAAwB,CAAC;IAG3D,OAAO,CAAC,oBAAoB,CAAiB;IAC7C,OAAO,CAAC,qBAAqB,CAAiB;IAC9C,OAAO,CAAC,oBAAoB,CAAiB;IAC7C,OAAO,CAAC,uBAAuB,CAAiC;IAIhE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA8B;IACnE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA+B;IACrE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA8B;;IAMnE,uDAAuD;IACvD,IACI,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAKrC;IACD,IAAI,mBAAmB,IAAI,OAAO,CAEjC;IAED,gEAAgE;IAChE,IACI,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAKtC;IACD,IAAI,oBAAoB,IAAI,OAAO,CAElC;IAED,gDAAgD;IAChD,IACI,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAKrC;IACD,IAAI,mBAAmB,IAAI,OAAO,CAEjC;IAED,+GAA+G;IAC/G,IAAW,sBAAsB,IAAI,uBAAuB,EAAE,CAE7D;IAED,OAAO,CAAC,uBAAuB;IAStB,WAAW,EAAE,MAAM,CAAsD;IACzE,QAAQ,EAAE,OAAO,CAAS;IAC1B,KAAK,EAAE,MAAM,CAAM;IACnB,kBAAkB,EAAE,OAAO,CAAS;IAC7C,qEAAqE;IAC5D,cAAc,EAAE,OAAO,CAAQ;IACxC,8FAA8F;IACrF,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAC1C,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,IAAI,EAAE,MAAM,CAAK;IACjB,iBAAiB,EAAE,OAAO,CAAQ;IAClC,cAAc,EAAE,MAAM,CAAM;IAC5B,sBAAsB,EAAE,MAAM,CAAoB;IAClD,iBAAiB,EAAE,MAAM,CAAa;IACtC,cAAc,EAAE,OAAO,CAAS;IAChC,WAAW,EAAE,OAAO,CAAS;IAC7B,gBAAgB,EAAE,OAAO,CAAQ;IACjC,cAAc,EAAE,OAAO,CAAS;IAChC,cAAc,EAAE,OAAO,CAAS;IAG/B,aAAa,uBAA8B;IACrD,0DAA0D;IAChD,OAAO,qBAA4B;IACnC,WAAW,uBAA8B;IACzC,kBAAkB,oCAA2C;IAC7D,eAAe,uBAA8B;IAC7C,iBAAiB,kCAAyC;IAC1D,cAAc,qBAA4B;IAC1C,qBAAqB,qBAA4B;IACjD,cAAc,qBAA4B;IACpD;;;;;;OAMG;IACO,kBAAkB,4CAAmD;IACrE,iBAAiB,qBAA4B;IAEvD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAO1C,uHAAuH;IACvH,IAAW,aAAa,IAAI,sBAAsB,GAAG,SAAS,CAE7D;IAED,gCAAgC;IAChC,0FAA0F;IACnF,aAAa,CAAC,UAAU,EAAE,iBAAiB,EAAE,KAAK,GAAE,OAAc,GAAG,OAAO;IAInF,kDAAkD;IAC3C,eAAe,IAAI,OAAO;IAI1B,KAAK,IAAI,IAAI;IAIpB,wDAAwD;IACjD,KAAK,IAAI,IAAI;IAIpB,8EAA8E;IACvE,mBAAmB,IAAI,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAIvH,2FAA2F;IACpF,4BAA4B,IAAI,MAAM;IAI7C,8CAA8C;IACvC,qBAAqB,IAAI,iBAAiB,EAAE;IAInD,wDAAwD;IACjD,cAAc,IAAI,IAAI;IAI7B,yEAAyE;IAClE,qBAAqB,CAAC,QAAQ,EAAE;QACrC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QACnD,SAAS,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC/C,GAAG,iBAAiB,GAAG,SAAS;yCAtKtB,mBAAmB;2CAAnB,mBAAmB;CAyK/B"}
1
+ {"version":3,"file":"ai-composer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/composer/ai-composer.component.ts"],"names":[],"mappings":"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"}
@@ -34,6 +34,18 @@ export class AiComposerComponent {
34
34
  agentMentionProvider = new AgentMentionProvider();
35
35
  recordMentionProvider = new RecordMentionProvider();
36
36
  skillCommandProvider = new SkillCommandProvider();
37
+ /**
38
+ * The agent the message is expected to go to, when the host knows it (`mj-message-input` binds an
39
+ * explicit `@agent` chip in the draft, else its resolved continuity/pinned/default agent). Narrows
40
+ * the '/' skill picker to the skills that agent accepts (`AcceptsSkills` + `MJ: AI Agent Skills`
41
+ * grants). Null = unknown, no narrowing — the server's RequestedSkills guard is the backstop.
42
+ */
43
+ set TargetAgentId(value) {
44
+ this.skillCommandProvider.TargetAgentId = value ?? null;
45
+ }
46
+ get TargetAgentId() {
47
+ return this.skillCommandProvider.TargetAgentId;
48
+ }
37
49
  constructor() {
38
50
  this.rebuildTriggerProviders();
39
51
  }
@@ -172,10 +184,9 @@ export class AiComposerComponent {
172
184
  } if (rf & 2) {
173
185
  let _t;
174
186
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inputBox = _t.first);
175
- } }, inputs: { EnableAgentMentions: "EnableAgentMentions", EnableEntityMentions: "EnableEntityMentions", EnableSkillCommands: "EnableSkillCommands", placeholder: "placeholder", disabled: "disabled", value: "value", showCharacterCount: "showCharacterCount", enableMentions: "enableMentions", Provider: "Provider", currentUser: "currentUser", rows: "rows", enableAttachments: "enableAttachments", maxAttachments: "maxAttachments", maxAttachmentSizeBytes: "maxAttachmentSizeBytes", acceptedFileTypes: "acceptedFileTypes", enableRealtime: "enableRealtime", voiceActive: "voiceActive", canStartRealtime: "canStartRealtime", enablePlanMode: "enablePlanMode", planModeActive: "planModeActive" }, outputs: { textSubmitted: "textSubmitted", blurred: "blurred", valueChange: "valueChange", attachmentsChanged: "attachmentsChanged", attachmentError: "attachmentError", attachmentClicked: "attachmentClicked", voiceRequested: "voiceRequested", voiceOptionsRequested: "voiceOptionsRequested", planModeToggle: "planModeToggle", beforeSkillsOpened: "beforeSkillsOpened", afterSkillsOpened: "afterSkillsOpened" }, standalone: false, decls: 2, vars: 19, consts: [["inputBox", ""], [3, "TextSubmitted", "Blurred", "ValueChange", "AttachmentsChanged", "AttachmentError", "AttachmentClicked", "VoiceRequested", "VoiceOptionsRequested", "PlanModeToggle", "BeforeSkillsOpened", "AfterSkillsOpened", "Placeholder", "Disabled", "Value", "ShowCharacterCount", "EnableMentions", "TriggerProviders", "Provider", "CurrentUser", "Rows", "EnableAttachments", "MaxAttachments", "MaxAttachmentSizeBytes", "AcceptedFileTypes", "EnableRealtime", "VoiceActive", "CanStartRealtime", "EnablePlanMode", "EnableSkills", "PlanModeActive"]], template: function AiComposerComponent_Template(rf, ctx) { if (rf & 1) {
176
- const _r1 = i0.ɵɵgetCurrentView();
187
+ } }, inputs: { TargetAgentId: "TargetAgentId", EnableAgentMentions: "EnableAgentMentions", EnableEntityMentions: "EnableEntityMentions", EnableSkillCommands: "EnableSkillCommands", placeholder: "placeholder", disabled: "disabled", value: "value", showCharacterCount: "showCharacterCount", enableMentions: "enableMentions", Provider: "Provider", currentUser: "currentUser", rows: "rows", enableAttachments: "enableAttachments", maxAttachments: "maxAttachments", maxAttachmentSizeBytes: "maxAttachmentSizeBytes", acceptedFileTypes: "acceptedFileTypes", enableRealtime: "enableRealtime", voiceActive: "voiceActive", canStartRealtime: "canStartRealtime", enablePlanMode: "enablePlanMode", planModeActive: "planModeActive" }, outputs: { textSubmitted: "textSubmitted", blurred: "blurred", valueChange: "valueChange", attachmentsChanged: "attachmentsChanged", attachmentError: "attachmentError", attachmentClicked: "attachmentClicked", voiceRequested: "voiceRequested", voiceOptionsRequested: "voiceOptionsRequested", planModeToggle: "planModeToggle", beforeSkillsOpened: "beforeSkillsOpened", afterSkillsOpened: "afterSkillsOpened" }, standalone: false, decls: 2, vars: 19, consts: [["inputBox", ""], [3, "TextSubmitted", "Blurred", "ValueChange", "AttachmentsChanged", "AttachmentError", "AttachmentClicked", "VoiceRequested", "VoiceOptionsRequested", "PlanModeToggle", "BeforeSkillsOpened", "AfterSkillsOpened", "Placeholder", "Disabled", "Value", "ShowCharacterCount", "EnableMentions", "TriggerProviders", "Provider", "CurrentUser", "Rows", "EnableAttachments", "MaxAttachments", "MaxAttachmentSizeBytes", "AcceptedFileTypes", "EnableRealtime", "VoiceActive", "CanStartRealtime", "EnablePlanMode", "EnableSkills", "PlanModeActive"]], template: function AiComposerComponent_Template(rf, ctx) { if (rf & 1) {
177
188
  i0.ɵɵelementStart(0, "mj-message-input-box", 1, 0);
178
- i0.ɵɵlistener("TextSubmitted", function AiComposerComponent_Template_mj_message_input_box_TextSubmitted_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.textSubmitted.emit($event)); })("Blurred", function AiComposerComponent_Template_mj_message_input_box_Blurred_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.blurred.emit()); })("ValueChange", function AiComposerComponent_Template_mj_message_input_box_ValueChange_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onInnerValueChange($event)); })("AttachmentsChanged", function AiComposerComponent_Template_mj_message_input_box_AttachmentsChanged_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.attachmentsChanged.emit($event)); })("AttachmentError", function AiComposerComponent_Template_mj_message_input_box_AttachmentError_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.attachmentError.emit($event)); })("AttachmentClicked", function AiComposerComponent_Template_mj_message_input_box_AttachmentClicked_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.attachmentClicked.emit($event)); })("VoiceRequested", function AiComposerComponent_Template_mj_message_input_box_VoiceRequested_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.voiceRequested.emit()); })("VoiceOptionsRequested", function AiComposerComponent_Template_mj_message_input_box_VoiceOptionsRequested_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.voiceOptionsRequested.emit()); })("PlanModeToggle", function AiComposerComponent_Template_mj_message_input_box_PlanModeToggle_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.planModeToggle.emit()); })("BeforeSkillsOpened", function AiComposerComponent_Template_mj_message_input_box_BeforeSkillsOpened_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.beforeSkillsOpened.emit($event)); })("AfterSkillsOpened", function AiComposerComponent_Template_mj_message_input_box_AfterSkillsOpened_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.afterSkillsOpened.emit()); });
189
+ i0.ɵɵlistener("TextSubmitted", function AiComposerComponent_Template_mj_message_input_box_TextSubmitted_0_listener($event) { return ctx.textSubmitted.emit($event); })("Blurred", function AiComposerComponent_Template_mj_message_input_box_Blurred_0_listener() { return ctx.blurred.emit(); })("ValueChange", function AiComposerComponent_Template_mj_message_input_box_ValueChange_0_listener($event) { return ctx.onInnerValueChange($event); })("AttachmentsChanged", function AiComposerComponent_Template_mj_message_input_box_AttachmentsChanged_0_listener($event) { return ctx.attachmentsChanged.emit($event); })("AttachmentError", function AiComposerComponent_Template_mj_message_input_box_AttachmentError_0_listener($event) { return ctx.attachmentError.emit($event); })("AttachmentClicked", function AiComposerComponent_Template_mj_message_input_box_AttachmentClicked_0_listener($event) { return ctx.attachmentClicked.emit($event); })("VoiceRequested", function AiComposerComponent_Template_mj_message_input_box_VoiceRequested_0_listener() { return ctx.voiceRequested.emit(); })("VoiceOptionsRequested", function AiComposerComponent_Template_mj_message_input_box_VoiceOptionsRequested_0_listener() { return ctx.voiceOptionsRequested.emit(); })("PlanModeToggle", function AiComposerComponent_Template_mj_message_input_box_PlanModeToggle_0_listener() { return ctx.planModeToggle.emit(); })("BeforeSkillsOpened", function AiComposerComponent_Template_mj_message_input_box_BeforeSkillsOpened_0_listener($event) { return ctx.beforeSkillsOpened.emit($event); })("AfterSkillsOpened", function AiComposerComponent_Template_mj_message_input_box_AfterSkillsOpened_0_listener() { return ctx.afterSkillsOpened.emit(); });
179
190
  i0.ɵɵelementEnd();
180
191
  } if (rf & 2) {
181
192
  i0.ɵɵproperty("Placeholder", ctx.placeholder)("Disabled", ctx.disabled)("Value", ctx.value)("ShowCharacterCount", ctx.showCharacterCount)("EnableMentions", ctx.enableMentions)("TriggerProviders", ctx.ActiveTriggerProviders)("Provider", ctx.Provider)("CurrentUser", ctx.currentUser)("Rows", ctx.rows)("EnableAttachments", ctx.enableAttachments)("MaxAttachments", ctx.maxAttachments)("MaxAttachmentSizeBytes", ctx.maxAttachmentSizeBytes)("AcceptedFileTypes", ctx.acceptedFileTypes)("EnableRealtime", ctx.enableRealtime)("VoiceActive", ctx.voiceActive)("CanStartRealtime", ctx.canStartRealtime)("EnablePlanMode", ctx.enablePlanMode)("EnableSkills", ctx.EnableSkillCommands)("PlanModeActive", ctx.planModeActive);
@@ -225,6 +236,8 @@ export class AiComposerComponent {
225
236
  }], () => [], { inputBox: [{
226
237
  type: ViewChild,
227
238
  args: ['inputBox']
239
+ }], TargetAgentId: [{
240
+ type: Input
228
241
  }], EnableAgentMentions: [{
229
242
  type: Input
230
243
  }], EnableEntityMentions: [{
@@ -1 +1 @@
1
- {"version":3,"file":"ai-composer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/composer/ai-composer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';\nimport { IMetadataProvider, UserInfo } from '@memberjunction/core';\nimport { MentionSuggestion,\n ComposerTriggerProvider,\n MentionEditorComponent,\n MessageInputBoxComponent,\n PendingAttachment,\n BeforeSkillsOpenedEventArgs\n} from '@memberjunction/ng-composer';\nimport { AgentMentionProvider } from '../../composer-plugins/agent-mention.provider';\nimport { RecordMentionProvider } from '../../composer-plugins/record-mention.provider';\nimport { SkillCommandProvider } from '../../composer-plugins/skill-command.provider';\n\n/**\n * AI-aware composer: wraps the generic `<mj-message-input-box>` (from\n * `@memberjunction/ng-composer`, which ships zero AI knowledge) and builds the AI\n * trigger plugins in — '@' agent/user mentions, '#' entity/query record mentions, and\n * '/' skill commands — while proxying the input box's full surface (inputs, outputs,\n * and public methods).\n *\n * The familiar granular flags live HERE now:\n * - `EnableAgentMentions` (default true) — the '@' trigger\n * - `EnableEntityMentions` (default true) — the '#' trigger\n * - `EnableSkillCommands` (default true) — the '/' trigger\n * plus the pass-through `enableMentions` master switch.\n *\n * The wrapper always runs the inner editor in EXPLICIT provider-list mode (it owns the\n * list; it deliberately does not proxy `TriggerProviders` / `ExcludedTriggerKeys` — use\n * the raw `<mj-message-input-box>` when you need custom providers or discovery mode).\n */\n@Component({\n standalone: false,\n selector: 'mj-ai-composer',\n template: `\n <mj-message-input-box\n #inputBox\n [Placeholder]=\"placeholder\"\n [Disabled]=\"disabled\"\n [Value]=\"value\"\n [ShowCharacterCount]=\"showCharacterCount\"\n [EnableMentions]=\"enableMentions\"\n [TriggerProviders]=\"ActiveTriggerProviders\"\n [Provider]=\"Provider\"\n [CurrentUser]=\"currentUser\"\n [Rows]=\"rows\"\n [EnableAttachments]=\"enableAttachments\"\n [MaxAttachments]=\"maxAttachments\"\n [MaxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [AcceptedFileTypes]=\"acceptedFileTypes\"\n [EnableRealtime]=\"enableRealtime\"\n [VoiceActive]=\"voiceActive\"\n [CanStartRealtime]=\"canStartRealtime\"\n [EnablePlanMode]=\"enablePlanMode\"\n [EnableSkills]=\"EnableSkillCommands\"\n [PlanModeActive]=\"planModeActive\"\n (TextSubmitted)=\"textSubmitted.emit($event)\"\n (Blurred)=\"blurred.emit()\"\n (ValueChange)=\"onInnerValueChange($event)\"\n (AttachmentsChanged)=\"attachmentsChanged.emit($event)\"\n (AttachmentError)=\"attachmentError.emit($event)\"\n (AttachmentClicked)=\"attachmentClicked.emit($event)\"\n (VoiceRequested)=\"voiceRequested.emit()\"\n (VoiceOptionsRequested)=\"voiceOptionsRequested.emit()\"\n (PlanModeToggle)=\"planModeToggle.emit()\"\n (BeforeSkillsOpened)=\"beforeSkillsOpened.emit($event)\"\n (AfterSkillsOpened)=\"afterSkillsOpened.emit()\">\n </mj-message-input-box>\n `\n})\nexport class AiComposerComponent {\n @ViewChild('inputBox') inputBox?: MessageInputBoxComponent;\n\n // ── AI convenience flags (the wrapper's reason to exist) ─────────────────────────\n private _enableAgentMentions: boolean = true;\n private _enableEntityMentions: boolean = true;\n private _enableSkillCommands: boolean = true;\n private _activeTriggerProviders: ComposerTriggerProvider[] = [];\n\n // One instance per plugin per composer — all instances share the singleton\n // MentionAutocompleteService engine, so there is no duplicate cache warm-up.\n private readonly agentMentionProvider = new AgentMentionProvider();\n private readonly recordMentionProvider = new RecordMentionProvider();\n private readonly skillCommandProvider = new SkillCommandProvider();\n\n constructor() {\n this.rebuildTriggerProviders();\n }\n\n /** Enables the '@' trigger (agent + user mentions). */\n @Input()\n set EnableAgentMentions(value: boolean) {\n if (value !== this._enableAgentMentions) {\n this._enableAgentMentions = value;\n this.rebuildTriggerProviders();\n }\n }\n get EnableAgentMentions(): boolean {\n return this._enableAgentMentions;\n }\n\n /** Enables the '#' trigger (entity + query record mentions). */\n @Input()\n set EnableEntityMentions(value: boolean) {\n if (value !== this._enableEntityMentions) {\n this._enableEntityMentions = value;\n this.rebuildTriggerProviders();\n }\n }\n get EnableEntityMentions(): boolean {\n return this._enableEntityMentions;\n }\n\n /** Enables the '/' trigger (skill commands). */\n @Input()\n set EnableSkillCommands(value: boolean) {\n if (value !== this._enableSkillCommands) {\n this._enableSkillCommands = value;\n this.rebuildTriggerProviders();\n }\n }\n get EnableSkillCommands(): boolean {\n return this._enableSkillCommands;\n }\n\n /** The explicit provider list bound to the inner editor (stable reference; rebuilt only when a flag flips). */\n public get ActiveTriggerProviders(): ComposerTriggerProvider[] {\n return this._activeTriggerProviders;\n }\n\n private rebuildTriggerProviders(): void {\n const providers: ComposerTriggerProvider[] = [];\n if (this._enableAgentMentions) providers.push(this.agentMentionProvider);\n if (this._enableEntityMentions) providers.push(this.recordMentionProvider);\n if (this._enableSkillCommands) providers.push(this.skillCommandProvider);\n this._activeTriggerProviders = providers;\n }\n\n // ── Proxied inputs (identical names/defaults to MessageInputBoxComponent) ────────\n @Input() placeholder: string = 'Type your message to start a new conversation...';\n @Input() disabled: boolean = false;\n @Input() value: string = '';\n @Input() showCharacterCount: boolean = false;\n /** Master switch for all mention/command triggers (pass-through). */\n @Input() enableMentions: boolean = true;\n /** Optional metadata provider scoping this composer (pass-through to the trigger plugins). */\n @Input() Provider: IMetadataProvider | null = null;\n @Input() currentUser?: UserInfo;\n @Input() rows: number = 3;\n @Input() enableAttachments: boolean = true;\n @Input() maxAttachments: number = 10;\n @Input() maxAttachmentSizeBytes: number = 20 * 1024 * 1024; // 20MB\n @Input() acceptedFileTypes: string = 'image/*';\n @Input() enableRealtime: boolean = false;\n @Input() voiceActive: boolean = false;\n @Input() canStartRealtime: boolean = true;\n @Input() enablePlanMode: boolean = false;\n @Input() planModeActive: boolean = false;\n\n // ── Proxied outputs ───────────────────────────────────────────────────────────────\n @Output() textSubmitted = new EventEmitter<string>();\n /** Composer lost focus — hosts persist drafts on this. */\n @Output() blurred = new EventEmitter<void>();\n @Output() valueChange = new EventEmitter<string>();\n @Output() attachmentsChanged = new EventEmitter<PendingAttachment[]>();\n @Output() attachmentError = new EventEmitter<string>();\n @Output() attachmentClicked = new EventEmitter<PendingAttachment>();\n @Output() voiceRequested = new EventEmitter<void>();\n @Output() voiceOptionsRequested = new EventEmitter<void>();\n @Output() planModeToggle = new EventEmitter<void>();\n /**\n * Before/After pair for the Skills button, proxied straight through from the input box. Gated on\n * `EnableSkillCommands` — the button and the keystroke are two doors to the same feature, so one\n * flag governs both rather than letting a composer advertise skills it will not serve.\n *\n * Cancel on `beforeSkillsOpened` vetoes the dropdown; `afterSkillsOpened` then does not fire.\n */\n @Output() beforeSkillsOpened = new EventEmitter<BeforeSkillsOpenedEventArgs>();\n @Output() afterSkillsOpened = new EventEmitter<void>();\n\n onInnerValueChange(newValue: string): void {\n this.value = newValue;\n this.valueChange.emit(newValue);\n }\n\n // ── Proxied public methods (ViewChild delegation) ─────────────────────────────────\n\n /** The inner mention editor — kept reachable for hosts that drive it directly (e.g. clear-after-programmatic-send). */\n public get mentionEditor(): MentionEditorComponent | undefined {\n return this.inputBox?.mentionEditor;\n }\n\n /** Focus the composer input. */\n /** Inserts a resolved mention chip + space (see MentionEditorComponent.InsertMention). */\n public InsertMention(suggestion: MentionSuggestion, focus: boolean = true): boolean {\n return this.inputBox?.InsertMention(suggestion, focus) ?? false;\n }\n\n /** Focus with the caret at the end of content. */\n public FocusCaretAtEnd(): boolean {\n return this.inputBox?.FocusCaretAtEnd() ?? false;\n }\n\n public focus(): void {\n this.inputBox?.focus();\n }\n\n /** Clear the editor content and pending attachments. */\n public clear(): void {\n this.inputBox?.mentionEditor?.clear();\n }\n\n /** Mention chip data (id/type/name + preset info) currently in the editor. */\n public getMentionChipsData(): Array<{ id: string; type: string; name: string; presetId?: string; presetName?: string }> {\n return this.inputBox?.GetMentionChipsData() || [];\n }\n\n /** Plain text with mentions encoded as JSON (`@{\"type\":...}`) — the persistence format. */\n public getPlainTextWithJsonMentions(): string {\n return this.inputBox?.mentionEditor?.getPlainTextWithJsonMentions() || '';\n }\n\n /** Pending (not yet uploaded) attachments. */\n public getPendingAttachments(): PendingAttachment[] {\n return this.inputBox?.GetPendingAttachments() || [];\n }\n\n /** Open the attachment file picker programmatically. */\n public openFilePicker(): void {\n this.inputBox?.OpenFilePicker();\n }\n\n /** Attach an artifact as a pending attachment (artifact picker flow). */\n public AddArtifactAttachment(artifact: {\n fileID: string; fileName: string; mimeType: string;\n sizeBytes: number; artifactVersionId?: string;\n }): PendingAttachment | undefined {\n return this.inputBox?.AddArtifactAttachment(artifact);\n }\n}\n"]}
1
+ {"version":3,"file":"ai-composer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/composer/ai-composer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';\nimport { IMetadataProvider, UserInfo } from '@memberjunction/core';\nimport { MentionSuggestion,\n ComposerTriggerProvider,\n MentionEditorComponent,\n MessageInputBoxComponent,\n PendingAttachment,\n BeforeSkillsOpenedEventArgs\n} from '@memberjunction/ng-composer';\nimport { AgentMentionProvider } from '../../composer-plugins/agent-mention.provider';\nimport { RecordMentionProvider } from '../../composer-plugins/record-mention.provider';\nimport { SkillCommandProvider } from '../../composer-plugins/skill-command.provider';\n\n/**\n * AI-aware composer: wraps the generic `<mj-message-input-box>` (from\n * `@memberjunction/ng-composer`, which ships zero AI knowledge) and builds the AI\n * trigger plugins in — '@' agent/user mentions, '#' entity/query record mentions, and\n * '/' skill commands — while proxying the input box's full surface (inputs, outputs,\n * and public methods).\n *\n * The familiar granular flags live HERE now:\n * - `EnableAgentMentions` (default true) — the '@' trigger\n * - `EnableEntityMentions` (default true) — the '#' trigger\n * - `EnableSkillCommands` (default true) — the '/' trigger\n * plus the pass-through `enableMentions` master switch.\n *\n * The wrapper always runs the inner editor in EXPLICIT provider-list mode (it owns the\n * list; it deliberately does not proxy `TriggerProviders` / `ExcludedTriggerKeys` — use\n * the raw `<mj-message-input-box>` when you need custom providers or discovery mode).\n */\n@Component({\n standalone: false,\n selector: 'mj-ai-composer',\n template: `\n <mj-message-input-box\n #inputBox\n [Placeholder]=\"placeholder\"\n [Disabled]=\"disabled\"\n [Value]=\"value\"\n [ShowCharacterCount]=\"showCharacterCount\"\n [EnableMentions]=\"enableMentions\"\n [TriggerProviders]=\"ActiveTriggerProviders\"\n [Provider]=\"Provider\"\n [CurrentUser]=\"currentUser\"\n [Rows]=\"rows\"\n [EnableAttachments]=\"enableAttachments\"\n [MaxAttachments]=\"maxAttachments\"\n [MaxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [AcceptedFileTypes]=\"acceptedFileTypes\"\n [EnableRealtime]=\"enableRealtime\"\n [VoiceActive]=\"voiceActive\"\n [CanStartRealtime]=\"canStartRealtime\"\n [EnablePlanMode]=\"enablePlanMode\"\n [EnableSkills]=\"EnableSkillCommands\"\n [PlanModeActive]=\"planModeActive\"\n (TextSubmitted)=\"textSubmitted.emit($event)\"\n (Blurred)=\"blurred.emit()\"\n (ValueChange)=\"onInnerValueChange($event)\"\n (AttachmentsChanged)=\"attachmentsChanged.emit($event)\"\n (AttachmentError)=\"attachmentError.emit($event)\"\n (AttachmentClicked)=\"attachmentClicked.emit($event)\"\n (VoiceRequested)=\"voiceRequested.emit()\"\n (VoiceOptionsRequested)=\"voiceOptionsRequested.emit()\"\n (PlanModeToggle)=\"planModeToggle.emit()\"\n (BeforeSkillsOpened)=\"beforeSkillsOpened.emit($event)\"\n (AfterSkillsOpened)=\"afterSkillsOpened.emit()\">\n </mj-message-input-box>\n `\n})\nexport class AiComposerComponent {\n @ViewChild('inputBox') inputBox?: MessageInputBoxComponent;\n\n // ── AI convenience flags (the wrapper's reason to exist) ─────────────────────────\n private _enableAgentMentions: boolean = true;\n private _enableEntityMentions: boolean = true;\n private _enableSkillCommands: boolean = true;\n private _activeTriggerProviders: ComposerTriggerProvider[] = [];\n\n // One instance per plugin per composer — all instances share the singleton\n // MentionAutocompleteService engine, so there is no duplicate cache warm-up.\n private readonly agentMentionProvider = new AgentMentionProvider();\n private readonly recordMentionProvider = new RecordMentionProvider();\n private readonly skillCommandProvider = new SkillCommandProvider();\n\n /**\n * The agent the message is expected to go to, when the host knows it (`mj-message-input` binds an\n * explicit `@agent` chip in the draft, else its resolved continuity/pinned/default agent). Narrows\n * the '/' skill picker to the skills that agent accepts (`AcceptsSkills` + `MJ: AI Agent Skills`\n * grants). Null = unknown, no narrowing — the server's RequestedSkills guard is the backstop.\n */\n @Input()\n set TargetAgentId(value: string | null) {\n this.skillCommandProvider.TargetAgentId = value ?? null;\n }\n get TargetAgentId(): string | null {\n return this.skillCommandProvider.TargetAgentId;\n }\n\n constructor() {\n this.rebuildTriggerProviders();\n }\n\n /** Enables the '@' trigger (agent + user mentions). */\n @Input()\n set EnableAgentMentions(value: boolean) {\n if (value !== this._enableAgentMentions) {\n this._enableAgentMentions = value;\n this.rebuildTriggerProviders();\n }\n }\n get EnableAgentMentions(): boolean {\n return this._enableAgentMentions;\n }\n\n /** Enables the '#' trigger (entity + query record mentions). */\n @Input()\n set EnableEntityMentions(value: boolean) {\n if (value !== this._enableEntityMentions) {\n this._enableEntityMentions = value;\n this.rebuildTriggerProviders();\n }\n }\n get EnableEntityMentions(): boolean {\n return this._enableEntityMentions;\n }\n\n /** Enables the '/' trigger (skill commands). */\n @Input()\n set EnableSkillCommands(value: boolean) {\n if (value !== this._enableSkillCommands) {\n this._enableSkillCommands = value;\n this.rebuildTriggerProviders();\n }\n }\n get EnableSkillCommands(): boolean {\n return this._enableSkillCommands;\n }\n\n /** The explicit provider list bound to the inner editor (stable reference; rebuilt only when a flag flips). */\n public get ActiveTriggerProviders(): ComposerTriggerProvider[] {\n return this._activeTriggerProviders;\n }\n\n private rebuildTriggerProviders(): void {\n const providers: ComposerTriggerProvider[] = [];\n if (this._enableAgentMentions) providers.push(this.agentMentionProvider);\n if (this._enableEntityMentions) providers.push(this.recordMentionProvider);\n if (this._enableSkillCommands) providers.push(this.skillCommandProvider);\n this._activeTriggerProviders = providers;\n }\n\n // ── Proxied inputs (identical names/defaults to MessageInputBoxComponent) ────────\n @Input() placeholder: string = 'Type your message to start a new conversation...';\n @Input() disabled: boolean = false;\n @Input() value: string = '';\n @Input() showCharacterCount: boolean = false;\n /** Master switch for all mention/command triggers (pass-through). */\n @Input() enableMentions: boolean = true;\n /** Optional metadata provider scoping this composer (pass-through to the trigger plugins). */\n @Input() Provider: IMetadataProvider | null = null;\n @Input() currentUser?: UserInfo;\n @Input() rows: number = 3;\n @Input() enableAttachments: boolean = true;\n @Input() maxAttachments: number = 10;\n @Input() maxAttachmentSizeBytes: number = 20 * 1024 * 1024; // 20MB\n @Input() acceptedFileTypes: string = 'image/*';\n @Input() enableRealtime: boolean = false;\n @Input() voiceActive: boolean = false;\n @Input() canStartRealtime: boolean = true;\n @Input() enablePlanMode: boolean = false;\n @Input() planModeActive: boolean = false;\n\n // ── Proxied outputs ───────────────────────────────────────────────────────────────\n @Output() textSubmitted = new EventEmitter<string>();\n /** Composer lost focus — hosts persist drafts on this. */\n @Output() blurred = new EventEmitter<void>();\n @Output() valueChange = new EventEmitter<string>();\n @Output() attachmentsChanged = new EventEmitter<PendingAttachment[]>();\n @Output() attachmentError = new EventEmitter<string>();\n @Output() attachmentClicked = new EventEmitter<PendingAttachment>();\n @Output() voiceRequested = new EventEmitter<void>();\n @Output() voiceOptionsRequested = new EventEmitter<void>();\n @Output() planModeToggle = new EventEmitter<void>();\n /**\n * Before/After pair for the Skills button, proxied straight through from the input box. Gated on\n * `EnableSkillCommands` — the button and the keystroke are two doors to the same feature, so one\n * flag governs both rather than letting a composer advertise skills it will not serve.\n *\n * Cancel on `beforeSkillsOpened` vetoes the dropdown; `afterSkillsOpened` then does not fire.\n */\n @Output() beforeSkillsOpened = new EventEmitter<BeforeSkillsOpenedEventArgs>();\n @Output() afterSkillsOpened = new EventEmitter<void>();\n\n onInnerValueChange(newValue: string): void {\n this.value = newValue;\n this.valueChange.emit(newValue);\n }\n\n // ── Proxied public methods (ViewChild delegation) ─────────────────────────────────\n\n /** The inner mention editor — kept reachable for hosts that drive it directly (e.g. clear-after-programmatic-send). */\n public get mentionEditor(): MentionEditorComponent | undefined {\n return this.inputBox?.mentionEditor;\n }\n\n /** Focus the composer input. */\n /** Inserts a resolved mention chip + space (see MentionEditorComponent.InsertMention). */\n public InsertMention(suggestion: MentionSuggestion, focus: boolean = true): boolean {\n return this.inputBox?.InsertMention(suggestion, focus) ?? false;\n }\n\n /** Focus with the caret at the end of content. */\n public FocusCaretAtEnd(): boolean {\n return this.inputBox?.FocusCaretAtEnd() ?? false;\n }\n\n public focus(): void {\n this.inputBox?.focus();\n }\n\n /** Clear the editor content and pending attachments. */\n public clear(): void {\n this.inputBox?.mentionEditor?.clear();\n }\n\n /** Mention chip data (id/type/name + preset info) currently in the editor. */\n public getMentionChipsData(): Array<{ id: string; type: string; name: string; presetId?: string; presetName?: string }> {\n return this.inputBox?.GetMentionChipsData() || [];\n }\n\n /** Plain text with mentions encoded as JSON (`@{\"type\":...}`) — the persistence format. */\n public getPlainTextWithJsonMentions(): string {\n return this.inputBox?.mentionEditor?.getPlainTextWithJsonMentions() || '';\n }\n\n /** Pending (not yet uploaded) attachments. */\n public getPendingAttachments(): PendingAttachment[] {\n return this.inputBox?.GetPendingAttachments() || [];\n }\n\n /** Open the attachment file picker programmatically. */\n public openFilePicker(): void {\n this.inputBox?.OpenFilePicker();\n }\n\n /** Attach an artifact as a pending attachment (artifact picker flow). */\n public AddArtifactAttachment(artifact: {\n fileID: string; fileName: string; mimeType: string;\n sizeBytes: number; artifactVersionId?: string;\n }): PendingAttachment | undefined {\n return this.inputBox?.AddArtifactAttachment(artifact);\n }\n}\n"]}
@@ -37,7 +37,7 @@ function ConversationAgentPickerComponent_Conditional_6_Conditional_8_Template(r
37
37
  function ConversationAgentPickerComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
38
38
  const _r1 = i0.ɵɵgetCurrentView();
39
39
  i0.ɵɵelementStart(0, "div", 6);
40
- i0.ɵɵlistener("click", function ConversationAgentPickerComponent_Conditional_6_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView($event.stopPropagation()); });
40
+ i0.ɵɵlistener("click", function ConversationAgentPickerComponent_Conditional_6_Template_div_click_0_listener($event) { return $event.stopPropagation(); });
41
41
  i0.ɵɵelementStart(1, "div", 7);
42
42
  i0.ɵɵtext(2, "Default agent for this conversation");
43
43
  i0.ɵɵelementEnd();
@@ -191,7 +191,7 @@ export class ConversationAgentPickerComponent {
191
191
  i0.ɵɵtextInterpolate(ctx.CurrentAgentLabel);
192
192
  i0.ɵɵadvance(2);
193
193
  i0.ɵɵconditional(ctx.IsOpen ? 6 : -1);
194
- } }, styles: ["\n\n\n\n .mj-cv-agent-picker[_ngcontent-%COMP%] { position: relative; display: inline-flex; align-items: center; }\n .mj-cv-agent-picker__trigger[_ngcontent-%COMP%] {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 6px 12px; min-height: 32px; box-sizing: border-box;\n background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default);\n border-radius: 4px; cursor: pointer;\n color: var(--mj-text-primary); font-size: 0.8125rem; line-height: 1.5;\n transition: background 120ms, border-color 120ms;\n }\n .mj-cv-agent-picker__trigger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover); border-color: var(--mj-border-strong);\n }\n .mj-cv-agent-picker__trigger[_ngcontent-%COMP%]:disabled { opacity: 0.5; cursor: not-allowed; }\n .mj-cv-agent-picker--open[_ngcontent-%COMP%] .mj-cv-agent-picker__trigger[_ngcontent-%COMP%] { border-color: var(--mj-border-focus); }\n .mj-cv-agent-picker__label[_ngcontent-%COMP%] { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .mj-cv-agent-picker__caret[_ngcontent-%COMP%] { font-size: 10px; opacity: 0.7; }\n .mj-cv-agent-picker__menu[_ngcontent-%COMP%] {\n position: absolute; top: calc(100% + 4px); right: 0; z-index: 50;\n min-width: 220px; max-height: 320px; overflow-y: auto;\n background: var(--mj-bg-surface-elevated); border: 1px solid var(--mj-border-default);\n border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.12);\n padding: 4px 0;\n }\n .mj-cv-agent-picker__menu-header[_ngcontent-%COMP%] {\n padding: 6px 12px 4px; font-size: 11px; text-transform: uppercase;\n letter-spacing: 0.04em; color: var(--mj-text-muted);\n }\n .mj-cv-agent-picker__item[_ngcontent-%COMP%] {\n display: flex; align-items: center; gap: 8px; width: 100%;\n padding: 6px 12px; background: transparent; border: none; cursor: pointer;\n color: var(--mj-text-primary); font-size: 13px; text-align: left;\n }\n .mj-cv-agent-picker__item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { width: 14px; text-align: center; color: var(--mj-text-secondary); }\n .mj-cv-agent-picker__item[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n .mj-cv-agent-picker__item--selected[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent); }\n .mj-cv-agent-picker__item--selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n .mj-cv-agent-picker__empty[_ngcontent-%COMP%] { padding: 8px 12px; font-size: 12px; color: var(--mj-text-muted); }"], changeDetection: 0 });
194
+ } }, styles: ["\n\n\n .mj-cv-agent-picker[_ngcontent-%COMP%] { position: relative; display: inline-flex; align-items: center; }\n .mj-cv-agent-picker__trigger[_ngcontent-%COMP%] {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 6px 12px; min-height: 32px; box-sizing: border-box;\n background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default);\n border-radius: 4px; cursor: pointer;\n color: var(--mj-text-primary); font-size: 0.8125rem; line-height: 1.5;\n transition: background 120ms, border-color 120ms;\n }\n .mj-cv-agent-picker__trigger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover); border-color: var(--mj-border-strong);\n }\n .mj-cv-agent-picker__trigger[_ngcontent-%COMP%]:disabled { opacity: 0.5; cursor: not-allowed; }\n .mj-cv-agent-picker--open[_ngcontent-%COMP%] .mj-cv-agent-picker__trigger[_ngcontent-%COMP%] { border-color: var(--mj-border-focus); }\n .mj-cv-agent-picker__label[_ngcontent-%COMP%] { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .mj-cv-agent-picker__caret[_ngcontent-%COMP%] { font-size: 10px; opacity: 0.7; }\n .mj-cv-agent-picker__menu[_ngcontent-%COMP%] {\n position: absolute; top: calc(100% + 4px); right: 0; z-index: 50;\n min-width: 220px; max-height: 320px; overflow-y: auto;\n background: var(--mj-bg-surface-elevated); border: 1px solid var(--mj-border-default);\n border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.12);\n padding: 4px 0;\n }\n .mj-cv-agent-picker__menu-header[_ngcontent-%COMP%] {\n padding: 6px 12px 4px; font-size: 11px; text-transform: uppercase;\n letter-spacing: 0.04em; color: var(--mj-text-muted);\n }\n .mj-cv-agent-picker__item[_ngcontent-%COMP%] {\n display: flex; align-items: center; gap: 8px; width: 100%;\n padding: 6px 12px; background: transparent; border: none; cursor: pointer;\n color: var(--mj-text-primary); font-size: 13px; text-align: left;\n }\n .mj-cv-agent-picker__item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { width: 14px; text-align: center; color: var(--mj-text-secondary); }\n .mj-cv-agent-picker__item[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n .mj-cv-agent-picker__item--selected[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent); }\n .mj-cv-agent-picker__item--selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n .mj-cv-agent-picker__empty[_ngcontent-%COMP%] { padding: 8px 12px; font-size: 12px; color: var(--mj-text-muted); }"], changeDetection: 0 });
195
195
  }
196
196
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationAgentPickerComponent, [{
197
197
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-agent-picker.component.js","sourceRoot":"","sources":["../../../../src/lib/components/conversation/conversation-agent-picker.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n HostListener,\n Input,\n OnInit,\n Output,\n inject,\n} from '@angular/core';\nimport { LogError } from '@memberjunction/core';\nimport type { UserInfo } from '@memberjunction/core';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport type { MJAIAgentEntityExtended } from '@memberjunction/ai-core-plus';\nimport type { MJConversationEntity } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * Header widget that lets a user pin a default AI agent on the active\n * conversation. The pinned agent (saved to\n * `MJConversationEntity.DefaultAgentID`) takes precedence over the\n * embedder-supplied default in `MessageInputComponent.routeMessage()` —\n * non-mention messages route to it instead of Sage.\n *\n * Eligible agents are top-level, Active, non-Sub-Agent rows from\n * `AIEngineBase.Instance.Agents`. The widget renders as a compact button\n * showing the current pin (or \"Auto\" when nothing is pinned). Clicking\n * opens an inline list with a \"Clear\" option to remove the pin.\n *\n * The host controls visibility via `<mj-conversation-chat-area>`'s\n * `[showAgentPicker]` input (default true). Surfaces that don't want this\n * UX (e.g. agent-less embed) set it to false.\n */\n@Component({\n standalone: false,\n selector: 'mj-conversation-agent-picker',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"mj-cv-agent-picker\" [class.mj-cv-agent-picker--open]=\"IsOpen\">\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__trigger\"\n [title]=\"ButtonTitle\"\n [disabled]=\"Disabled || !Conversation\"\n (click)=\"Toggle($event)\">\n <i class=\"fa-solid fa-robot\"></i>\n <span class=\"mj-cv-agent-picker__label\">{{ CurrentAgentLabel }}</span>\n <i class=\"fa-solid fa-caret-down mj-cv-agent-picker__caret\"></i>\n </button>\n @if (IsOpen) {\n <div class=\"mj-cv-agent-picker__menu\" (click)=\"$event.stopPropagation()\">\n <div class=\"mj-cv-agent-picker__menu-header\">Default agent for this conversation</div>\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__item\"\n [class.mj-cv-agent-picker__item--selected]=\"!Conversation?.DefaultAgentID\"\n (click)=\"PickAgent(null)\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Auto (use default)</span>\n </button>\n @if (EligibleAgents.length === 0) {\n <div class=\"mj-cv-agent-picker__empty\">No agents available</div>\n } @else {\n @for (agent of EligibleAgents; track agent.ID) {\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__item\"\n [class.mj-cv-agent-picker__item--selected]=\"IsSelected(agent)\"\n [title]=\"agent.Description || agent.Name\"\n (click)=\"PickAgent(agent)\">\n <i [class]=\"IconClassFor(agent)\"></i>\n <span>{{ agent.Name }}</span>\n </button>\n }\n }\n </div>\n }\n </div>\n `,\n styles: [`\n /* Match mjButton size=\"sm\" so the trigger lines up with neighboring\n Export / Share buttons: min-height 32px, 6px/12px padding,\n 0.8125rem font. Same border-radius as the other chrome buttons. */\n .mj-cv-agent-picker { position: relative; display: inline-flex; align-items: center; }\n .mj-cv-agent-picker__trigger {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 6px 12px; min-height: 32px; box-sizing: border-box;\n background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default);\n border-radius: 4px; cursor: pointer;\n color: var(--mj-text-primary); font-size: 0.8125rem; line-height: 1.5;\n transition: background 120ms, border-color 120ms;\n }\n .mj-cv-agent-picker__trigger:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover); border-color: var(--mj-border-strong);\n }\n .mj-cv-agent-picker__trigger:disabled { opacity: 0.5; cursor: not-allowed; }\n .mj-cv-agent-picker--open .mj-cv-agent-picker__trigger { border-color: var(--mj-border-focus); }\n .mj-cv-agent-picker__label { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .mj-cv-agent-picker__caret { font-size: 10px; opacity: 0.7; }\n .mj-cv-agent-picker__menu {\n position: absolute; top: calc(100% + 4px); right: 0; z-index: 50;\n min-width: 220px; max-height: 320px; overflow-y: auto;\n background: var(--mj-bg-surface-elevated); border: 1px solid var(--mj-border-default);\n border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.12);\n padding: 4px 0;\n }\n .mj-cv-agent-picker__menu-header {\n padding: 6px 12px 4px; font-size: 11px; text-transform: uppercase;\n letter-spacing: 0.04em; color: var(--mj-text-muted);\n }\n .mj-cv-agent-picker__item {\n display: flex; align-items: center; gap: 8px; width: 100%;\n padding: 6px 12px; background: transparent; border: none; cursor: pointer;\n color: var(--mj-text-primary); font-size: 13px; text-align: left;\n }\n .mj-cv-agent-picker__item i { width: 14px; text-align: center; color: var(--mj-text-secondary); }\n .mj-cv-agent-picker__item:hover { background: var(--mj-bg-surface-hover); }\n .mj-cv-agent-picker__item--selected { background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent); }\n .mj-cv-agent-picker__item--selected i { color: var(--mj-brand-primary); }\n .mj-cv-agent-picker__empty { padding: 8px 12px; font-size: 12px; color: var(--mj-text-muted); }\n `]\n})\nexport class ConversationAgentPickerComponent implements OnInit {\n /** The conversation whose `DefaultAgentID` this widget edits. */\n @Input() Conversation: MJConversationEntity | null = null;\n\n /** Required for the Save() audit context. */\n @Input() CurrentUser: UserInfo | null = null;\n\n /** Disable the picker (e.g. read-only conversation). */\n @Input() Disabled: boolean = false;\n\n /** Emitted after a successful save with the new (or null) agent ID. */\n @Output() AgentChanged = new EventEmitter<string | null>();\n\n public IsOpen = false;\n public EligibleAgents: MJAIAgentEntityExtended[] = [];\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly notifications = inject(MJNotificationService);\n\n public async ngOnInit(): Promise<void> {\n try {\n // AIEngineBase is the live, cached agent catalog. Ensure it's\n // loaded — most app shells warm it up at boot, but the picker\n // could mount before that completes.\n await AIEngineBase.Instance.Config(false);\n this.EligibleAgents = (AIEngineBase.Instance.Agents ?? [])\n .filter(a =>\n !a.ParentID &&\n a.Status === 'Active' &&\n a.InvocationMode !== 'Sub-Agent'\n )\n .sort((a, b) => (a.Name ?? '').localeCompare(b.Name ?? ''));\n this.cdr.markForCheck();\n } catch (err) {\n LogError(`ConversationAgentPicker.ngOnInit: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n public get CurrentAgentLabel(): string {\n const id = this.Conversation?.DefaultAgentID;\n if (!id) return 'Auto';\n const match = this.EligibleAgents.find(a => UUIDsEqual(a.ID, id));\n // If the pinned agent is no longer eligible (deactivated, demoted to\n // sub-agent), still surface its name from the cache so the user can\n // see what was pinned even though they can't re-pin it.\n const fromCache = match\n ?? (AIEngineBase.Instance.Agents ?? []).find(a => UUIDsEqual(a.ID, id));\n return fromCache?.Name ?? 'Pinned agent';\n }\n\n public get ButtonTitle(): string {\n return this.Conversation?.DefaultAgentID\n ? `This conversation routes to ${this.CurrentAgentLabel}. Click to change.`\n : 'No agent pinned — messages route via the standard rules. Click to pin an agent.';\n }\n\n public IconClassFor(agent: MJAIAgentEntityExtended): string {\n return agent.IconClass?.trim() || 'fa-solid fa-robot';\n }\n\n public IsSelected(agent: MJAIAgentEntityExtended): boolean {\n return !!this.Conversation?.DefaultAgentID\n && UUIDsEqual(agent.ID, this.Conversation.DefaultAgentID);\n }\n\n public Toggle(event: MouseEvent): void {\n event.stopPropagation();\n if (this.Disabled || !this.Conversation) return;\n this.IsOpen = !this.IsOpen;\n this.cdr.markForCheck();\n }\n\n public async PickAgent(agent: MJAIAgentEntityExtended | null): Promise<void> {\n this.IsOpen = false;\n const conv = this.Conversation;\n if (!conv) return;\n const newId = agent?.ID ?? null;\n if (conv.DefaultAgentID === newId) {\n this.cdr.markForCheck();\n return;\n }\n const prev = conv.DefaultAgentID;\n conv.DefaultAgentID = newId;\n try {\n const saved = await conv.Save();\n if (!saved) {\n conv.DefaultAgentID = prev;\n this.notifications.CreateSimpleNotification(\n conv.LatestResult?.CompleteMessage ?? 'Failed to update conversation default agent.',\n 'error', 4500);\n return;\n }\n this.AgentChanged.emit(newId);\n } catch (err) {\n conv.DefaultAgentID = prev;\n LogError(`ConversationAgentPicker.PickAgent: ${err instanceof Error ? err.message : String(err)}`);\n } finally {\n this.cdr.markForCheck();\n }\n }\n\n /** Close the menu when the user clicks outside the picker. */\n @HostListener('document:click', ['$event'])\n public OnDocumentClick(_event: MouseEvent): void {\n if (this.IsOpen) {\n this.IsOpen = false;\n this.cdr.markForCheck();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"conversation-agent-picker.component.js","sourceRoot":"","sources":["../../../../src/lib/components/conversation/conversation-agent-picker.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n HostListener,\n Input,\n OnInit,\n Output,\n inject,\n} from '@angular/core';\nimport { LogError } from '@memberjunction/core';\nimport type { UserInfo } from '@memberjunction/core';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport type { MJAIAgentEntityExtended } from '@memberjunction/ai-core-plus';\nimport type { MJConversationEntity } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * Header widget that lets a user pin a default AI agent on the active\n * conversation. The pinned agent (saved to\n * `MJConversationEntity.DefaultAgentID`) takes precedence over the\n * embedder-supplied default in `MessageInputComponent.routeMessage()` —\n * non-mention messages route to it instead of Sage.\n *\n * Eligible agents are top-level, Active, non-Sub-Agent rows from\n * `AIEngineBase.Instance.Agents`. The widget renders as a compact button\n * showing the current pin (or \"Auto\" when nothing is pinned). Clicking\n * opens an inline list with a \"Clear\" option to remove the pin.\n *\n * The host controls visibility via `<mj-conversation-chat-area>`'s\n * `[showAgentPicker]` input (default true). Surfaces that don't want this\n * UX (e.g. agent-less embed) set it to false.\n */\n@Component({\n standalone: false,\n selector: 'mj-conversation-agent-picker',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"mj-cv-agent-picker\" [class.mj-cv-agent-picker--open]=\"IsOpen\">\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__trigger\"\n [title]=\"ButtonTitle\"\n [disabled]=\"Disabled || !Conversation\"\n (click)=\"Toggle($event)\">\n <i class=\"fa-solid fa-robot\"></i>\n <span class=\"mj-cv-agent-picker__label\">{{ CurrentAgentLabel }}</span>\n <i class=\"fa-solid fa-caret-down mj-cv-agent-picker__caret\"></i>\n </button>\n @if (IsOpen) {\n <div class=\"mj-cv-agent-picker__menu\" (click)=\"$event.stopPropagation()\">\n <div class=\"mj-cv-agent-picker__menu-header\">Default agent for this conversation</div>\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__item\"\n [class.mj-cv-agent-picker__item--selected]=\"!Conversation?.DefaultAgentID\"\n (click)=\"PickAgent(null)\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Auto (use default)</span>\n </button>\n @if (EligibleAgents.length === 0) {\n <div class=\"mj-cv-agent-picker__empty\">No agents available</div>\n } @else {\n @for (agent of EligibleAgents; track agent.ID) {\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__item\"\n [class.mj-cv-agent-picker__item--selected]=\"IsSelected(agent)\"\n [title]=\"agent.Description || agent.Name\"\n (click)=\"PickAgent(agent)\">\n <i [class]=\"IconClassFor(agent)\"></i>\n <span>{{ agent.Name }}</span>\n </button>\n }\n }\n </div>\n }\n </div>\n `,\n styles: [`\n /* Match mjButton size=\"sm\" so the trigger lines up with neighboring\n Export / Share buttons: min-height 32px, 6px/12px padding,\n 0.8125rem font. Same border-radius as the other chrome buttons. */\n .mj-cv-agent-picker { position: relative; display: inline-flex; align-items: center; }\n .mj-cv-agent-picker__trigger {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 6px 12px; min-height: 32px; box-sizing: border-box;\n background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default);\n border-radius: 4px; cursor: pointer;\n color: var(--mj-text-primary); font-size: 0.8125rem; line-height: 1.5;\n transition: background 120ms, border-color 120ms;\n }\n .mj-cv-agent-picker__trigger:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover); border-color: var(--mj-border-strong);\n }\n .mj-cv-agent-picker__trigger:disabled { opacity: 0.5; cursor: not-allowed; }\n .mj-cv-agent-picker--open .mj-cv-agent-picker__trigger { border-color: var(--mj-border-focus); }\n .mj-cv-agent-picker__label { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .mj-cv-agent-picker__caret { font-size: 10px; opacity: 0.7; }\n .mj-cv-agent-picker__menu {\n position: absolute; top: calc(100% + 4px); right: 0; z-index: 50;\n min-width: 220px; max-height: 320px; overflow-y: auto;\n background: var(--mj-bg-surface-elevated); border: 1px solid var(--mj-border-default);\n border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.12);\n padding: 4px 0;\n }\n .mj-cv-agent-picker__menu-header {\n padding: 6px 12px 4px; font-size: 11px; text-transform: uppercase;\n letter-spacing: 0.04em; color: var(--mj-text-muted);\n }\n .mj-cv-agent-picker__item {\n display: flex; align-items: center; gap: 8px; width: 100%;\n padding: 6px 12px; background: transparent; border: none; cursor: pointer;\n color: var(--mj-text-primary); font-size: 13px; text-align: left;\n }\n .mj-cv-agent-picker__item i { width: 14px; text-align: center; color: var(--mj-text-secondary); }\n .mj-cv-agent-picker__item:hover { background: var(--mj-bg-surface-hover); }\n .mj-cv-agent-picker__item--selected { background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent); }\n .mj-cv-agent-picker__item--selected i { color: var(--mj-brand-primary); }\n .mj-cv-agent-picker__empty { padding: 8px 12px; font-size: 12px; color: var(--mj-text-muted); }\n `]\n})\nexport class ConversationAgentPickerComponent implements OnInit {\n /** The conversation whose `DefaultAgentID` this widget edits. */\n @Input() Conversation: MJConversationEntity | null = null;\n\n /** Required for the Save() audit context. */\n @Input() CurrentUser: UserInfo | null = null;\n\n /** Disable the picker (e.g. read-only conversation). */\n @Input() Disabled: boolean = false;\n\n /** Emitted after a successful save with the new (or null) agent ID. */\n @Output() AgentChanged = new EventEmitter<string | null>();\n\n public IsOpen = false;\n public EligibleAgents: MJAIAgentEntityExtended[] = [];\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly notifications = inject(MJNotificationService);\n\n public async ngOnInit(): Promise<void> {\n try {\n // AIEngineBase is the live, cached agent catalog. Ensure it's\n // loaded — most app shells warm it up at boot, but the picker\n // could mount before that completes.\n await AIEngineBase.Instance.Config(false);\n this.EligibleAgents = (AIEngineBase.Instance.Agents ?? [])\n .filter(a =>\n !a.ParentID &&\n a.Status === 'Active' &&\n a.InvocationMode !== 'Sub-Agent'\n )\n .sort((a, b) => (a.Name ?? '').localeCompare(b.Name ?? ''));\n this.cdr.markForCheck();\n } catch (err) {\n LogError(`ConversationAgentPicker.ngOnInit: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n public get CurrentAgentLabel(): string {\n const id = this.Conversation?.DefaultAgentID;\n if (!id) return 'Auto';\n const match = this.EligibleAgents.find(a => UUIDsEqual(a.ID, id));\n // If the pinned agent is no longer eligible (deactivated, demoted to\n // sub-agent), still surface its name from the cache so the user can\n // see what was pinned even though they can't re-pin it.\n const fromCache = match\n ?? (AIEngineBase.Instance.Agents ?? []).find(a => UUIDsEqual(a.ID, id));\n return fromCache?.Name ?? 'Pinned agent';\n }\n\n public get ButtonTitle(): string {\n return this.Conversation?.DefaultAgentID\n ? `This conversation routes to ${this.CurrentAgentLabel}. Click to change.`\n : 'No agent pinned — messages route via the standard rules. Click to pin an agent.';\n }\n\n public IconClassFor(agent: MJAIAgentEntityExtended): string {\n return agent.IconClass?.trim() || 'fa-solid fa-robot';\n }\n\n public IsSelected(agent: MJAIAgentEntityExtended): boolean {\n return !!this.Conversation?.DefaultAgentID\n && UUIDsEqual(agent.ID, this.Conversation.DefaultAgentID);\n }\n\n public Toggle(event: MouseEvent): void {\n event.stopPropagation();\n if (this.Disabled || !this.Conversation) return;\n this.IsOpen = !this.IsOpen;\n this.cdr.markForCheck();\n }\n\n public async PickAgent(agent: MJAIAgentEntityExtended | null): Promise<void> {\n this.IsOpen = false;\n const conv = this.Conversation;\n if (!conv) return;\n const newId = agent?.ID ?? null;\n if (conv.DefaultAgentID === newId) {\n this.cdr.markForCheck();\n return;\n }\n const prev = conv.DefaultAgentID;\n conv.DefaultAgentID = newId;\n try {\n const saved = await conv.Save();\n if (!saved) {\n conv.DefaultAgentID = prev;\n this.notifications.CreateSimpleNotification(\n conv.LatestResult?.CompleteMessage ?? 'Failed to update conversation default agent.',\n 'error', 4500);\n return;\n }\n this.AgentChanged.emit(newId);\n } catch (err) {\n conv.DefaultAgentID = prev;\n LogError(`ConversationAgentPicker.PickAgent: ${err instanceof Error ? err.message : String(err)}`);\n } finally {\n this.cdr.markForCheck();\n }\n }\n\n /** Close the menu when the user clicks outside the picker. */\n @HostListener('document:click', ['$event'])\n public OnDocumentClick(_event: MouseEvent): void {\n if (this.IsOpen) {\n this.IsOpen = false;\n this.cdr.markForCheck();\n }\n }\n}\n"]}