@memberjunction/ng-conversations 5.4.1 → 5.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/components/agent/agent-process-panel.component.d.ts.map +1 -1
- package/dist/lib/components/agent/agent-process-panel.component.js +3 -2
- package/dist/lib/components/agent/agent-process-panel.component.js.map +1 -1
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +10 -9
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js.map +1 -1
- package/dist/lib/components/collection/artifact-create-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/artifact-create-modal.component.js +3 -2
- package/dist/lib/components/collection/artifact-create-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.js +4 -3
- package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.js +5 -4
- package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.d.ts +2 -0
- package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.js +24 -17
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.d.ts +1 -0
- package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +14 -10
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +21 -7
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +44 -14
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.d.ts +3 -0
- package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +21 -11
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/mention/mention-editor.component.d.ts.map +1 -1
- package/dist/lib/components/mention/mention-editor.component.js +4 -3
- package/dist/lib/components/mention/mention-editor.component.js.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.js +3 -2
- package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +21 -7
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +7 -6
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/project/project-selector.component.d.ts.map +1 -1
- package/dist/lib/components/project/project-selector.component.js +3 -2
- package/dist/lib/components/project/project-selector.component.js.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.js +4 -3
- package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts +4 -0
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +15 -6
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/artifact-permission.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-permission.service.js +3 -2
- package/dist/lib/services/artifact-permission.service.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +5 -4
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-attachment.service.js +2 -1
- package/dist/lib/services/conversation-attachment.service.js.map +1 -1
- package/dist/lib/services/conversation-data.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-data.service.js +7 -6
- package/dist/lib/services/conversation-data.service.js.map +1 -1
- package/dist/lib/services/data-cache.service.d.ts.map +1 -1
- package/dist/lib/services/data-cache.service.js +9 -8
- package/dist/lib/services/data-cache.service.js.map +1 -1
- package/package.json +17 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-process-panel.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/agent/agent-process-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAW,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;;
|
|
1
|
+
{"version":3,"file":"agent-process-panel.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/agent/agent-process-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAW,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;;AAGrG,UAAU,YAAa,SAAQ,eAAe;IAC5C,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,qBA+Sa,0BAA2B,YAAW,MAAM,EAAE,SAAS;IAUhE,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,iBAAiB;IAVlB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAG,QAAQ,CAAC;IAEzB,eAAe,EAAE,YAAY,EAAE,CAAM;IACrC,WAAW,EAAE,OAAO,CAAS;IAEpC,OAAO,CAAC,YAAY,CAAC,CAAe;gBAG1B,aAAa,EAAE,aAAa,EAC5B,iBAAiB,EAAE,iBAAiB;IAG9C,QAAQ,IAAI,IAAI;IAmBhB,WAAW,IAAI,IAAI;IAKnB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAI1C,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAW1C,cAAc,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI;IAoBhD,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB3D,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;yCA9F/B,0BAA0B;2CAA1B,0BAA0B;CAkGtC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Component, Input } from '@angular/core';
|
|
2
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
2
3
|
import * as i0 from "@angular/core";
|
|
3
4
|
import * as i1 from "../../services/dialog.service";
|
|
4
5
|
import * as i2 from "../../services/agent-state.service";
|
|
@@ -167,7 +168,7 @@ export class AgentProcessPanelComponent {
|
|
|
167
168
|
.subscribe(agents => {
|
|
168
169
|
// Preserve expanded state for existing processes
|
|
169
170
|
this.activeProcesses = agents.map(agent => {
|
|
170
|
-
const existing = this.activeProcesses.find(p => p.run.ID
|
|
171
|
+
const existing = this.activeProcesses.find(p => UUIDsEqual(p.run.ID, agent.run.ID));
|
|
171
172
|
return {
|
|
172
173
|
...agent,
|
|
173
174
|
expanded: existing ? existing.expanded : false
|
|
@@ -330,5 +331,5 @@ export class AgentProcessPanelComponent {
|
|
|
330
331
|
}], currentUser: [{
|
|
331
332
|
type: Input
|
|
332
333
|
}] }); })();
|
|
333
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AgentProcessPanelComponent, { className: "AgentProcessPanelComponent", filePath: "src/lib/components/agent/agent-process-panel.component.ts", lineNumber:
|
|
334
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AgentProcessPanelComponent, { className: "AgentProcessPanelComponent", filePath: "src/lib/components/agent/agent-process-panel.component.ts", lineNumber: 317 }); })();
|
|
334
335
|
//# sourceMappingURL=agent-process-panel.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-process-panel.component.js","sourceRoot":"","sources":["../../../../src/lib/components/agent/agent-process-panel.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, OnInit, OnDestroy } from '@angular/core';\nimport { UserInfo, RunView } from '@memberjunction/core';\nimport { MJAIAgentRunEntity } from '@memberjunction/core-entities';\nimport { Subscription, interval } from 'rxjs';\nimport { switchMap } from 'rxjs/operators';\nimport { DialogService } from '../../services/dialog.service';\nimport { AgentStateService, AgentStatus, AgentWithStatus } from '../../services/agent-state.service';\n\ninterface AgentProcess extends AgentWithStatus {\n expanded: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-agent-process-panel',\n template: `\n @if (activeProcesses.length > 0) {\n <div class=\"agent-panel\" [class.minimized]=\"isMinimized\">\n <div class=\"panel-header\">\n <h3>\n <i class=\"fas fa-robot\"></i>\n Active Agents ({{ activeProcesses.length }})\n </h3>\n <div class=\"header-actions\">\n <button class=\"header-btn\" (click)=\"isMinimized = !isMinimized\" [title]=\"isMinimized ? 'Expand' : 'Minimize'\">\n <i class=\"fas\" [ngClass]=\"isMinimized ? 'fa-chevron-up' : 'fa-chevron-down'\"></i>\n </button>\n </div>\n </div>\n\n @if (!isMinimized) {\n <div class=\"panel-content\">\n @for (process of activeProcesses; track process.run.ID) {\n <div class=\"process-item\">\n <div class=\"process-header\" (click)=\"toggleProcess(process)\">\n <div class=\"process-info\">\n <div class=\"agent-avatar-small\"\n [class.status-acknowledging]=\"process.status === 'acknowledging'\"\n [class.status-working]=\"process.status === 'working'\"\n [class.status-completing]=\"process.status === 'completing'\"\n [class.status-completed]=\"process.status === 'completed'\"\n [class.status-error]=\"process.status === 'error'\">\n <i class=\"fas fa-robot\"></i>\n @if (process.status !== 'completed') {\n <div class=\"pulse-dot\"></div>\n }\n </div>\n <div class=\"agent-details\">\n <span class=\"process-name\">{{ process.run.Agent || 'Agent' }}</span>\n <span class=\"process-status\" [class]=\"'status-' + process.status\">\n {{ getStatusText(process.status) }}\n </span>\n </div>\n @if (process.confidence != null) {\n <div class=\"confidence-indicator\" [title]=\"'Confidence: ' + (process.confidence * 100).toFixed(0) + '%'\">\n <i class=\"fas fa-gauge-high\"></i>\n <span>{{ (process.confidence * 100).toFixed(0) }}%</span>\n </div>\n }\n </div>\n <i class=\"fas\" [ngClass]=\"process.expanded ? 'fa-chevron-up' : 'fa-chevron-down'\"></i>\n </div>\n\n @if (process.expanded) {\n <div class=\"process-details\">\n @if (process.run.StartedAt) {\n <div class=\"detail-row\">\n <i class=\"fas fa-clock\"></i>\n <span>Started: {{ process.run.StartedAt | date:'short' }}</span>\n </div>\n }\n @if (getElapsedTime(process.run)) {\n <div class=\"detail-row\">\n <i class=\"fas fa-hourglass-half\"></i>\n <span>Duration: {{ getElapsedTime(process.run) }}</span>\n </div>\n }\n <div class=\"process-actions\">\n @if (process.run.Status === 'Running' || process.run.Status === 'Paused') {\n <button class=\"btn-action btn-cancel\" (click)=\"onCancelProcess(process)\">\n <i class=\"fas fa-stop\"></i> Cancel\n </button>\n }\n <button class=\"btn-action\" (click)=\"onViewDetails(process)\">\n <i class=\"fas fa-external-link-alt\"></i> View Details\n </button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n `,\n styles: [`\n .agent-panel {\n position: fixed;\n bottom: 24px;\n right: 24px;\n width: 450px;\n max-height: 600px;\n background: white;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.12);\n z-index: 1000;\n transition: all 300ms ease;\n overflow: hidden;\n }\n .agent-panel.minimized { width: 280px; max-height: 60px; }\n\n .panel-header {\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: linear-gradient(135deg, #F9FAFB, #F3F4F6);\n border-radius: 12px 12px 0 0;\n }\n .panel-header h3 {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 10px;\n color: #111827;\n }\n .header-actions { display: flex; gap: 4px; }\n .header-btn {\n padding: 8px;\n background: transparent;\n border: none;\n cursor: pointer;\n border-radius: 6px;\n color: #6B7280;\n transition: all 150ms ease;\n }\n .header-btn:hover { background: rgba(0,0,0,0.08); color: #111827; }\n\n .panel-content {\n max-height: 500px;\n overflow-y: auto;\n overflow-x: hidden;\n }\n\n .process-item {\n border-bottom: 1px solid #F3F4F6;\n transition: background 150ms ease;\n }\n .process-item:last-child { border-bottom: none; }\n .process-item:hover { background: #FAFAFA; }\n\n .process-header {\n padding: 14px 20px;\n cursor: pointer;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n }\n\n .process-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n }\n\n .agent-avatar-small {\n position: relative;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n }\n\n .agent-avatar-small.status-acknowledging { background: linear-gradient(135deg, #3B82F6, #2563EB); }\n .agent-avatar-small.status-working { background: linear-gradient(135deg, #F59E0B, #D97706); }\n .agent-avatar-small.status-completing { background: linear-gradient(135deg, #10B981, #059669); }\n .agent-avatar-small.status-completed { background: linear-gradient(135deg, #6B7280, #4B5563); opacity: 0.6; }\n .agent-avatar-small.status-error { background: linear-gradient(135deg, #EF4444, #DC2626); }\n\n .pulse-dot {\n position: absolute;\n top: -2px;\n right: -2px;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: #10B981;\n animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(1.5); }\n }\n\n .agent-details {\n display: flex;\n flex-direction: column;\n gap: 4px;\n flex: 1;\n min-width: 0;\n }\n\n .process-name {\n font-size: 14px;\n font-weight: 500;\n color: #111827;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .process-status {\n padding: 3px 8px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: inline-block;\n width: fit-content;\n }\n\n .status-acknowledging { background: #DBEAFE; color: #1E40AF; }\n .status-working { background: #FEF3C7; color: #B45309; }\n .status-completing { background: #D1FAE5; color: #065F46; }\n .status-completed { background: #F3F4F6; color: #6B7280; }\n .status-error { background: #FEE2E2; color: #991B1B; }\n\n .confidence-indicator {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n background: #F3F4F6;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 600;\n color: #374151;\n flex-shrink: 0;\n }\n\n .process-details {\n padding: 0 20px 16px 68px;\n animation: slideDown 200ms ease;\n }\n\n @keyframes slideDown {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .detail-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n font-size: 13px;\n color: #6B7280;\n }\n .detail-row i {\n width: 16px;\n color: #9CA3AF;\n text-align: center;\n }\n\n .process-actions {\n display: flex;\n gap: 8px;\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid #F3F4F6;\n }\n\n .btn-action {\n padding: 8px 14px;\n background: #3B82F6;\n color: white;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 150ms ease;\n }\n .btn-action:hover {\n background: #2563EB;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(59, 130, 246, 0.3);\n }\n\n .btn-cancel {\n background: #EF4444;\n }\n .btn-cancel:hover {\n background: #DC2626;\n box-shadow: 0 2px 4px rgba(239, 68, 68, 0.3);\n }\n `]\n})\nexport class AgentProcessPanelComponent implements OnInit, OnDestroy {\n @Input() conversationId?: string;\n @Input() currentUser!: UserInfo;\n\n public activeProcesses: AgentProcess[] = [];\n public isMinimized: boolean = false;\n\n private subscription?: Subscription;\n\n constructor(\n private dialogService: DialogService,\n private agentStateService: AgentStateService\n ) {}\n\n ngOnInit(): void {\n // Start polling for active agents\n this.agentStateService.startPolling(this.currentUser, this.conversationId);\n\n // Subscribe to active agents\n this.subscription = this.agentStateService\n .getActiveAgents(this.conversationId)\n .subscribe(agents => {\n // Preserve expanded state for existing processes\n this.activeProcesses = agents.map(agent => {\n const existing = this.activeProcesses.find(p => p.run.ID === agent.run.ID);\n return {\n ...agent,\n expanded: existing ? existing.expanded : false\n };\n });\n });\n }\n\n ngOnDestroy(): void {\n this.subscription?.unsubscribe();\n // Note: We don't stop polling here as other components may be using the service\n }\n\n toggleProcess(process: AgentProcess): void {\n process.expanded = !process.expanded;\n }\n\n getStatusText(status: AgentStatus): string {\n switch (status) {\n case 'acknowledging': return 'Acknowledging';\n case 'working': return 'Working';\n case 'completing': return 'Completing';\n case 'completed': return 'Completed';\n case 'error': return 'Error';\n default: return 'Active';\n }\n }\n\n getElapsedTime(run: MJAIAgentRunEntity): string | null {\n if (!run.StartedAt) return null;\n\n const start = new Date(run.StartedAt).getTime();\n const end = run.CompletedAt ? new Date(run.CompletedAt).getTime() : Date.now();\n const elapsed = end - start;\n\n const seconds = Math.floor(elapsed / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m`;\n } else if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n } else {\n return `${seconds}s`;\n }\n }\n\n async onCancelProcess(process: AgentProcess): Promise<void> {\n const confirmed = await this.dialogService.confirm({\n title: 'Cancel Agent',\n message: `Cancel agent \"${process.run.Agent || 'Agent'}\"?`,\n okText: 'Cancel Agent',\n cancelText: 'Keep Running'\n });\n\n if (!confirmed) return;\n\n try {\n const success = await this.agentStateService.cancelAgent(process.run.ID);\n if (!success) {\n await this.dialogService.alert('Error', 'Failed to cancel agent process');\n }\n } catch (error) {\n console.error('Failed to cancel agent process:', error);\n await this.dialogService.alert('Error', 'Failed to cancel agent process');\n }\n }\n\n onViewDetails(process: AgentProcess): void {\n // TODO: Navigate to agent run details page or open modal\n console.log('View agent run details:', process.run.ID);\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"agent-process-panel.component.js","sourceRoot":"","sources":["../../../../src/lib/components/agent/agent-process-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAqB,MAAM,eAAe,CAAC;AAOpE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;;;;;;;IAsC5B,0BAA6B;;;IAU/B,+BAAyG;IACvG,wBAAiC;IACjC,4BAAM;IAAA,YAA4C;IACpD,AADoD,iBAAO,EACrD;;;IAH4B,uFAAsE;IAEhG,eAA4C;IAA5C,wEAA4C;;;IAUpD,+BAAwB;IACtB,wBAA4B;IAC5B,4BAAM;IAAA,YAAmD;;IAC3D,AAD2D,iBAAO,EAC5D;;;IADE,eAAmD;IAAnD,2FAAmD;;;IAI3D,+BAAwB;IACtB,wBAAqC;IACrC,4BAAM;IAAA,YAA2C;IACnD,AADmD,iBAAO,EACpD;;;;IADE,eAA2C;IAA3C,0EAA2C;;;;IAKjD,kCAAyE;IAAnC,kSAAS,kCAAwB,KAAC;IACtE,wBAA2B;IAAC,wBAC9B;IAAA,iBAAS;;;;IAjBf,+BAA6B;IAC3B,8IAA6B;IAM7B,8IAAmC;IAMnC,+BAA6B;IAC3B,iJAA2E;IAK3E,kCAA4D;IAAjC,mRAAS,gCAAsB,KAAC;IACzD,wBAAwC;IAAC,8BAC3C;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;;IAtBJ,cAKC;IALD,mDAKC;IACD,cAKC;IALD,gEAKC;IAEC,eAIC;IAJD,oGAIC;;;;IAhDP,AADF,8BAA0B,aACqC;IAAjC,6OAAS,gCAAsB,KAAC;IAExD,AADF,+BAA0B,cAM+B;IACrD,uBAA4B;IAC5B,+HAAsC;IAGxC,iBAAM;IAEJ,AADF,+BAA2B,eACE;IAAA,YAAkC;IAAA,iBAAO;IACpE,gCAAkE;IAChE,aACF;IACF,AADE,iBAAO,EACH;IACN,iIAAkC;IAMpC,iBAAM;IACN,wBAAsF;IACxF,iBAAM;IAEN,iIAAwB;IA0B1B,iBAAM;;;;IApDK,eAAiE;IAIjE,AADA,AADA,AADA,AADA,6EAAiE,mDACZ,yDACM,uDACF,+CACR;IAEpD,eAEC;IAFD,4DAEC;IAG0B,eAAkC;IAAlC,qDAAkC;IAChC,cAAoC;IAApC,4CAAoC;IAC/D,cACF;IADE,wEACF;IAEF,cAKC;IALD,yDAKC;IAEY,cAAkE;IAAlE,mFAAkE;IAGnF,cAyBC;IAzBD,+CAyBC;;;IAzDP,8BAA2B;IACzB,2HA0DC;IACH,iBAAM;;;IA3DJ,cA0DC;IA1DD,qCA0DC;;;;IAvEH,AADF,AADF,8BAAyD,aAC7B,SACpB;IACF,uBAA4B;IAC5B,YACF;IAAA,iBAAK;IAEH,AADF,8BAA4B,gBACoF;IAAnF,2OAAoC;IAC7D,uBAAiF;IAGvF,AADE,AADE,iBAAS,EACL,EACF;IAEN,0GAAoB;IA+DtB,iBAAM;;;IA5EmB,+CAA+B;IAIlD,eACF;IADE,8EACF;IAEkE,eAA6C;IAA7C,kEAA6C;IAC5F,cAA6D;IAA7D,kFAA6D;IAKlF,cA8DC;IA9DD,8CA8DC;;AA+NT,MAAM,OAAO,0BAA0B;IAU3B;IACA;IAVD,cAAc,CAAU;IACxB,WAAW,CAAY;IAEzB,eAAe,GAAmB,EAAE,CAAC;IACrC,WAAW,GAAY,KAAK,CAAC;IAE5B,YAAY,CAAgB;IAEpC,YACU,aAA4B,EAC5B,iBAAoC;QADpC,kBAAa,GAAb,aAAa,CAAe;QAC5B,sBAAiB,GAAjB,iBAAiB,CAAmB;IAC3C,CAAC;IAEJ,QAAQ;QACN,kCAAkC;QAClC,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAE3E,6BAA6B;QAC7B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,iBAAiB;aACvC,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC;aACpC,SAAS,CAAC,MAAM,CAAC,EAAE;YAClB,iDAAiD;YACjD,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;gBACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpF,OAAO;oBACL,GAAG,KAAK;oBACR,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK;iBAC/C,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,WAAW;QACT,IAAI,CAAC,YAAY,EAAE,WAAW,EAAE,CAAC;QACjC,gFAAgF;IAClF,CAAC;IAED,aAAa,CAAC,OAAqB;QACjC,OAAO,CAAC,QAAQ,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;IACvC,CAAC;IAED,aAAa,CAAC,MAAmB;QAC/B,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,eAAe,CAAC,CAAC,OAAO,eAAe,CAAC;YAC7C,KAAK,SAAS,CAAC,CAAC,OAAO,SAAS,CAAC;YACjC,KAAK,YAAY,CAAC,CAAC,OAAO,YAAY,CAAC;YACvC,KAAK,WAAW,CAAC,CAAC,OAAO,WAAW,CAAC;YACrC,KAAK,OAAO,CAAC,CAAC,OAAO,OAAO,CAAC;YAC7B,OAAO,CAAC,CAAC,OAAO,QAAQ,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,cAAc,CAAC,GAAuB;QACpC,IAAI,CAAC,GAAG,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAEhC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/E,MAAM,OAAO,GAAG,GAAG,GAAG,KAAK,CAAC;QAE5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QAEvC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO,GAAG,KAAK,KAAK,OAAO,GAAG,EAAE,GAAG,CAAC;QACtC,CAAC;aAAM,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,GAAG,OAAO,KAAK,OAAO,GAAG,EAAE,GAAG,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,OAAO,GAAG,CAAC;QACvB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAAqB;QACzC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;YACjD,KAAK,EAAE,cAAc;YACrB,OAAO,EAAE,iBAAiB,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,IAAI;YAC1D,MAAM,EAAE,cAAc;YACtB,UAAU,EAAE,cAAc;SAC3B,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,gCAAgC,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YACxD,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,gCAAgC,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,aAAa,CAAC,OAAqB;QACjC,yDAAyD;QACzD,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC;oHAjGU,0BAA0B;6DAA1B,0BAA0B;YA3SnC,4FAAkC;;YAAlC,yDA8EC;;;iFA6NQ,0BAA0B;cA/StC,SAAS;6BACI,KAAK,YACP,wBAAwB,YACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFT;;kBA6NA,KAAK;;kBACL,KAAK;;kFAFK,0BAA0B","sourcesContent":["import { Component, Input, OnInit, OnDestroy } from '@angular/core';\nimport { UserInfo, RunView } from '@memberjunction/core';\nimport { MJAIAgentRunEntity } from '@memberjunction/core-entities';\nimport { Subscription, interval } from 'rxjs';\nimport { switchMap } from 'rxjs/operators';\nimport { DialogService } from '../../services/dialog.service';\nimport { AgentStateService, AgentStatus, AgentWithStatus } from '../../services/agent-state.service';\nimport { UUIDsEqual } from '@memberjunction/global';\n\ninterface AgentProcess extends AgentWithStatus {\n expanded: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-agent-process-panel',\n template: `\n @if (activeProcesses.length > 0) {\n <div class=\"agent-panel\" [class.minimized]=\"isMinimized\">\n <div class=\"panel-header\">\n <h3>\n <i class=\"fas fa-robot\"></i>\n Active Agents ({{ activeProcesses.length }})\n </h3>\n <div class=\"header-actions\">\n <button class=\"header-btn\" (click)=\"isMinimized = !isMinimized\" [title]=\"isMinimized ? 'Expand' : 'Minimize'\">\n <i class=\"fas\" [ngClass]=\"isMinimized ? 'fa-chevron-up' : 'fa-chevron-down'\"></i>\n </button>\n </div>\n </div>\n\n @if (!isMinimized) {\n <div class=\"panel-content\">\n @for (process of activeProcesses; track process.run.ID) {\n <div class=\"process-item\">\n <div class=\"process-header\" (click)=\"toggleProcess(process)\">\n <div class=\"process-info\">\n <div class=\"agent-avatar-small\"\n [class.status-acknowledging]=\"process.status === 'acknowledging'\"\n [class.status-working]=\"process.status === 'working'\"\n [class.status-completing]=\"process.status === 'completing'\"\n [class.status-completed]=\"process.status === 'completed'\"\n [class.status-error]=\"process.status === 'error'\">\n <i class=\"fas fa-robot\"></i>\n @if (process.status !== 'completed') {\n <div class=\"pulse-dot\"></div>\n }\n </div>\n <div class=\"agent-details\">\n <span class=\"process-name\">{{ process.run.Agent || 'Agent' }}</span>\n <span class=\"process-status\" [class]=\"'status-' + process.status\">\n {{ getStatusText(process.status) }}\n </span>\n </div>\n @if (process.confidence != null) {\n <div class=\"confidence-indicator\" [title]=\"'Confidence: ' + (process.confidence * 100).toFixed(0) + '%'\">\n <i class=\"fas fa-gauge-high\"></i>\n <span>{{ (process.confidence * 100).toFixed(0) }}%</span>\n </div>\n }\n </div>\n <i class=\"fas\" [ngClass]=\"process.expanded ? 'fa-chevron-up' : 'fa-chevron-down'\"></i>\n </div>\n\n @if (process.expanded) {\n <div class=\"process-details\">\n @if (process.run.StartedAt) {\n <div class=\"detail-row\">\n <i class=\"fas fa-clock\"></i>\n <span>Started: {{ process.run.StartedAt | date:'short' }}</span>\n </div>\n }\n @if (getElapsedTime(process.run)) {\n <div class=\"detail-row\">\n <i class=\"fas fa-hourglass-half\"></i>\n <span>Duration: {{ getElapsedTime(process.run) }}</span>\n </div>\n }\n <div class=\"process-actions\">\n @if (process.run.Status === 'Running' || process.run.Status === 'Paused') {\n <button class=\"btn-action btn-cancel\" (click)=\"onCancelProcess(process)\">\n <i class=\"fas fa-stop\"></i> Cancel\n </button>\n }\n <button class=\"btn-action\" (click)=\"onViewDetails(process)\">\n <i class=\"fas fa-external-link-alt\"></i> View Details\n </button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n `,\n styles: [`\n .agent-panel {\n position: fixed;\n bottom: 24px;\n right: 24px;\n width: 450px;\n max-height: 600px;\n background: white;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.12);\n z-index: 1000;\n transition: all 300ms ease;\n overflow: hidden;\n }\n .agent-panel.minimized { width: 280px; max-height: 60px; }\n\n .panel-header {\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: linear-gradient(135deg, #F9FAFB, #F3F4F6);\n border-radius: 12px 12px 0 0;\n }\n .panel-header h3 {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 10px;\n color: #111827;\n }\n .header-actions { display: flex; gap: 4px; }\n .header-btn {\n padding: 8px;\n background: transparent;\n border: none;\n cursor: pointer;\n border-radius: 6px;\n color: #6B7280;\n transition: all 150ms ease;\n }\n .header-btn:hover { background: rgba(0,0,0,0.08); color: #111827; }\n\n .panel-content {\n max-height: 500px;\n overflow-y: auto;\n overflow-x: hidden;\n }\n\n .process-item {\n border-bottom: 1px solid #F3F4F6;\n transition: background 150ms ease;\n }\n .process-item:last-child { border-bottom: none; }\n .process-item:hover { background: #FAFAFA; }\n\n .process-header {\n padding: 14px 20px;\n cursor: pointer;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n }\n\n .process-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n }\n\n .agent-avatar-small {\n position: relative;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n }\n\n .agent-avatar-small.status-acknowledging { background: linear-gradient(135deg, #3B82F6, #2563EB); }\n .agent-avatar-small.status-working { background: linear-gradient(135deg, #F59E0B, #D97706); }\n .agent-avatar-small.status-completing { background: linear-gradient(135deg, #10B981, #059669); }\n .agent-avatar-small.status-completed { background: linear-gradient(135deg, #6B7280, #4B5563); opacity: 0.6; }\n .agent-avatar-small.status-error { background: linear-gradient(135deg, #EF4444, #DC2626); }\n\n .pulse-dot {\n position: absolute;\n top: -2px;\n right: -2px;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: #10B981;\n animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(1.5); }\n }\n\n .agent-details {\n display: flex;\n flex-direction: column;\n gap: 4px;\n flex: 1;\n min-width: 0;\n }\n\n .process-name {\n font-size: 14px;\n font-weight: 500;\n color: #111827;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .process-status {\n padding: 3px 8px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: inline-block;\n width: fit-content;\n }\n\n .status-acknowledging { background: #DBEAFE; color: #1E40AF; }\n .status-working { background: #FEF3C7; color: #B45309; }\n .status-completing { background: #D1FAE5; color: #065F46; }\n .status-completed { background: #F3F4F6; color: #6B7280; }\n .status-error { background: #FEE2E2; color: #991B1B; }\n\n .confidence-indicator {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n background: #F3F4F6;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 600;\n color: #374151;\n flex-shrink: 0;\n }\n\n .process-details {\n padding: 0 20px 16px 68px;\n animation: slideDown 200ms ease;\n }\n\n @keyframes slideDown {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .detail-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n font-size: 13px;\n color: #6B7280;\n }\n .detail-row i {\n width: 16px;\n color: #9CA3AF;\n text-align: center;\n }\n\n .process-actions {\n display: flex;\n gap: 8px;\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid #F3F4F6;\n }\n\n .btn-action {\n padding: 8px 14px;\n background: #3B82F6;\n color: white;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 150ms ease;\n }\n .btn-action:hover {\n background: #2563EB;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(59, 130, 246, 0.3);\n }\n\n .btn-cancel {\n background: #EF4444;\n }\n .btn-cancel:hover {\n background: #DC2626;\n box-shadow: 0 2px 4px rgba(239, 68, 68, 0.3);\n }\n `]\n})\nexport class AgentProcessPanelComponent implements OnInit, OnDestroy {\n @Input() conversationId?: string;\n @Input() currentUser!: UserInfo;\n\n public activeProcesses: AgentProcess[] = [];\n public isMinimized: boolean = false;\n\n private subscription?: Subscription;\n\n constructor(\n private dialogService: DialogService,\n private agentStateService: AgentStateService\n ) {}\n\n ngOnInit(): void {\n // Start polling for active agents\n this.agentStateService.startPolling(this.currentUser, this.conversationId);\n\n // Subscribe to active agents\n this.subscription = this.agentStateService\n .getActiveAgents(this.conversationId)\n .subscribe(agents => {\n // Preserve expanded state for existing processes\n this.activeProcesses = agents.map(agent => {\n const existing = this.activeProcesses.find(p => UUIDsEqual(p.run.ID, agent.run.ID));\n return {\n ...agent,\n expanded: existing ? existing.expanded : false\n };\n });\n });\n }\n\n ngOnDestroy(): void {\n this.subscription?.unsubscribe();\n // Note: We don't stop polling here as other components may be using the service\n }\n\n toggleProcess(process: AgentProcess): void {\n process.expanded = !process.expanded;\n }\n\n getStatusText(status: AgentStatus): string {\n switch (status) {\n case 'acknowledging': return 'Acknowledging';\n case 'working': return 'Working';\n case 'completing': return 'Completing';\n case 'completed': return 'Completed';\n case 'error': return 'Error';\n default: return 'Active';\n }\n }\n\n getElapsedTime(run: MJAIAgentRunEntity): string | null {\n if (!run.StartedAt) return null;\n\n const start = new Date(run.StartedAt).getTime();\n const end = run.CompletedAt ? new Date(run.CompletedAt).getTime() : Date.now();\n const elapsed = end - start;\n\n const seconds = Math.floor(elapsed / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m`;\n } else if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n } else {\n return `${seconds}s`;\n }\n }\n\n async onCancelProcess(process: AgentProcess): Promise<void> {\n const confirmed = await this.dialogService.confirm({\n title: 'Cancel Agent',\n message: `Cancel agent \"${process.run.Agent || 'Agent'}\"?`,\n okText: 'Cancel Agent',\n cancelText: 'Keep Running'\n });\n\n if (!confirmed) return;\n\n try {\n const success = await this.agentStateService.cancelAgent(process.run.ID);\n if (!success) {\n await this.dialogService.alert('Error', 'Failed to cancel agent process');\n }\n } catch (error) {\n console.error('Failed to cancel agent process:', error);\n await this.dialogService.alert('Error', 'Failed to cancel agent process');\n }\n }\n\n onViewDetails(process: AgentProcess): void {\n // TODO: Navigate to agent run details page or open modal\n console.log('View agent run details:', process.run.ID);\n }\n}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-collection-picker-modal.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/collection/artifact-collection-picker-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAiB,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAG5H,OAAO,EAAE,QAAQ,EAAqB,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAKnE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;;
|
|
1
|
+
{"version":3,"file":"artifact-collection-picker-modal.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/collection/artifact-collection-picker-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAiB,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAG5H,OAAO,EAAE,QAAQ,EAAqB,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAKnE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;;AAGjH,UAAU,cAAc;IACtB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,qBA2ca,sCAAuC,YAAW,MAAM,EAAE,SAAS;IA6B5E,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,GAAG;IA9BJ,MAAM,EAAE,OAAO,CAAS;IACxB,aAAa,EAAG,MAAM,CAAC;IACvB,WAAW,EAAG,QAAQ,CAAC;IACvB,oBAAoB,EAAE,MAAM,EAAE,CAAM;IAEnC,KAAK,yBAAgC;IACrC,SAAS,qBAA4B;IAExC,cAAc,EAAE,kBAAkB,EAAE,CAAM;IAC1C,oBAAoB,EAAE,cAAc,EAAE,CAAM;IAC5C,mBAAmB,EAAE,kBAAkB,EAAE,CAAM;IAC/C,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAa;IAE/D,cAAc,EAAE,cAAc,EAAE,CAAM;IACtC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,uBAAuB,EAAE,kBAAkB,GAAG,SAAS,CAAa;IAEpE,WAAW,EAAE,MAAM,CAAM;IACzB,SAAS,EAAE,OAAO,CAAS;IAC3B,QAAQ,EAAE,OAAO,CAAS;IAC1B,YAAY,EAAE,MAAM,CAAM;IAG1B,cAAc,EAAE,OAAO,CAAS;IAChC,iBAAiB,EAAE,MAAM,CAAM;IAC/B,oBAAoB,EAAE,OAAO,CAAS;gBAGnC,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,2BAA2B,EAC9C,GAAG,EAAE,iBAAiB;IAG1B,QAAQ;IAMR,WAAW,CAAC,OAAO,EAAE,GAAG;IAO9B,OAAO,CAAC,KAAK;YAYC,eAAe;YA0Cf,mBAAmB;IAsBjC,OAAO,CAAC,sBAAsB;IAK9B,OAAO,CAAC,uBAAuB;IAK/B,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO;IAWhD,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAgB3C,mBAAmB,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAmBzD,cAAc,IAAI,IAAI;IAatB,oBAAoB,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAmB1D,cAAc,IAAI,IAAI;IA0BhB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAmEjC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB7B,QAAQ,IAAI,IAAI;yCA7UL,sCAAsC;2CAAtC,sCAAsC;CAgVlD"}
|
|
@@ -5,6 +5,7 @@ import { DialogModule } from '@progress/kendo-angular-dialog';
|
|
|
5
5
|
import { ButtonsModule } from '@progress/kendo-angular-buttons';
|
|
6
6
|
import { InputsModule } from '@progress/kendo-angular-inputs';
|
|
7
7
|
import { SharedGenericModule } from '@memberjunction/ng-shared-generic';
|
|
8
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
8
9
|
import * as i0 from "@angular/core";
|
|
9
10
|
import * as i1 from "../../services/toast.service";
|
|
10
11
|
import * as i2 from "../../services/collection-permission.service";
|
|
@@ -356,7 +357,7 @@ export class ArtifactCollectionPickerModalComponent {
|
|
|
356
357
|
}
|
|
357
358
|
async loadUserPermissions() {
|
|
358
359
|
// Load permissions for collections not owned by current user
|
|
359
|
-
const nonOwnedCollections = this.allCollections.filter(c => c.OwnerID && c.OwnerID
|
|
360
|
+
const nonOwnedCollections = this.allCollections.filter(c => c.OwnerID && !UUIDsEqual(c.OwnerID, this.currentUser.ID));
|
|
360
361
|
if (nonOwnedCollections.length === 0) {
|
|
361
362
|
return;
|
|
362
363
|
}
|
|
@@ -371,22 +372,22 @@ export class ArtifactCollectionPickerModalComponent {
|
|
|
371
372
|
this.displayedCollections = rootCollections.map(c => this.createNode(c, editableCollections));
|
|
372
373
|
}
|
|
373
374
|
displayChildCollections(parentId, editableCollections) {
|
|
374
|
-
const childCollections = editableCollections.filter(c => c.ParentID
|
|
375
|
+
const childCollections = editableCollections.filter(c => UUIDsEqual(c.ParentID, parentId));
|
|
375
376
|
this.displayedCollections = childCollections.map(c => this.createNode(c, editableCollections));
|
|
376
377
|
}
|
|
377
378
|
createNode(collection, allEditableCollections) {
|
|
378
|
-
const hasChildren = allEditableCollections.some(c => c.ParentID
|
|
379
|
-
const alreadyContainsArtifact = this.excludeCollectionIds.
|
|
379
|
+
const hasChildren = allEditableCollections.some(c => UUIDsEqual(c.ParentID, collection.ID));
|
|
380
|
+
const alreadyContainsArtifact = this.excludeCollectionIds.some(id => UUIDsEqual(id, collection.ID));
|
|
380
381
|
return {
|
|
381
382
|
collection,
|
|
382
|
-
selected: this.selectedCollections.some(sc => sc.ID
|
|
383
|
+
selected: this.selectedCollections.some(sc => UUIDsEqual(sc.ID, collection.ID)),
|
|
383
384
|
hasChildren,
|
|
384
385
|
alreadyContainsArtifact
|
|
385
386
|
};
|
|
386
387
|
}
|
|
387
388
|
canEdit(collection) {
|
|
388
389
|
// Backwards compatibility: treat null OwnerID as owned by current user
|
|
389
|
-
if (!collection.OwnerID || collection.OwnerID
|
|
390
|
+
if (!collection.OwnerID || UUIDsEqual(collection.OwnerID, this.currentUser.ID)) {
|
|
390
391
|
return true;
|
|
391
392
|
}
|
|
392
393
|
// Check permission record
|
|
@@ -398,7 +399,7 @@ export class ArtifactCollectionPickerModalComponent {
|
|
|
398
399
|
if (node.alreadyContainsArtifact) {
|
|
399
400
|
return;
|
|
400
401
|
}
|
|
401
|
-
const index = this.selectedCollections.findIndex(c => c.ID
|
|
402
|
+
const index = this.selectedCollections.findIndex(c => UUIDsEqual(c.ID, node.collection.ID));
|
|
402
403
|
if (index >= 0) {
|
|
403
404
|
this.selectedCollections.splice(index, 1);
|
|
404
405
|
node.selected = false;
|
|
@@ -434,7 +435,7 @@ export class ArtifactCollectionPickerModalComponent {
|
|
|
434
435
|
}
|
|
435
436
|
navigateToCollection(collection) {
|
|
436
437
|
// Find the index of this collection in the navigation path
|
|
437
|
-
const index = this.navigationPath.findIndex(n => n.collection.ID
|
|
438
|
+
const index = this.navigationPath.findIndex(n => UUIDsEqual(n.collection.ID, collection.ID));
|
|
438
439
|
if (index >= 0) {
|
|
439
440
|
// Trim navigation path to this level
|
|
440
441
|
this.navigationPath = this.navigationPath.slice(0, index + 1);
|
|
@@ -728,5 +729,5 @@ export class ArtifactCollectionPickerModalComponent {
|
|
|
728
729
|
}], cancelled: [{
|
|
729
730
|
type: Output
|
|
730
731
|
}] }); })();
|
|
731
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactCollectionPickerModalComponent, { className: "ArtifactCollectionPickerModalComponent", filePath: "src/lib/components/collection/artifact-collection-picker-modal.component.ts", lineNumber:
|
|
732
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactCollectionPickerModalComponent, { className: "ArtifactCollectionPickerModalComponent", filePath: "src/lib/components/collection/artifact-collection-picker-modal.component.ts", lineNumber: 489 }); })();
|
|
732
733
|
//# sourceMappingURL=artifact-collection-picker-modal.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-collection-picker-modal.component.js","sourceRoot":"","sources":["../../../../src/lib/components/collection/artifact-collection-picker-modal.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core';\n\nimport { FormsModule } from '@angular/forms';\nimport { UserInfo, RunView, Metadata } from '@memberjunction/core';\nimport { MJCollectionEntity } from '@memberjunction/core-entities';\nimport { DialogModule } from '@progress/kendo-angular-dialog';\nimport { ButtonsModule } from '@progress/kendo-angular-buttons';\nimport { InputsModule } from '@progress/kendo-angular-inputs';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { ToastService } from '../../services/toast.service';\nimport { CollectionPermissionService, CollectionPermission } from '../../services/collection-permission.service';\n\ninterface CollectionNode {\n collection: MJCollectionEntity;\n selected: boolean;\n hasChildren: boolean;\n alreadyContainsArtifact: boolean;\n}\n\n/**\n * Modal for selecting collections to save artifacts to.\n * Features:\n * - Permission-aware: only shows collections where user has Edit permission\n * - Hierarchical navigation: start with root collections, drill down as needed\n * - Search by name\n * - Multi-selection support\n * - Create new collection with proper permission logic\n */\n@Component({\n selector: 'mj-artifact-collection-picker-modal',\n standalone: true,\n imports: [\n FormsModule,\n DialogModule,\n ButtonsModule,\n InputsModule,\n SharedGenericModule\n],\n template: `\n @if (isOpen) {\n <kendo-dialog\n title=\"Save to Collection\"\n (close)=\"onCancel()\"\n [width]=\"700\"\n [minWidth]=\"500\">\n <div class=\"picker-modal\">\n <!-- Breadcrumb Navigation -->\n @if (navigationPath.length > 0) {\n <div class=\"breadcrumb-nav\">\n <button class=\"breadcrumb-btn\" (click)=\"navigateToRoot()\">\n <i class=\"fas fa-home\"></i> Root\n </button>\n @for (item of navigationPath; track item.collection.ID) {\n <i class=\"fas fa-chevron-right breadcrumb-separator\"></i>\n <button class=\"breadcrumb-btn\" (click)=\"navigateToCollection(item.collection)\">\n {{ item.collection.Name }}\n </button>\n }\n </div>\n }\n <!-- Search Bar -->\n <div class=\"search-bar\">\n <i class=\"fas fa-search search-icon\"></i>\n <input\n type=\"text\"\n class=\"k-textbox search-input\"\n [(ngModel)]=\"searchQuery\"\n (input)=\"onSearchChange()\"\n placeholder=\"Search collections...\"\n [disabled]=\"isLoading\">\n </div>\n <!-- Collections List -->\n @if (!isLoading && !errorMessage) {\n <div class=\"collections-list\">\n @if (displayedCollections.length === 0) {\n <div class=\"empty-state\">\n @if (searchQuery) {\n <i class=\"fas fa-search\"></i>\n <p>No collections found matching \"{{ searchQuery }}\"</p>\n } @else if (currentParentId) {\n <i class=\"fas fa-folder-open\"></i>\n <p>No sub-collections available</p>\n } @else {\n <i class=\"fas fa-folder\"></i>\n <p>No collections available</p>\n <p class=\"hint\">Create a new collection to get started</p>\n }\n </div>\n } @else {\n @for (node of displayedCollections; track node.collection.ID) {\n <div class=\"collection-item\"\n [class.already-added]=\"node.alreadyContainsArtifact\"\n (click)=\"toggleSelection(node)\">\n <div class=\"collection-checkbox\">\n <input\n type=\"checkbox\"\n [checked]=\"node.selected\"\n [disabled]=\"node.alreadyContainsArtifact\"\n (click)=\"$event.stopPropagation(); toggleSelection(node)\">\n </div>\n <i class=\"fas fa-folder collection-icon\" [style.color]=\"node.collection.Color || '#0076B6'\"></i>\n <span class=\"collection-name\">{{ node.collection.Name }}</span>\n @if (node.alreadyContainsArtifact) {\n <span class=\"already-added-badge\">\n <i class=\"fas fa-check-circle\"></i> Already added\n </span>\n }\n @if (node.hasChildren) {\n <button\n class=\"drill-down-btn\"\n (click)=\"$event.stopPropagation(); drillIntoCollection(node.collection)\"\n title=\"View sub-collections\">\n <i class=\"fas fa-chevron-right\"></i>\n </button>\n }\n </div>\n }\n }\n </div>\n }\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading collections...\" size=\"medium\"></mj-loading>\n </div>\n }\n <!-- Error State -->\n @if (errorMessage) {\n <div class=\"error-state\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <span>{{ errorMessage }}</span>\n </div>\n }\n <!-- Selected Collections Summary -->\n @if (selectedCollections.length > 0) {\n <div class=\"selected-summary\">\n <i class=\"fas fa-check-circle\"></i>\n <span>{{ selectedCollections.length }} collection(s) selected</span>\n </div>\n }\n <!-- Create New Collection Section -->\n <div class=\"create-section\">\n <div class=\"divider\">\n <span>OR CREATE NEW</span>\n </div>\n @if (!showCreateForm) {\n <button class=\"btn-create-collection\" (click)=\"showCreateForm = true\">\n <i class=\"fas fa-plus\"></i>\n Create New Collection\n </button>\n } @else {\n <div class=\"create-form\">\n <input\n type=\"text\"\n class=\"k-textbox create-input\"\n [(ngModel)]=\"newCollectionName\"\n placeholder=\"Enter collection name\"\n (keydown.enter)=\"createCollection()\"\n #newCollectionInput>\n <div class=\"create-actions\">\n <button class=\"btn-create\" kendoButton (click)=\"createCollection()\" [disabled]=\"isCreatingCollection || !newCollectionName.trim()\">\n @if (isCreatingCollection) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n } @else {\n Create\n }\n </button>\n <button class=\"btn-cancel\" kendoButton (click)=\"showCreateForm = false; newCollectionName = ''\">\n Cancel\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"onCancel()\">\n Cancel\n </button>\n <button kendoButton\n [primary]=\"true\"\n (click)=\"onSave()\"\n [disabled]=\"selectedCollections.length === 0 || isSaving\">\n @if (isSaving) {\n <i class=\"fas fa-spinner fa-spin\"></i> Saving...\n } @else {\n <i class=\"fas fa-save\"></i> Save to {{ selectedCollections.length }} Collection(s)\n }\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n }\n `,\n styles: [`\n .picker-modal {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 20px 0;\n min-height: 400px;\n max-height: 600px;\n }\n\n .breadcrumb-nav {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: #F9FAFB;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n overflow-x: auto;\n }\n\n .breadcrumb-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: #0076B6;\n cursor: pointer;\n white-space: nowrap;\n font-size: 14px;\n }\n\n .breadcrumb-btn:hover {\n background: #E5E7EB;\n }\n\n .breadcrumb-separator {\n color: #9CA3AF;\n font-size: 12px;\n }\n\n .search-bar {\n position: relative;\n display: flex;\n align-items: center;\n }\n\n .search-icon {\n position: absolute;\n left: 12px;\n color: #9CA3AF;\n pointer-events: none;\n }\n\n .search-input {\n width: 100%;\n padding-left: 36px;\n }\n\n .collections-list {\n flex: 1;\n overflow-y: auto;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n min-height: 250px;\n max-height: 350px;\n }\n\n .collection-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border-bottom: 1px solid #F3F4F6;\n cursor: pointer;\n transition: background 0.2s;\n }\n\n .collection-item:hover {\n background: #F9FAFB;\n }\n\n .collection-item:last-child {\n border-bottom: none;\n }\n\n .collection-item.already-added {\n background: #F9FAFB;\n opacity: 0.7;\n cursor: not-allowed;\n }\n\n .collection-item.already-added:hover {\n background: #F9FAFB;\n }\n\n .collection-checkbox {\n display: flex;\n align-items: center;\n }\n\n .collection-checkbox input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n }\n\n .collection-icon {\n font-size: 18px;\n flex-shrink: 0;\n }\n\n .collection-name {\n flex: 1;\n font-size: 14px;\n color: #1F2937;\n }\n\n .already-added-badge {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n background: #DBEAFE;\n border: 1px solid #93C5FD;\n border-radius: 12px;\n color: #1E40AF;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n }\n\n .already-added-badge i {\n font-size: 12px;\n color: #2563EB;\n }\n\n .drill-down-btn {\n padding: 6px 10px;\n background: transparent;\n border: 1px solid #D1D5DB;\n border-radius: 4px;\n color: #6B7280;\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .drill-down-btn:hover {\n background: #F3F4F6;\n border-color: #9CA3AF;\n color: #374151;\n }\n\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n color: #6B7280;\n text-align: center;\n }\n\n .empty-state i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.4;\n }\n\n .empty-state p {\n margin: 4px 0;\n font-size: 14px;\n }\n\n .empty-state .hint {\n font-size: 13px;\n color: #9CA3AF;\n }\n\n .loading-state, .error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n gap: 12px;\n color: #6B7280;\n }\n\n .error-state i {\n font-size: 32px;\n }\n\n .error-state {\n color: #DC2626;\n }\n\n .selected-summary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: #DBEAFE;\n border: 1px solid #93C5FD;\n border-radius: 6px;\n color: #1E40AF;\n font-size: 14px;\n font-weight: 500;\n }\n\n .selected-summary i {\n color: #2563EB;\n }\n\n .create-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .divider {\n display: flex;\n align-items: center;\n text-align: center;\n color: #9CA3AF;\n font-size: 12px;\n font-weight: 500;\n }\n\n .divider::before,\n .divider::after {\n content: '';\n flex: 1;\n border-bottom: 1px solid #E5E7EB;\n }\n\n .divider span {\n padding: 0 12px;\n }\n\n .btn-create-collection {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n background: #F9FAFB;\n border: 2px dashed #D1D5DB;\n border-radius: 6px;\n color: #0076B6;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .btn-create-collection:hover {\n background: #F3F4F6;\n border-color: #0076B6;\n }\n\n .btn-create-collection i {\n font-size: 16px;\n }\n\n .create-form {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n background: #F9FAFB;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n }\n\n .create-input {\n width: 100%;\n }\n\n .create-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n }\n\n .btn-create, .btn-cancel {\n padding: 8px 16px;\n font-size: 14px;\n }\n `]\n})\nexport class ArtifactCollectionPickerModalComponent implements OnInit, OnChanges {\n @Input() isOpen: boolean = false;\n @Input() environmentId!: string;\n @Input() currentUser!: UserInfo;\n @Input() excludeCollectionIds: string[] = []; // Collections to exclude (e.g., already contains artifact)\n\n @Output() saved = new EventEmitter<string[]>(); // Emits selected collection IDs\n @Output() cancelled = new EventEmitter<void>();\n\n public allCollections: MJCollectionEntity[] = [];\n public displayedCollections: CollectionNode[] = [];\n public selectedCollections: MJCollectionEntity[] = [];\n public userPermissions: Map<string, CollectionPermission> = new Map();\n\n public navigationPath: CollectionNode[] = []; // Breadcrumb trail\n public currentParentId: string | null = null;\n public currentParentCollection: MJCollectionEntity | undefined = undefined;\n\n public searchQuery: string = '';\n public isLoading: boolean = false;\n public isSaving: boolean = false;\n public errorMessage: string = '';\n\n // Create collection form state\n public showCreateForm: boolean = false;\n public newCollectionName: string = '';\n public isCreatingCollection: boolean = false;\n\n constructor(\n private toastService: ToastService,\n private permissionService: CollectionPermissionService,\n private cdr: ChangeDetectorRef\n ) {}\n\n async ngOnInit() {\n if (this.isOpen) {\n await this.loadCollections();\n }\n }\n\n async ngOnChanges(changes: any) {\n if (changes['isOpen'] && this.isOpen) {\n this.reset();\n await this.loadCollections();\n }\n }\n\n private reset(): void {\n this.allCollections = [];\n this.displayedCollections = [];\n this.selectedCollections = [];\n this.userPermissions.clear();\n this.navigationPath = [];\n this.currentParentId = null;\n this.currentParentCollection = undefined;\n this.searchQuery = '';\n this.errorMessage = '';\n }\n\n private async loadCollections(): Promise<void> {\n try {\n this.isLoading = true;\n this.errorMessage = '';\n\n // Load all collections in environment\n const rv = new RunView();\n const result = await rv.RunView<MJCollectionEntity>({\n EntityName: 'MJ: Collections',\n ExtraFilter: `EnvironmentID='${this.environmentId}'`,\n OrderBy: 'Name ASC',\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (!result.Success) {\n this.errorMessage = result.ErrorMessage || 'Failed to load collections';\n return;\n }\n\n this.allCollections = result.Results || [];\n\n // Load user permissions for all collections\n await this.loadUserPermissions();\n\n // Filter to collections with Edit permission\n // Include collections that already contain the artifact (will be shown as disabled)\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n\n // Show root collections initially\n this.displayRootCollections(editableCollections);\n\n } catch (error) {\n console.error('Error loading collections:', error);\n this.errorMessage = 'An error occurred while loading collections';\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private async loadUserPermissions(): Promise<void> {\n // Load permissions for collections not owned by current user\n const nonOwnedCollections = this.allCollections.filter(\n c => c.OwnerID && c.OwnerID !== this.currentUser.ID\n );\n\n if (nonOwnedCollections.length === 0) {\n return;\n }\n\n const collectionIds = nonOwnedCollections.map(c => c.ID);\n const permissions = await this.permissionService.checkBulkPermissions(\n collectionIds,\n this.currentUser.ID,\n this.currentUser\n );\n\n permissions.forEach((permission, collectionId) => {\n this.userPermissions.set(collectionId, permission);\n });\n }\n\n private displayRootCollections(editableCollections: MJCollectionEntity[]): void {\n const rootCollections = editableCollections.filter(c => !c.ParentID);\n this.displayedCollections = rootCollections.map(c => this.createNode(c, editableCollections));\n }\n\n private displayChildCollections(parentId: string, editableCollections: MJCollectionEntity[]): void {\n const childCollections = editableCollections.filter(c => c.ParentID === parentId);\n this.displayedCollections = childCollections.map(c => this.createNode(c, editableCollections));\n }\n\n private createNode(collection: MJCollectionEntity, allEditableCollections: MJCollectionEntity[]): CollectionNode {\n const hasChildren = allEditableCollections.some(c => c.ParentID === collection.ID);\n const alreadyContainsArtifact = this.excludeCollectionIds.includes(collection.ID);\n return {\n collection,\n selected: this.selectedCollections.some(sc => sc.ID === collection.ID),\n hasChildren,\n alreadyContainsArtifact\n };\n }\n\n canEdit(collection: MJCollectionEntity): boolean {\n // Backwards compatibility: treat null OwnerID as owned by current user\n if (!collection.OwnerID || collection.OwnerID === this.currentUser.ID) {\n return true;\n }\n\n // Check permission record\n const permission = this.userPermissions.get(collection.ID);\n return permission?.canEdit || false;\n }\n\n toggleSelection(node: CollectionNode): void {\n // Don't allow selection of collections that already contain the artifact\n if (node.alreadyContainsArtifact) {\n return;\n }\n\n const index = this.selectedCollections.findIndex(c => c.ID === node.collection.ID);\n if (index >= 0) {\n this.selectedCollections.splice(index, 1);\n node.selected = false;\n } else {\n this.selectedCollections.push(node.collection);\n node.selected = true;\n }\n }\n\n drillIntoCollection(collection: MJCollectionEntity): void {\n // Add current location to navigation path\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n\n const node = this.createNode(collection, editableCollections);\n this.navigationPath.push(node);\n\n this.currentParentId = collection.ID;\n this.currentParentCollection = collection;\n\n // Display child collections\n this.displayChildCollections(collection.ID, editableCollections);\n\n // Clear search when drilling down\n this.searchQuery = '';\n }\n\n navigateToRoot(): void {\n this.navigationPath = [];\n this.currentParentId = null;\n this.currentParentCollection = undefined;\n\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n\n this.displayRootCollections(editableCollections);\n this.searchQuery = '';\n }\n\n navigateToCollection(collection: MJCollectionEntity): void {\n // Find the index of this collection in the navigation path\n const index = this.navigationPath.findIndex(n => n.collection.ID === collection.ID);\n\n if (index >= 0) {\n // Trim navigation path to this level\n this.navigationPath = this.navigationPath.slice(0, index + 1);\n this.currentParentId = collection.ID;\n this.currentParentCollection = collection;\n\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n\n this.displayChildCollections(collection.ID, editableCollections);\n this.searchQuery = '';\n }\n }\n\n onSearchChange(): void {\n if (!this.searchQuery.trim()) {\n // Reset to current navigation context\n if (this.currentParentId) {\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n this.displayChildCollections(this.currentParentId, editableCollections);\n } else {\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n this.displayRootCollections(editableCollections);\n }\n return;\n }\n\n // Search across all editable collections\n const query = this.searchQuery.toLowerCase();\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c) && c.Name.toLowerCase().includes(query);\n });\n\n this.displayedCollections = editableCollections.map(c => this.createNode(c, editableCollections));\n }\n\n async createCollection(): Promise<void> {\n if (!this.newCollectionName.trim()) {\n this.toastService.warning('Please enter a collection name');\n return;\n }\n\n try {\n this.isCreatingCollection = true;\n const md = new Metadata();\n const collection = await md.GetEntityObject<MJCollectionEntity>('MJ: Collections', this.currentUser);\n\n collection.Name = this.newCollectionName.trim();\n collection.EnvironmentID = this.environmentId;\n\n // Set parent and owner based on current navigation context\n if (this.currentParentCollection) {\n // Creating sub-collection - inherit parent's owner\n collection.ParentID = this.currentParentCollection.ID;\n collection.OwnerID = this.currentParentCollection.OwnerID || this.currentUser.ID;\n } else {\n // Creating root collection - current user becomes owner\n collection.OwnerID = this.currentUser.ID;\n }\n\n const saved = await collection.Save();\n\n if (saved) {\n // Create owner permission or copy parent permissions\n if (this.currentParentCollection) {\n // Copy permissions from parent\n await this.permissionService.copyParentPermissions(\n this.currentParentCollection.ID,\n collection.ID,\n this.currentUser\n );\n } else {\n // Create owner permission\n await this.permissionService.createOwnerPermission(\n collection.ID,\n this.currentUser.ID,\n this.currentUser\n );\n }\n\n this.toastService.success('Collection created successfully');\n\n // Reset form\n this.showCreateForm = false;\n this.newCollectionName = '';\n\n // Reload collections to include the new one\n await this.loadCollections();\n\n // Auto-select the newly created collection\n this.selectedCollections.push(collection);\n } else {\n this.toastService.error(collection.LatestResult?.Message || 'Failed to create collection');\n }\n } catch (error) {\n console.error('Error creating collection:', error);\n this.toastService.error('An error occurred while creating the collection');\n } finally {\n this.isCreatingCollection = false;\n this.cdr.detectChanges();\n }\n }\n\n async onSave(): Promise<void> {\n if (this.selectedCollections.length === 0) {\n this.toastService.warning('Please select at least one collection');\n return;\n }\n\n this.isSaving = true;\n\n try {\n // Emit the selected collection IDs - parent handles actual saving and modal close\n const collectionIds = this.selectedCollections.map(c => c.ID);\n this.saved.emit(collectionIds);\n } finally {\n this.isSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n onCancel(): void {\n this.cancelled.emit();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"artifact-collection-picker-modal.component.js","sourceRoot":"","sources":["../../../../src/lib/components/collection/artifact-collection-picker-modal.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core';\n\nimport { FormsModule } from '@angular/forms';\nimport { UserInfo, RunView, Metadata } from '@memberjunction/core';\nimport { MJCollectionEntity } from '@memberjunction/core-entities';\nimport { DialogModule } from '@progress/kendo-angular-dialog';\nimport { ButtonsModule } from '@progress/kendo-angular-buttons';\nimport { InputsModule } from '@progress/kendo-angular-inputs';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { ToastService } from '../../services/toast.service';\nimport { CollectionPermissionService, CollectionPermission } from '../../services/collection-permission.service';\nimport { UUIDsEqual } from '@memberjunction/global';\n\ninterface CollectionNode {\n collection: MJCollectionEntity;\n selected: boolean;\n hasChildren: boolean;\n alreadyContainsArtifact: boolean;\n}\n\n/**\n * Modal for selecting collections to save artifacts to.\n * Features:\n * - Permission-aware: only shows collections where user has Edit permission\n * - Hierarchical navigation: start with root collections, drill down as needed\n * - Search by name\n * - Multi-selection support\n * - Create new collection with proper permission logic\n */\n@Component({\n selector: 'mj-artifact-collection-picker-modal',\n standalone: true,\n imports: [\n FormsModule,\n DialogModule,\n ButtonsModule,\n InputsModule,\n SharedGenericModule\n],\n template: `\n @if (isOpen) {\n <kendo-dialog\n title=\"Save to Collection\"\n (close)=\"onCancel()\"\n [width]=\"700\"\n [minWidth]=\"500\">\n <div class=\"picker-modal\">\n <!-- Breadcrumb Navigation -->\n @if (navigationPath.length > 0) {\n <div class=\"breadcrumb-nav\">\n <button class=\"breadcrumb-btn\" (click)=\"navigateToRoot()\">\n <i class=\"fas fa-home\"></i> Root\n </button>\n @for (item of navigationPath; track item.collection.ID) {\n <i class=\"fas fa-chevron-right breadcrumb-separator\"></i>\n <button class=\"breadcrumb-btn\" (click)=\"navigateToCollection(item.collection)\">\n {{ item.collection.Name }}\n </button>\n }\n </div>\n }\n <!-- Search Bar -->\n <div class=\"search-bar\">\n <i class=\"fas fa-search search-icon\"></i>\n <input\n type=\"text\"\n class=\"k-textbox search-input\"\n [(ngModel)]=\"searchQuery\"\n (input)=\"onSearchChange()\"\n placeholder=\"Search collections...\"\n [disabled]=\"isLoading\">\n </div>\n <!-- Collections List -->\n @if (!isLoading && !errorMessage) {\n <div class=\"collections-list\">\n @if (displayedCollections.length === 0) {\n <div class=\"empty-state\">\n @if (searchQuery) {\n <i class=\"fas fa-search\"></i>\n <p>No collections found matching \"{{ searchQuery }}\"</p>\n } @else if (currentParentId) {\n <i class=\"fas fa-folder-open\"></i>\n <p>No sub-collections available</p>\n } @else {\n <i class=\"fas fa-folder\"></i>\n <p>No collections available</p>\n <p class=\"hint\">Create a new collection to get started</p>\n }\n </div>\n } @else {\n @for (node of displayedCollections; track node.collection.ID) {\n <div class=\"collection-item\"\n [class.already-added]=\"node.alreadyContainsArtifact\"\n (click)=\"toggleSelection(node)\">\n <div class=\"collection-checkbox\">\n <input\n type=\"checkbox\"\n [checked]=\"node.selected\"\n [disabled]=\"node.alreadyContainsArtifact\"\n (click)=\"$event.stopPropagation(); toggleSelection(node)\">\n </div>\n <i class=\"fas fa-folder collection-icon\" [style.color]=\"node.collection.Color || '#0076B6'\"></i>\n <span class=\"collection-name\">{{ node.collection.Name }}</span>\n @if (node.alreadyContainsArtifact) {\n <span class=\"already-added-badge\">\n <i class=\"fas fa-check-circle\"></i> Already added\n </span>\n }\n @if (node.hasChildren) {\n <button\n class=\"drill-down-btn\"\n (click)=\"$event.stopPropagation(); drillIntoCollection(node.collection)\"\n title=\"View sub-collections\">\n <i class=\"fas fa-chevron-right\"></i>\n </button>\n }\n </div>\n }\n }\n </div>\n }\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading collections...\" size=\"medium\"></mj-loading>\n </div>\n }\n <!-- Error State -->\n @if (errorMessage) {\n <div class=\"error-state\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <span>{{ errorMessage }}</span>\n </div>\n }\n <!-- Selected Collections Summary -->\n @if (selectedCollections.length > 0) {\n <div class=\"selected-summary\">\n <i class=\"fas fa-check-circle\"></i>\n <span>{{ selectedCollections.length }} collection(s) selected</span>\n </div>\n }\n <!-- Create New Collection Section -->\n <div class=\"create-section\">\n <div class=\"divider\">\n <span>OR CREATE NEW</span>\n </div>\n @if (!showCreateForm) {\n <button class=\"btn-create-collection\" (click)=\"showCreateForm = true\">\n <i class=\"fas fa-plus\"></i>\n Create New Collection\n </button>\n } @else {\n <div class=\"create-form\">\n <input\n type=\"text\"\n class=\"k-textbox create-input\"\n [(ngModel)]=\"newCollectionName\"\n placeholder=\"Enter collection name\"\n (keydown.enter)=\"createCollection()\"\n #newCollectionInput>\n <div class=\"create-actions\">\n <button class=\"btn-create\" kendoButton (click)=\"createCollection()\" [disabled]=\"isCreatingCollection || !newCollectionName.trim()\">\n @if (isCreatingCollection) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n } @else {\n Create\n }\n </button>\n <button class=\"btn-cancel\" kendoButton (click)=\"showCreateForm = false; newCollectionName = ''\">\n Cancel\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"onCancel()\">\n Cancel\n </button>\n <button kendoButton\n [primary]=\"true\"\n (click)=\"onSave()\"\n [disabled]=\"selectedCollections.length === 0 || isSaving\">\n @if (isSaving) {\n <i class=\"fas fa-spinner fa-spin\"></i> Saving...\n } @else {\n <i class=\"fas fa-save\"></i> Save to {{ selectedCollections.length }} Collection(s)\n }\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n }\n `,\n styles: [`\n .picker-modal {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 20px 0;\n min-height: 400px;\n max-height: 600px;\n }\n\n .breadcrumb-nav {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: #F9FAFB;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n overflow-x: auto;\n }\n\n .breadcrumb-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n background: transparent;\n border: none;\n border-radius: 4px;\n color: #0076B6;\n cursor: pointer;\n white-space: nowrap;\n font-size: 14px;\n }\n\n .breadcrumb-btn:hover {\n background: #E5E7EB;\n }\n\n .breadcrumb-separator {\n color: #9CA3AF;\n font-size: 12px;\n }\n\n .search-bar {\n position: relative;\n display: flex;\n align-items: center;\n }\n\n .search-icon {\n position: absolute;\n left: 12px;\n color: #9CA3AF;\n pointer-events: none;\n }\n\n .search-input {\n width: 100%;\n padding-left: 36px;\n }\n\n .collections-list {\n flex: 1;\n overflow-y: auto;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n min-height: 250px;\n max-height: 350px;\n }\n\n .collection-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border-bottom: 1px solid #F3F4F6;\n cursor: pointer;\n transition: background 0.2s;\n }\n\n .collection-item:hover {\n background: #F9FAFB;\n }\n\n .collection-item:last-child {\n border-bottom: none;\n }\n\n .collection-item.already-added {\n background: #F9FAFB;\n opacity: 0.7;\n cursor: not-allowed;\n }\n\n .collection-item.already-added:hover {\n background: #F9FAFB;\n }\n\n .collection-checkbox {\n display: flex;\n align-items: center;\n }\n\n .collection-checkbox input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n }\n\n .collection-icon {\n font-size: 18px;\n flex-shrink: 0;\n }\n\n .collection-name {\n flex: 1;\n font-size: 14px;\n color: #1F2937;\n }\n\n .already-added-badge {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n background: #DBEAFE;\n border: 1px solid #93C5FD;\n border-radius: 12px;\n color: #1E40AF;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n }\n\n .already-added-badge i {\n font-size: 12px;\n color: #2563EB;\n }\n\n .drill-down-btn {\n padding: 6px 10px;\n background: transparent;\n border: 1px solid #D1D5DB;\n border-radius: 4px;\n color: #6B7280;\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .drill-down-btn:hover {\n background: #F3F4F6;\n border-color: #9CA3AF;\n color: #374151;\n }\n\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n color: #6B7280;\n text-align: center;\n }\n\n .empty-state i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.4;\n }\n\n .empty-state p {\n margin: 4px 0;\n font-size: 14px;\n }\n\n .empty-state .hint {\n font-size: 13px;\n color: #9CA3AF;\n }\n\n .loading-state, .error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n gap: 12px;\n color: #6B7280;\n }\n\n .error-state i {\n font-size: 32px;\n }\n\n .error-state {\n color: #DC2626;\n }\n\n .selected-summary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: #DBEAFE;\n border: 1px solid #93C5FD;\n border-radius: 6px;\n color: #1E40AF;\n font-size: 14px;\n font-weight: 500;\n }\n\n .selected-summary i {\n color: #2563EB;\n }\n\n .create-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .divider {\n display: flex;\n align-items: center;\n text-align: center;\n color: #9CA3AF;\n font-size: 12px;\n font-weight: 500;\n }\n\n .divider::before,\n .divider::after {\n content: '';\n flex: 1;\n border-bottom: 1px solid #E5E7EB;\n }\n\n .divider span {\n padding: 0 12px;\n }\n\n .btn-create-collection {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n background: #F9FAFB;\n border: 2px dashed #D1D5DB;\n border-radius: 6px;\n color: #0076B6;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n }\n\n .btn-create-collection:hover {\n background: #F3F4F6;\n border-color: #0076B6;\n }\n\n .btn-create-collection i {\n font-size: 16px;\n }\n\n .create-form {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n background: #F9FAFB;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n }\n\n .create-input {\n width: 100%;\n }\n\n .create-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n }\n\n .btn-create, .btn-cancel {\n padding: 8px 16px;\n font-size: 14px;\n }\n `]\n})\nexport class ArtifactCollectionPickerModalComponent implements OnInit, OnChanges {\n @Input() isOpen: boolean = false;\n @Input() environmentId!: string;\n @Input() currentUser!: UserInfo;\n @Input() excludeCollectionIds: string[] = []; // Collections to exclude (e.g., already contains artifact)\n\n @Output() saved = new EventEmitter<string[]>(); // Emits selected collection IDs\n @Output() cancelled = new EventEmitter<void>();\n\n public allCollections: MJCollectionEntity[] = [];\n public displayedCollections: CollectionNode[] = [];\n public selectedCollections: MJCollectionEntity[] = [];\n public userPermissions: Map<string, CollectionPermission> = new Map();\n\n public navigationPath: CollectionNode[] = []; // Breadcrumb trail\n public currentParentId: string | null = null;\n public currentParentCollection: MJCollectionEntity | undefined = undefined;\n\n public searchQuery: string = '';\n public isLoading: boolean = false;\n public isSaving: boolean = false;\n public errorMessage: string = '';\n\n // Create collection form state\n public showCreateForm: boolean = false;\n public newCollectionName: string = '';\n public isCreatingCollection: boolean = false;\n\n constructor(\n private toastService: ToastService,\n private permissionService: CollectionPermissionService,\n private cdr: ChangeDetectorRef\n ) {}\n\n async ngOnInit() {\n if (this.isOpen) {\n await this.loadCollections();\n }\n }\n\n async ngOnChanges(changes: any) {\n if (changes['isOpen'] && this.isOpen) {\n this.reset();\n await this.loadCollections();\n }\n }\n\n private reset(): void {\n this.allCollections = [];\n this.displayedCollections = [];\n this.selectedCollections = [];\n this.userPermissions.clear();\n this.navigationPath = [];\n this.currentParentId = null;\n this.currentParentCollection = undefined;\n this.searchQuery = '';\n this.errorMessage = '';\n }\n\n private async loadCollections(): Promise<void> {\n try {\n this.isLoading = true;\n this.errorMessage = '';\n\n // Load all collections in environment\n const rv = new RunView();\n const result = await rv.RunView<MJCollectionEntity>({\n EntityName: 'MJ: Collections',\n ExtraFilter: `EnvironmentID='${this.environmentId}'`,\n OrderBy: 'Name ASC',\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (!result.Success) {\n this.errorMessage = result.ErrorMessage || 'Failed to load collections';\n return;\n }\n\n this.allCollections = result.Results || [];\n\n // Load user permissions for all collections\n await this.loadUserPermissions();\n\n // Filter to collections with Edit permission\n // Include collections that already contain the artifact (will be shown as disabled)\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n\n // Show root collections initially\n this.displayRootCollections(editableCollections);\n\n } catch (error) {\n console.error('Error loading collections:', error);\n this.errorMessage = 'An error occurred while loading collections';\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n private async loadUserPermissions(): Promise<void> {\n // Load permissions for collections not owned by current user\n const nonOwnedCollections = this.allCollections.filter(\n c => c.OwnerID && !UUIDsEqual(c.OwnerID, this.currentUser.ID)\n );\n\n if (nonOwnedCollections.length === 0) {\n return;\n }\n\n const collectionIds = nonOwnedCollections.map(c => c.ID);\n const permissions = await this.permissionService.checkBulkPermissions(\n collectionIds,\n this.currentUser.ID,\n this.currentUser\n );\n\n permissions.forEach((permission, collectionId) => {\n this.userPermissions.set(collectionId, permission);\n });\n }\n\n private displayRootCollections(editableCollections: MJCollectionEntity[]): void {\n const rootCollections = editableCollections.filter(c => !c.ParentID);\n this.displayedCollections = rootCollections.map(c => this.createNode(c, editableCollections));\n }\n\n private displayChildCollections(parentId: string, editableCollections: MJCollectionEntity[]): void {\n const childCollections = editableCollections.filter(c => UUIDsEqual(c.ParentID, parentId));\n this.displayedCollections = childCollections.map(c => this.createNode(c, editableCollections));\n }\n\n private createNode(collection: MJCollectionEntity, allEditableCollections: MJCollectionEntity[]): CollectionNode {\n const hasChildren = allEditableCollections.some(c => UUIDsEqual(c.ParentID, collection.ID));\n const alreadyContainsArtifact = this.excludeCollectionIds.some(id => UUIDsEqual(id, collection.ID));\n return {\n collection,\n selected: this.selectedCollections.some(sc => UUIDsEqual(sc.ID, collection.ID)),\n hasChildren,\n alreadyContainsArtifact\n };\n }\n\n canEdit(collection: MJCollectionEntity): boolean {\n // Backwards compatibility: treat null OwnerID as owned by current user\n if (!collection.OwnerID || UUIDsEqual(collection.OwnerID, this.currentUser.ID)) {\n return true;\n }\n\n // Check permission record\n const permission = this.userPermissions.get(collection.ID);\n return permission?.canEdit || false;\n }\n\n toggleSelection(node: CollectionNode): void {\n // Don't allow selection of collections that already contain the artifact\n if (node.alreadyContainsArtifact) {\n return;\n }\n\n const index = this.selectedCollections.findIndex(c => UUIDsEqual(c.ID, node.collection.ID));\n if (index >= 0) {\n this.selectedCollections.splice(index, 1);\n node.selected = false;\n } else {\n this.selectedCollections.push(node.collection);\n node.selected = true;\n }\n }\n\n drillIntoCollection(collection: MJCollectionEntity): void {\n // Add current location to navigation path\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n\n const node = this.createNode(collection, editableCollections);\n this.navigationPath.push(node);\n\n this.currentParentId = collection.ID;\n this.currentParentCollection = collection;\n\n // Display child collections\n this.displayChildCollections(collection.ID, editableCollections);\n\n // Clear search when drilling down\n this.searchQuery = '';\n }\n\n navigateToRoot(): void {\n this.navigationPath = [];\n this.currentParentId = null;\n this.currentParentCollection = undefined;\n\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n\n this.displayRootCollections(editableCollections);\n this.searchQuery = '';\n }\n\n navigateToCollection(collection: MJCollectionEntity): void {\n // Find the index of this collection in the navigation path\n const index = this.navigationPath.findIndex(n => UUIDsEqual(n.collection.ID, collection.ID));\n\n if (index >= 0) {\n // Trim navigation path to this level\n this.navigationPath = this.navigationPath.slice(0, index + 1);\n this.currentParentId = collection.ID;\n this.currentParentCollection = collection;\n\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n\n this.displayChildCollections(collection.ID, editableCollections);\n this.searchQuery = '';\n }\n }\n\n onSearchChange(): void {\n if (!this.searchQuery.trim()) {\n // Reset to current navigation context\n if (this.currentParentId) {\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n this.displayChildCollections(this.currentParentId, editableCollections);\n } else {\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c);\n });\n this.displayRootCollections(editableCollections);\n }\n return;\n }\n\n // Search across all editable collections\n const query = this.searchQuery.toLowerCase();\n const editableCollections = this.allCollections.filter(c => {\n return this.canEdit(c) && c.Name.toLowerCase().includes(query);\n });\n\n this.displayedCollections = editableCollections.map(c => this.createNode(c, editableCollections));\n }\n\n async createCollection(): Promise<void> {\n if (!this.newCollectionName.trim()) {\n this.toastService.warning('Please enter a collection name');\n return;\n }\n\n try {\n this.isCreatingCollection = true;\n const md = new Metadata();\n const collection = await md.GetEntityObject<MJCollectionEntity>('MJ: Collections', this.currentUser);\n\n collection.Name = this.newCollectionName.trim();\n collection.EnvironmentID = this.environmentId;\n\n // Set parent and owner based on current navigation context\n if (this.currentParentCollection) {\n // Creating sub-collection - inherit parent's owner\n collection.ParentID = this.currentParentCollection.ID;\n collection.OwnerID = this.currentParentCollection.OwnerID || this.currentUser.ID;\n } else {\n // Creating root collection - current user becomes owner\n collection.OwnerID = this.currentUser.ID;\n }\n\n const saved = await collection.Save();\n\n if (saved) {\n // Create owner permission or copy parent permissions\n if (this.currentParentCollection) {\n // Copy permissions from parent\n await this.permissionService.copyParentPermissions(\n this.currentParentCollection.ID,\n collection.ID,\n this.currentUser\n );\n } else {\n // Create owner permission\n await this.permissionService.createOwnerPermission(\n collection.ID,\n this.currentUser.ID,\n this.currentUser\n );\n }\n\n this.toastService.success('Collection created successfully');\n\n // Reset form\n this.showCreateForm = false;\n this.newCollectionName = '';\n\n // Reload collections to include the new one\n await this.loadCollections();\n\n // Auto-select the newly created collection\n this.selectedCollections.push(collection);\n } else {\n this.toastService.error(collection.LatestResult?.Message || 'Failed to create collection');\n }\n } catch (error) {\n console.error('Error creating collection:', error);\n this.toastService.error('An error occurred while creating the collection');\n } finally {\n this.isCreatingCollection = false;\n this.cdr.detectChanges();\n }\n }\n\n async onSave(): Promise<void> {\n if (this.selectedCollections.length === 0) {\n this.toastService.warning('Please select at least one collection');\n return;\n }\n\n this.isSaving = true;\n\n try {\n // Emit the selected collection IDs - parent handles actual saving and modal close\n const collectionIds = this.selectedCollections.map(c => c.ID);\n this.saved.emit(collectionIds);\n } finally {\n this.isSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n onCancel(): void {\n this.cancelled.emit();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-create-modal.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/collection/artifact-create-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,QAAQ,EAAqB,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAA+C,MAAM,+BAA+B,CAAC;AACpI,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;;
|
|
1
|
+
{"version":3,"file":"artifact-create-modal.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/collection/artifact-create-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAE,QAAQ,EAAqB,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAA+C,MAAM,+BAA+B,CAAC;AACpI,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;;AAG3F;;GAEG;AACH,qBAkJa,4BAA6B,YAAW,SAAS;IAsB1D,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,GAAG;IAvBJ,MAAM,EAAE,OAAO,CAAS;IACxB,YAAY,EAAG,MAAM,CAAC;IACtB,aAAa,EAAG,MAAM,CAAC;IACvB,WAAW,EAAG,QAAQ,CAAC;IAEtB,KAAK,iCAAwC;IAC7C,SAAS,qBAA4B;IAExC,QAAQ;;;;sBAIS,oBAAoB,GAAG,IAAI;MACjD;IAEK,aAAa,EAAE,oBAAoB,EAAE,CAAM;IAC3C,cAAc,EAAE,OAAO,CAAS;IAChC,QAAQ,EAAE,OAAO,CAAS;IAC1B,YAAY,EAAE,MAAM,CAAM;gBAGvB,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,2BAA2B,EAC9C,GAAG,EAAE,iBAAiB;IAGhC,WAAW,CAAC,OAAO,EAAE,aAAa;IAOlC,IAAI,OAAO,IAAI,OAAO,CAIrB;YAEa,iBAAiB;IAkCzB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAuF7B,QAAQ,IAAI,IAAI;IAKhB,OAAO,CAAC,SAAS;yCAtKN,4BAA4B;2CAA5B,4BAA4B;CA+KxC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
2
|
import { Metadata, RunView } from '@memberjunction/core';
|
|
3
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
import * as i1 from "../../services/toast.service";
|
|
5
6
|
import * as i2 from "../../services/collection-permission.service";
|
|
@@ -171,7 +172,7 @@ export class ArtifactCreateModalComponent {
|
|
|
171
172
|
const collection = await md.GetEntityObject('MJ: Collections', this.currentUser);
|
|
172
173
|
await collection.Load(this.collectionId);
|
|
173
174
|
// Check if user has Edit permission on collection
|
|
174
|
-
if (collection.OwnerID && collection.OwnerID
|
|
175
|
+
if (collection.OwnerID && !UUIDsEqual(collection.OwnerID, this.currentUser.ID)) {
|
|
175
176
|
const permission = await this.permissionService.checkPermission(this.collectionId, this.currentUser.ID, this.currentUser);
|
|
176
177
|
if (!permission?.canEdit) {
|
|
177
178
|
this.errorMessage = 'You do not have Edit permission to add artifacts to this collection.';
|
|
@@ -347,5 +348,5 @@ export class ArtifactCreateModalComponent {
|
|
|
347
348
|
}], cancelled: [{
|
|
348
349
|
type: Output
|
|
349
350
|
}] }); })();
|
|
350
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactCreateModalComponent, { className: "ArtifactCreateModalComponent", filePath: "src/lib/components/collection/artifact-create-modal.component.ts", lineNumber:
|
|
351
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactCreateModalComponent, { className: "ArtifactCreateModalComponent", filePath: "src/lib/components/collection/artifact-create-modal.component.ts", lineNumber: 157 }); })();
|
|
351
352
|
//# sourceMappingURL=artifact-create-modal.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-create-modal.component.js","sourceRoot":"","sources":["../../../../src/lib/components/collection/artifact-create-modal.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core';\nimport { UserInfo, Metadata, RunView } from '@memberjunction/core';\nimport { MJArtifactEntity, MJArtifactTypeEntity, MJArtifactVersionEntity, MJCollectionEntity } from '@memberjunction/core-entities';\nimport { ToastService } from '../../services/toast.service';\nimport { CollectionPermissionService } from '../../services/collection-permission.service';\n\n/**\n * Modal for creating new artifacts and adding them to collections\n */\n@Component({\n standalone: false,\n selector: 'mj-artifact-create-modal',\n template: `\n @if (isOpen) {\n <kendo-dialog\n title=\"Create Artifact\"\n (close)=\"onCancel()\"\n [width]=\"600\"\n [minWidth]=\"400\">\n <div class=\"artifact-form\">\n <div class=\"form-group\">\n <label class=\"form-label\">\n Name <span class=\"required\">*</span>\n </label>\n <input\n type=\"text\"\n class=\"k-textbox form-control\"\n [(ngModel)]=\"formData.name\"\n placeholder=\"Artifact name\"\n #nameInput>\n </div>\n <div class=\"form-group\">\n <label class=\"form-label\">\n Type <span class=\"required\">*</span>\n </label>\n <kendo-dropdownlist\n [data]=\"artifactTypes\"\n [(ngModel)]=\"formData.selectedType\"\n textField=\"Name\"\n valueField=\"ID\"\n [valuePrimitive]=\"false\"\n class=\"form-control\"\n [loading]=\"isLoadingTypes\">\n </kendo-dropdownlist>\n </div>\n <div class=\"form-group\">\n <label class=\"form-label\">Description</label>\n <textarea\n class=\"k-textarea form-control\"\n [(ngModel)]=\"formData.description\"\n placeholder=\"Optional description\"\n rows=\"2\">\n </textarea>\n </div>\n <div class=\"form-group\">\n <label class=\"form-label\">\n Content <span class=\"required\">*</span>\n </label>\n <textarea\n class=\"k-textarea form-control content-area\"\n [(ngModel)]=\"formData.content\"\n placeholder=\"Paste your content here...\"\n rows=\"12\">\n </textarea>\n <div class=\"content-hint\">\n <i class=\"fas fa-info-circle\"></i>\n Paste or type the artifact content. The content will be saved as version 1.\n </div>\n </div>\n @if (errorMessage) {\n <div class=\"form-error\">\n <i class=\"fas fa-exclamation-circle\"></i>\n {{ errorMessage }}\n </div>\n }\n </div>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"onCancel()\" [disabled]=\"isSaving\">\n Cancel\n </button>\n <button kendoButton\n [primary]=\"true\"\n (click)=\"onSave()\"\n [disabled]=\"!canSave || isSaving\">\n {{ isSaving ? 'Creating...' : 'Create Artifact' }}\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n }\n `,\n styles: [`\n .artifact-form {\n padding: 20px 0;\n }\n\n .form-group {\n margin-bottom: 20px;\n }\n\n .form-label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n }\n\n .required {\n color: #DC2626;\n }\n\n .form-control {\n width: 100%;\n }\n\n .content-area {\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;\n font-size: 13px;\n line-height: 1.5;\n }\n\n .content-hint {\n display: flex;\n align-items: start;\n gap: 8px;\n margin-top: 8px;\n padding: 8px 12px;\n background: #EFF6FF;\n border: 1px solid #BFDBFE;\n border-radius: 6px;\n font-size: 13px;\n color: #1e40af;\n }\n\n .content-hint i {\n flex-shrink: 0;\n margin-top: 2px;\n }\n\n .form-error {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n background: #FEE2E2;\n border: 1px solid #FCA5A5;\n border-radius: 6px;\n color: #DC2626;\n font-size: 14px;\n }\n\n .form-error i {\n flex-shrink: 0;\n }\n `]\n})\nexport class ArtifactCreateModalComponent implements OnChanges {\n @Input() isOpen: boolean = false;\n @Input() collectionId!: string;\n @Input() environmentId!: string;\n @Input() currentUser!: UserInfo;\n\n @Output() saved = new EventEmitter<MJArtifactEntity>();\n @Output() cancelled = new EventEmitter<void>();\n\n public formData = {\n name: '',\n description: '',\n content: '',\n selectedType: null as MJArtifactTypeEntity | null\n };\n\n public artifactTypes: MJArtifactTypeEntity[] = [];\n public isLoadingTypes: boolean = false;\n public isSaving: boolean = false;\n public errorMessage: string = '';\n\n constructor(\n private toastService: ToastService,\n private permissionService: CollectionPermissionService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes['isOpen'] && this.isOpen) {\n this.resetForm();\n this.loadArtifactTypes();\n }\n }\n\n get canSave(): boolean {\n return this.formData.name.trim().length > 0 &&\n this.formData.content.trim().length > 0 &&\n this.formData.selectedType !== null;\n }\n\n private async loadArtifactTypes(): Promise<void> {\n this.isLoadingTypes = true;\n try {\n const rv = new RunView();\n const result = await rv.RunView<MJArtifactTypeEntity>(\n {\n EntityName: 'MJ: Artifact Types',\n ExtraFilter: 'IsEnabled=1',\n OrderBy: 'Name ASC',\n MaxRows: 1000,\n ResultType: 'entity_object'\n },\n this.currentUser\n );\n\n if (result.Success && result.Results) {\n this.artifactTypes = result.Results;\n // Default to \"Text\" or first type\n const textType = this.artifactTypes.find(t => t.Name === 'Text' || t.Name === 'Markdown');\n if (textType) {\n this.formData.selectedType = textType;\n } else if (this.artifactTypes.length > 0) {\n this.formData.selectedType = this.artifactTypes[0];\n }\n }\n } catch (error) {\n console.error('Error loading artifact types:', error);\n this.toastService.error('Failed to load artifact types');\n } finally {\n this.isLoadingTypes = false;\n this.cdr.detectChanges(); // zone.js 0.15: async RunView doesn't trigger CD\n }\n }\n\n async onSave(): Promise<void> {\n if (!this.canSave) return;\n\n this.isSaving = true;\n this.errorMessage = '';\n\n try {\n // Validate permission to add artifacts to collection\n const md = new Metadata();\n const collection = await md.GetEntityObject<MJCollectionEntity>('MJ: Collections', this.currentUser);\n await collection.Load(this.collectionId);\n\n // Check if user has Edit permission on collection\n if (collection.OwnerID && collection.OwnerID !== this.currentUser.ID) {\n const permission = await this.permissionService.checkPermission(\n this.collectionId,\n this.currentUser.ID,\n this.currentUser\n );\n\n if (!permission?.canEdit) {\n this.errorMessage = 'You do not have Edit permission to add artifacts to this collection.';\n this.isSaving = false;\n return;\n }\n }\n\n // Step 1: Create the artifact\n const artifact = await md.GetEntityObject<MJArtifactEntity>('MJ: Artifacts', this.currentUser);\n artifact.Name = this.formData.name.trim();\n artifact.Description = this.formData.description.trim() || null;\n artifact.TypeID = this.formData.selectedType!.ID;\n artifact.EnvironmentID = this.environmentId;\n artifact.UserID = this.currentUser.ID;\n\n const artifactSaved = await artifact.Save();\n if (!artifactSaved) {\n this.errorMessage = artifact.LatestResult?.Message || 'Failed to create artifact';\n this.toastService.error(this.errorMessage);\n return;\n }\n\n // Step 2: Create the first version\n const version = await md.GetEntityObject<MJArtifactVersionEntity>('MJ: Artifact Versions', this.currentUser);\n version.ArtifactID = artifact.ID;\n version.VersionNumber = 1;\n version.Content = this.formData.content.trim();\n version.UserID = this.currentUser.ID;\n version.Name = this.formData.name.trim(); // Version inherits name\n version.Description = this.formData.description.trim() || null;\n\n const versionSaved = await version.Save();\n if (!versionSaved) {\n // Rollback: delete the artifact if version creation fails\n await artifact.Delete();\n this.errorMessage = version.LatestResult?.Message || 'Failed to create artifact version';\n this.toastService.error(this.errorMessage);\n return;\n }\n\n // Step 3: Add to collection\n const collectionArtifact = await md.GetEntityObject('MJ: Collection Artifacts', this.currentUser);\n (collectionArtifact as any).CollectionID = this.collectionId;\n (collectionArtifact as any).ArtifactVersionID = version.ID;\n\n const collectionLinkSaved = await collectionArtifact.Save();\n if (!collectionLinkSaved) {\n // Rollback: delete version and artifact if collection link fails\n await version.Delete();\n await artifact.Delete();\n this.errorMessage = 'Failed to add artifact to collection';\n this.toastService.error(this.errorMessage);\n return;\n }\n\n this.toastService.success('Artifact created successfully');\n this.saved.emit(artifact);\n this.resetForm();\n } catch (error) {\n console.error('Error creating artifact:', error);\n this.errorMessage = 'An unexpected error occurred';\n this.toastService.error(this.errorMessage);\n } finally {\n this.isSaving = false;\n }\n }\n\n onCancel(): void {\n this.resetForm();\n this.cancelled.emit();\n }\n\n private resetForm(): void {\n this.formData = {\n name: '',\n description: '',\n content: '',\n selectedType: this.artifactTypes.length > 0 ? this.artifactTypes[0] : null\n };\n this.errorMessage = '';\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"artifact-create-modal.component.js","sourceRoot":"","sources":["../../../../src/lib/components/collection/artifact-create-modal.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core';\nimport { UserInfo, Metadata, RunView } from '@memberjunction/core';\nimport { MJArtifactEntity, MJArtifactTypeEntity, MJArtifactVersionEntity, MJCollectionEntity } from '@memberjunction/core-entities';\nimport { ToastService } from '../../services/toast.service';\nimport { CollectionPermissionService } from '../../services/collection-permission.service';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * Modal for creating new artifacts and adding them to collections\n */\n@Component({\n standalone: false,\n selector: 'mj-artifact-create-modal',\n template: `\n @if (isOpen) {\n <kendo-dialog\n title=\"Create Artifact\"\n (close)=\"onCancel()\"\n [width]=\"600\"\n [minWidth]=\"400\">\n <div class=\"artifact-form\">\n <div class=\"form-group\">\n <label class=\"form-label\">\n Name <span class=\"required\">*</span>\n </label>\n <input\n type=\"text\"\n class=\"k-textbox form-control\"\n [(ngModel)]=\"formData.name\"\n placeholder=\"Artifact name\"\n #nameInput>\n </div>\n <div class=\"form-group\">\n <label class=\"form-label\">\n Type <span class=\"required\">*</span>\n </label>\n <kendo-dropdownlist\n [data]=\"artifactTypes\"\n [(ngModel)]=\"formData.selectedType\"\n textField=\"Name\"\n valueField=\"ID\"\n [valuePrimitive]=\"false\"\n class=\"form-control\"\n [loading]=\"isLoadingTypes\">\n </kendo-dropdownlist>\n </div>\n <div class=\"form-group\">\n <label class=\"form-label\">Description</label>\n <textarea\n class=\"k-textarea form-control\"\n [(ngModel)]=\"formData.description\"\n placeholder=\"Optional description\"\n rows=\"2\">\n </textarea>\n </div>\n <div class=\"form-group\">\n <label class=\"form-label\">\n Content <span class=\"required\">*</span>\n </label>\n <textarea\n class=\"k-textarea form-control content-area\"\n [(ngModel)]=\"formData.content\"\n placeholder=\"Paste your content here...\"\n rows=\"12\">\n </textarea>\n <div class=\"content-hint\">\n <i class=\"fas fa-info-circle\"></i>\n Paste or type the artifact content. The content will be saved as version 1.\n </div>\n </div>\n @if (errorMessage) {\n <div class=\"form-error\">\n <i class=\"fas fa-exclamation-circle\"></i>\n {{ errorMessage }}\n </div>\n }\n </div>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"onCancel()\" [disabled]=\"isSaving\">\n Cancel\n </button>\n <button kendoButton\n [primary]=\"true\"\n (click)=\"onSave()\"\n [disabled]=\"!canSave || isSaving\">\n {{ isSaving ? 'Creating...' : 'Create Artifact' }}\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n }\n `,\n styles: [`\n .artifact-form {\n padding: 20px 0;\n }\n\n .form-group {\n margin-bottom: 20px;\n }\n\n .form-label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n }\n\n .required {\n color: #DC2626;\n }\n\n .form-control {\n width: 100%;\n }\n\n .content-area {\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;\n font-size: 13px;\n line-height: 1.5;\n }\n\n .content-hint {\n display: flex;\n align-items: start;\n gap: 8px;\n margin-top: 8px;\n padding: 8px 12px;\n background: #EFF6FF;\n border: 1px solid #BFDBFE;\n border-radius: 6px;\n font-size: 13px;\n color: #1e40af;\n }\n\n .content-hint i {\n flex-shrink: 0;\n margin-top: 2px;\n }\n\n .form-error {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n background: #FEE2E2;\n border: 1px solid #FCA5A5;\n border-radius: 6px;\n color: #DC2626;\n font-size: 14px;\n }\n\n .form-error i {\n flex-shrink: 0;\n }\n `]\n})\nexport class ArtifactCreateModalComponent implements OnChanges {\n @Input() isOpen: boolean = false;\n @Input() collectionId!: string;\n @Input() environmentId!: string;\n @Input() currentUser!: UserInfo;\n\n @Output() saved = new EventEmitter<MJArtifactEntity>();\n @Output() cancelled = new EventEmitter<void>();\n\n public formData = {\n name: '',\n description: '',\n content: '',\n selectedType: null as MJArtifactTypeEntity | null\n };\n\n public artifactTypes: MJArtifactTypeEntity[] = [];\n public isLoadingTypes: boolean = false;\n public isSaving: boolean = false;\n public errorMessage: string = '';\n\n constructor(\n private toastService: ToastService,\n private permissionService: CollectionPermissionService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes['isOpen'] && this.isOpen) {\n this.resetForm();\n this.loadArtifactTypes();\n }\n }\n\n get canSave(): boolean {\n return this.formData.name.trim().length > 0 &&\n this.formData.content.trim().length > 0 &&\n this.formData.selectedType !== null;\n }\n\n private async loadArtifactTypes(): Promise<void> {\n this.isLoadingTypes = true;\n try {\n const rv = new RunView();\n const result = await rv.RunView<MJArtifactTypeEntity>(\n {\n EntityName: 'MJ: Artifact Types',\n ExtraFilter: 'IsEnabled=1',\n OrderBy: 'Name ASC',\n MaxRows: 1000,\n ResultType: 'entity_object'\n },\n this.currentUser\n );\n\n if (result.Success && result.Results) {\n this.artifactTypes = result.Results;\n // Default to \"Text\" or first type\n const textType = this.artifactTypes.find(t => t.Name === 'Text' || t.Name === 'Markdown');\n if (textType) {\n this.formData.selectedType = textType;\n } else if (this.artifactTypes.length > 0) {\n this.formData.selectedType = this.artifactTypes[0];\n }\n }\n } catch (error) {\n console.error('Error loading artifact types:', error);\n this.toastService.error('Failed to load artifact types');\n } finally {\n this.isLoadingTypes = false;\n this.cdr.detectChanges(); // zone.js 0.15: async RunView doesn't trigger CD\n }\n }\n\n async onSave(): Promise<void> {\n if (!this.canSave) return;\n\n this.isSaving = true;\n this.errorMessage = '';\n\n try {\n // Validate permission to add artifacts to collection\n const md = new Metadata();\n const collection = await md.GetEntityObject<MJCollectionEntity>('MJ: Collections', this.currentUser);\n await collection.Load(this.collectionId);\n\n // Check if user has Edit permission on collection\n if (collection.OwnerID && !UUIDsEqual(collection.OwnerID, this.currentUser.ID)) {\n const permission = await this.permissionService.checkPermission(\n this.collectionId,\n this.currentUser.ID,\n this.currentUser\n );\n\n if (!permission?.canEdit) {\n this.errorMessage = 'You do not have Edit permission to add artifacts to this collection.';\n this.isSaving = false;\n return;\n }\n }\n\n // Step 1: Create the artifact\n const artifact = await md.GetEntityObject<MJArtifactEntity>('MJ: Artifacts', this.currentUser);\n artifact.Name = this.formData.name.trim();\n artifact.Description = this.formData.description.trim() || null;\n artifact.TypeID = this.formData.selectedType!.ID;\n artifact.EnvironmentID = this.environmentId;\n artifact.UserID = this.currentUser.ID;\n\n const artifactSaved = await artifact.Save();\n if (!artifactSaved) {\n this.errorMessage = artifact.LatestResult?.Message || 'Failed to create artifact';\n this.toastService.error(this.errorMessage);\n return;\n }\n\n // Step 2: Create the first version\n const version = await md.GetEntityObject<MJArtifactVersionEntity>('MJ: Artifact Versions', this.currentUser);\n version.ArtifactID = artifact.ID;\n version.VersionNumber = 1;\n version.Content = this.formData.content.trim();\n version.UserID = this.currentUser.ID;\n version.Name = this.formData.name.trim(); // Version inherits name\n version.Description = this.formData.description.trim() || null;\n\n const versionSaved = await version.Save();\n if (!versionSaved) {\n // Rollback: delete the artifact if version creation fails\n await artifact.Delete();\n this.errorMessage = version.LatestResult?.Message || 'Failed to create artifact version';\n this.toastService.error(this.errorMessage);\n return;\n }\n\n // Step 3: Add to collection\n const collectionArtifact = await md.GetEntityObject('MJ: Collection Artifacts', this.currentUser);\n (collectionArtifact as any).CollectionID = this.collectionId;\n (collectionArtifact as any).ArtifactVersionID = version.ID;\n\n const collectionLinkSaved = await collectionArtifact.Save();\n if (!collectionLinkSaved) {\n // Rollback: delete version and artifact if collection link fails\n await version.Delete();\n await artifact.Delete();\n this.errorMessage = 'Failed to add artifact to collection';\n this.toastService.error(this.errorMessage);\n return;\n }\n\n this.toastService.success('Artifact created successfully');\n this.saved.emit(artifact);\n this.resetForm();\n } catch (error) {\n console.error('Error creating artifact:', error);\n this.errorMessage = 'An unexpected error occurred';\n this.toastService.error(this.errorMessage);\n } finally {\n this.isSaving = false;\n }\n }\n\n onCancel(): void {\n this.resetForm();\n this.cancelled.emit();\n }\n\n private resetForm(): void {\n this.formData = {\n name: '',\n description: '',\n content: '',\n selectedType: this.artifactTypes.length > 0 ? this.artifactTypes[0] : null\n };\n this.errorMessage = '';\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-form-modal.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/collection/collection-form-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;;
|
|
1
|
+
{"version":3,"file":"collection-form-modal.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/collection/collection-form-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;;AAG3F;;GAEG;AACH,qBAsHa,4BAA6B,YAAW,SAAS;IAmB1D,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,iBAAiB;IAnBlB,MAAM,EAAE,OAAO,CAAS;IACxB,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,aAAa,EAAG,MAAM,CAAC;IACvB,WAAW,EAAG,QAAQ,CAAC;IAEtB,KAAK,mCAA0C;IAC/C,SAAS,qBAA4B;IAExC,QAAQ;;;MAGb;IAEK,QAAQ,EAAE,OAAO,CAAS;IAC1B,YAAY,EAAE,MAAM,CAAM;gBAGvB,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,2BAA2B;IAGxD,WAAW,CAAC,OAAO,EAAE,aAAa;IAWlC,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAsG7B,QAAQ,IAAI,IAAI;IAKhB,OAAO,CAAC,SAAS;yCAjJN,4BAA4B;2CAA5B,4BAA4B;CAwJxC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
2
|
import { Metadata } from '@memberjunction/core';
|
|
3
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
import * as i1 from "../../services/toast.service";
|
|
5
6
|
import * as i2 from "../../services/collection-permission.service";
|
|
@@ -125,7 +126,7 @@ export class CollectionFormModalComponent {
|
|
|
125
126
|
// Validate permissions before saving
|
|
126
127
|
if (this.collection) {
|
|
127
128
|
// Editing existing collection - need Edit permission
|
|
128
|
-
if (this.collection.OwnerID && this.collection.OwnerID
|
|
129
|
+
if (this.collection.OwnerID && !UUIDsEqual(this.collection.OwnerID, this.currentUser.ID)) {
|
|
129
130
|
const permission = await this.permissionService.checkPermission(this.collection.ID, this.currentUser.ID, this.currentUser);
|
|
130
131
|
if (!permission?.canEdit) {
|
|
131
132
|
this.errorMessage = 'You do not have Edit permission for this collection.';
|
|
@@ -136,7 +137,7 @@ export class CollectionFormModalComponent {
|
|
|
136
137
|
}
|
|
137
138
|
else if (this.parentCollection) {
|
|
138
139
|
// Creating child collection - need Edit permission on parent
|
|
139
|
-
if (this.parentCollection.OwnerID && this.parentCollection.OwnerID
|
|
140
|
+
if (this.parentCollection.OwnerID && !UUIDsEqual(this.parentCollection.OwnerID, this.currentUser.ID)) {
|
|
140
141
|
const permission = await this.permissionService.checkPermission(this.parentCollection.ID, this.currentUser.ID, this.currentUser);
|
|
141
142
|
if (!permission?.canEdit) {
|
|
142
143
|
this.errorMessage = 'You do not have Edit permission for the parent collection.';
|
|
@@ -292,5 +293,5 @@ export class CollectionFormModalComponent {
|
|
|
292
293
|
}], cancelled: [{
|
|
293
294
|
type: Output
|
|
294
295
|
}] }); })();
|
|
295
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CollectionFormModalComponent, { className: "CollectionFormModalComponent", filePath: "src/lib/components/collection/collection-form-modal.component.ts", lineNumber:
|
|
296
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CollectionFormModalComponent, { className: "CollectionFormModalComponent", filePath: "src/lib/components/collection/collection-form-modal.component.ts", lineNumber: 130 }); })();
|
|
296
297
|
//# sourceMappingURL=collection-form-modal.component.js.map
|