@memberjunction/ng-tasks 6.2.0-edge.0 → 6.2.0-edge.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"gantt-task-viewer.component.js","sourceRoot":"","sources":["../../../src/lib/components/gantt-task-viewer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, AfterViewInit, ElementRef, ViewChild, OnDestroy, HostListener } from '@angular/core';\n\nimport { MJTaskEntity, MJTaskDependencyEntity } from '@memberjunction/core-entities';\nimport type { GanttStatic, Task as GanttTask, Link as GanttLink } from 'dhtmlx-gantt';\nimport { TaskDetailPanelComponent } from './task-detail-panel.component';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * Gantt chart view for tasks using DHTMLX Gantt\n */\n@Component({\n selector: 'mj-gantt-task-viewer',\n standalone: true,\n imports: [TaskDetailPanelComponent, SharedGenericModule],\n template: `\n <div class=\"gantt-task-viewer\">\n @if (IsGanttLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading Gantt chart...\"></mj-loading>\n </div>\n }\n\n @if (!IsGanttLoading) {\n @if (!tasks || tasks.length === 0) {\n <div class=\"no-tasks\">\n <i class=\"fas fa-chart-gantt\"></i>\n <p>No tasks to display in Gantt view</p>\n </div>\n }\n\n @if (tasks && tasks.length > 0) {\n <div class=\"gantt-layout\">\n <div #ganttContainer class=\"gantt-container\"></div>\n @if (selectedTask) {\n <div class=\"gantt-resizer\"\n (mousedown)=\"startResize($event)\"></div>\n }\n @if (selectedTask) {\n <div class=\"task-detail-panel\" [style.width.px]=\"detailPanelWidth\">\n <mj-task-detail-panel\n [task]=\"selectedTask\"\n [agentRunId]=\"getAgentRunId(selectedTask)\"\n (closePanel)=\"closeDetailPanel()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-task-detail-panel>\n </div>\n }\n </div>\n }\n }\n </div>\n `,\n styles: [`\n .gantt-task-viewer {\n height: 100%;\n background: var(--mj-bg-surface);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .gantt-layout {\n display: flex;\n height: 600px;\n position: relative;\n }\n\n .gantt-container {\n flex: 1;\n min-width: 400px;\n height: 100%;\n position: relative;\n }\n\n .gantt-resizer {\n width: 4px;\n background: var(--mj-border-default);\n cursor: col-resize;\n flex-shrink: 0;\n transition: background 0.2s;\n }\n\n .gantt-resizer:hover {\n background: var(--mj-brand-primary);\n }\n\n .task-detail-panel {\n min-width: 300px;\n max-width: 600px;\n height: 100%;\n border-left: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n /* Override DHTMLX Gantt default styles */\n :host ::ng-deep .gantt_container {\n font-family: inherit;\n font-size: 13px;\n }\n\n :host ::ng-deep .gantt_grid_scale,\n :host ::ng-deep .gantt_task_scale {\n background: var(--mj-bg-surface-sunken);\n border-bottom: 2px solid var(--mj-border-default);\n }\n\n :host ::ng-deep .gantt_task .gantt_task_content {\n font-weight: 500;\n }\n\n .loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 80px 20px;\n }\n\n .no-tasks {\n text-align: center;\n padding: 80px 20px;\n color: var(--mj-text-disabled);\n }\n\n .no-tasks i {\n font-size: 64px;\n opacity: 0.3;\n margin-bottom: 16px;\n }\n\n .no-tasks p {\n margin: 0;\n font-size: 14px;\n }\n `]\n})\nexport class GanttTaskViewerComponent implements OnChanges, AfterViewInit, OnDestroy {\n @Input() tasks: MJTaskEntity[] = [];\n @Input() taskDependencies: MJTaskDependencyEntity[] = [];\n @Input() agentRunMap?: Map<string, string>; // Maps TaskID -> AgentRunID\n @Output() taskClicked = new EventEmitter<MJTaskEntity>();\n @Output() openEntityRecord = new EventEmitter<{ entityName: string; recordId: string }>();\n\n @ViewChild('ganttContainer', { static: false }) ganttContainer!: ElementRef<HTMLDivElement>;\n\n public selectedTask: MJTaskEntity | null = null;\n public detailPanelWidth: number = 400;\n public IsGanttLoading = true;\n\n private ganttLib: GanttStatic | null = null;\n private ganttInitialized = false;\n private isResizing = false;\n private resizeStartX = 0;\n private resizeStartWidth = 0;\n\n async ngAfterViewInit() {\n console.log('🔧 ngAfterViewInit called', {\n taskCount: this.tasks?.length || 0,\n hasContainer: !!this.ganttContainer\n });\n\n try {\n const module = await import('dhtmlx-gantt');\n this.ganttLib = module.gantt;\n this.IsGanttLoading = false;\n\n if (this.tasks && this.tasks.length > 0 && this.ganttContainer) {\n this.initGantt();\n }\n } catch (error) {\n console.error('Failed to load dhtmlx-gantt:', error);\n this.IsGanttLoading = false;\n }\n }\n\n ngOnChanges() {\n console.log('🔄 ngOnChanges called', {\n initialized: this.ganttInitialized,\n hasContainer: !!this.ganttContainer,\n taskCount: this.tasks?.length || 0\n });\n\n if (!this.ganttLib) return; // Library not yet loaded\n\n if (this.ganttInitialized && this.ganttContainer) {\n this.updateGanttData();\n } else if (!this.ganttInitialized && this.ganttContainer && this.tasks && this.tasks.length > 0) {\n // Initialize if we have container and tasks but haven't initialized yet\n console.log('🎨 Late initialization - gantt not initialized but container and tasks available');\n this.initGantt();\n }\n }\n\n ngOnDestroy() {\n if (this.ganttInitialized && this.ganttLib) {\n this.ganttLib.clearAll();\n this.ganttInitialized = false;\n }\n }\n\n private initGantt(): void {\n try {\n console.log('🎨 Initializing DHTMLX Gantt');\n const g = this.ganttLib!;\n\n // IMPORTANT: Clear any previous configuration\n g.clearAll();\n\n // Configure Gantt layout and appearance\n g.config.date_format = '%Y-%m-%d %H:%i';\n g.config.scale_unit = 'day';\n g.config.date_scale = '%d %M';\n g.config.subscales = [];\n g.config.show_progress = true;\n g.config.show_links = true;\n g.config.auto_types = true;\n g.config.readonly = true; // Read-only for now\n g.config.fit_tasks = true; // Auto-fit timeline to tasks\n\n // Disable auto-scheduling - we calculate dates ourselves based on dependencies\n g.config.auto_scheduling = false;\n\n // Grid configuration\n g.config.grid_width = 350;\n g.config.row_height = 36;\n g.config.scale_height = 0; // Hide date scale - dates are just for positioning\n\n // Layout configuration - ensure timeline is visible\n g.config.layout = {\n css: \"gantt_container\",\n rows: [\n {\n cols: [\n { view: \"grid\", group: \"grids\", scrollY: \"scrollVer\" },\n { resizer: true, width: 1 },\n { view: \"timeline\", scrollX: \"scrollHor\", scrollY: \"scrollVer\" },\n { view: \"scrollbar\", id: \"scrollVer\", group: \"vertical\" }\n ]\n },\n { view: \"scrollbar\", id: \"scrollHor\", group: \"horizontal\" }\n ]\n };\n\n // Column configuration - only show task names, hide dates\n g.config.columns = [\n { name: 'text', label: 'Task name', tree: true, width: '*' }\n ];\n\n // Initialize Gantt in the container\n g.init(this.ganttContainer.nativeElement);\n this.ganttInitialized = true;\n\n // Attach click event\n g.attachEvent('onTaskClick', (id: string) => {\n const originalTask = this.tasks.find(t => UUIDsEqual(t.ID, id));\n if (originalTask) {\n this.selectedTask = originalTask;\n this.taskClicked.emit(originalTask);\n }\n return true;\n });\n\n // Load data\n this.updateGanttData();\n\n // Force resize after data load to ensure proper rendering\n setTimeout(() => {\n g.setSizes();\n }, 0);\n\n // Expand and select after render completes\n setTimeout(() => {\n this.expandAllAndSelectRoot();\n }, 100);\n\n console.log('✅ DHTMLX Gantt initialized successfully');\n } catch (error) {\n console.error('❌ Error initializing Gantt:', error);\n }\n }\n\n private updateGanttData(): void {\n if (!this.ganttInitialized) return;\n\n try {\n console.log('📊 Updating Gantt data with', this.tasks.length, 'tasks');\n const g = this.ganttLib!;\n\n const ganttData = this.convertToGanttFormat(this.tasks);\n g.clearAll();\n g.parse(ganttData);\n\n // Log final parsed data for debugging\n console.log('📋 Gantt data after parse:', {\n tasks: g.getTaskByTime(),\n links: g.getLinks()\n });\n\n // Force resize after data update\n setTimeout(() => {\n g.setSizes();\n }, 0);\n\n // Expand and select after render completes\n setTimeout(() => {\n this.expandAllAndSelectRoot();\n }, 100);\n\n console.log('✅ Gantt data updated');\n } catch (error) {\n console.error('❌ Error updating Gantt data:', error);\n }\n }\n\n private convertToGanttFormat(tasks: MJTaskEntity[]): { data: GanttTask[], links: GanttLink[] } {\n const data: GanttTask[] = [];\n const links: GanttLink[] = [];\n\n console.log('🔍 Converting tasks:', tasks);\n console.log('🔗 Task dependencies:', this.taskDependencies);\n\n // Build a map of task ID to task for quick lookup\n const taskMap = new Map<string, MJTaskEntity>();\n tasks.forEach(t => taskMap.set(t.ID, t));\n\n // Build dependency map: taskId -> array of tasks it depends on\n const dependencyMap = new Map<string, string[]>();\n this.taskDependencies.forEach(dep => {\n if (!dependencyMap.has(dep.TaskID)) {\n dependencyMap.set(dep.TaskID, []);\n }\n dependencyMap.get(dep.TaskID)!.push(dep.DependsOnTaskID);\n });\n\n // Calculate start dates based on dependencies\n const taskStartDates = new Map<string, Date>();\n const baseDate = new Date();\n baseDate.setHours(0, 0, 0, 0);\n\n // Recursive function to calculate start date for a task\n const calculateStartDate = (taskId: string, visited = new Set<string>()): Date => {\n // Prevent circular dependencies\n if (visited.has(taskId)) {\n return new Date(baseDate);\n }\n visited.add(taskId);\n\n // If already calculated, return it\n if (taskStartDates.has(taskId)) {\n return taskStartDates.get(taskId)!;\n }\n\n const task = taskMap.get(taskId);\n if (!task) return new Date(baseDate);\n\n const dependencies = dependencyMap.get(taskId) || [];\n\n if (dependencies.length === 0) {\n // No dependencies - use base date or task's actual start date\n const startDate = task.StartedAt ? new Date(task.StartedAt) : new Date(baseDate);\n taskStartDates.set(taskId, startDate);\n return startDate;\n }\n\n // Has dependencies - start after the latest dependency ends\n let latestEnd = new Date(baseDate);\n for (const depId of dependencies) {\n const depTask = taskMap.get(depId);\n if (depTask) {\n const depStart = calculateStartDate(depId, new Set(visited));\n const depDuration = this.calculateDuration(depTask);\n const depEnd = new Date(depStart);\n depEnd.setDate(depEnd.getDate() + depDuration);\n\n if (depEnd > latestEnd) {\n latestEnd = depEnd;\n }\n }\n }\n\n taskStartDates.set(taskId, latestEnd);\n return latestEnd;\n };\n\n // Calculate start dates for all tasks\n tasks.forEach(task => calculateStartDate(task.ID));\n\n // Calculate min/max dates for timeline display range\n let minDate: Date | null = null;\n let maxDate: Date | null = null;\n\n tasks.forEach(task => {\n const startDate = taskStartDates.get(task.ID);\n if (startDate) {\n const duration = this.calculateDuration(task);\n const endDate = new Date(startDate);\n endDate.setDate(endDate.getDate() + duration);\n\n if (!minDate || startDate < minDate) {\n minDate = startDate;\n }\n if (!maxDate || endDate > maxDate) {\n maxDate = endDate;\n }\n }\n });\n\n // Add 1 day padding before and after\n const g = this.ganttLib!;\n if (minDate) {\n const paddedStart = new Date(minDate);\n paddedStart.setDate(paddedStart.getDate() - 1);\n g.config.start_date = paddedStart;\n }\n if (maxDate) {\n const paddedEnd = new Date(maxDate);\n paddedEnd.setDate(paddedEnd.getDate() + 1);\n g.config.end_date = paddedEnd;\n }\n\n // Now create Gantt tasks with calculated dates\n tasks.forEach((task) => {\n console.log('📝 Processing task:', {\n ID: task.ID,\n Name: task.Name,\n ParentID: task.ParentID\n });\n\n // Calculate progress (0-1 scale for DHTMLX)\n let progress = (task.PercentComplete || 0) / 100;\n if (task.Status === 'Complete') {\n progress = 1;\n }\n\n const duration = this.calculateDuration(task);\n const startDate = taskStartDates.get(task.ID) || new Date(baseDate);\n\n const ganttTask: Partial<GanttTask> & Pick<GanttTask, 'id'> = {\n id: task.ID,\n text: task.Name || 'Untitled Task',\n start_date: this.formatDateForDHTMLX(startDate) as unknown as Date,\n duration: duration,\n progress: progress\n };\n\n // Add parent relationship for tree structure (not dependency)\n if (task.ParentID) {\n ganttTask.parent = task.ParentID;\n } else {\n // Root tasks need parent: 0\n ganttTask.parent = 0;\n }\n\n console.log('✅ Created Gantt task:', ganttTask);\n data.push(ganttTask as GanttTask);\n });\n\n // Create links from MJTaskDependencyEntity records\n this.taskDependencies.forEach((dep, index) => {\n links.push({\n id: dep.ID || `link_${index}`,\n source: dep.DependsOnTaskID, // The task being depended on\n target: dep.TaskID, // The task that depends on it\n type: '0' // finish-to-start (DHTMLX type 0)\n });\n console.log(`🔗 Created link: ${dep.DependsOnTaskID} -> ${dep.TaskID}`);\n });\n\n console.log('📊 Final DHTMLX format:', { data, links });\n return { data, links };\n }\n\n private calculateDuration(task: MJTaskEntity): number {\n if (task.StartedAt && task.DueAt) {\n const startDate = new Date(task.StartedAt);\n const endDate = new Date(task.DueAt);\n return Math.max(1, Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)));\n }\n return 1; // Default to 1 day\n }\n\n private formatDateForDHTMLX(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day} 00:00`;\n }\n\n public getAgentRunId(task: MJTaskEntity): string | null {\n return this.agentRunMap?.get(task.ID) || null;\n }\n\n public closeDetailPanel(): void {\n this.selectedTask = null;\n }\n\n public onOpenEntityRecord(event: { entityName: string; recordId: string }): void {\n this.openEntityRecord.emit(event);\n }\n\n public startResize(event: MouseEvent): void {\n this.isResizing = true;\n this.resizeStartX = event.clientX;\n this.resizeStartWidth = this.detailPanelWidth;\n event.preventDefault();\n }\n\n @HostListener('document:mousemove', ['$event'])\n handleResize(event: MouseEvent): void {\n if (!this.isResizing) return;\n\n const delta = this.resizeStartX - event.clientX;\n const newWidth = this.resizeStartWidth + delta;\n\n // Constrain width between min and max\n this.detailPanelWidth = Math.max(300, Math.min(600, newWidth));\n }\n\n @HostListener('document:mouseup')\n stopResize(): void {\n if (this.isResizing) {\n this.isResizing = false;\n // Resize gantt chart after panel resize completes\n setTimeout(() => {\n if (this.ganttInitialized && this.ganttLib) {\n this.ganttLib.setSizes();\n }\n }, 0);\n }\n }\n\n private expandAllAndSelectRoot(): void {\n try {\n const g = this.ganttLib!;\n\n // Expand all tasks\n g.eachTask((task: GanttTask) => {\n g.open(task.id);\n });\n\n // Find and select the root task (task with parent = 0)\n let rootTaskId: string | number | null = null;\n g.eachTask((task: GanttTask) => {\n if (task.parent === 0 || task.parent === '0') {\n rootTaskId = task.id;\n return false; // Stop iteration\n }\n });\n\n if (rootTaskId != null) {\n g.selectTask(rootTaskId);\n // Trigger task click event to open detail panel\n const originalTask = this.tasks.find(t => UUIDsEqual(t.ID, String(rootTaskId)));\n if (originalTask) {\n this.selectedTask = originalTask;\n this.taskClicked.emit(originalTask);\n }\n }\n\n console.log('✅ Expanded all tasks and selected root:', rootTaskId);\n } catch (error) {\n console.error('❌ Error expanding/selecting tasks:', error);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"gantt-task-viewer.component.js","sourceRoot":"","sources":["../../../src/lib/components/gantt-task-viewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAwC,SAAS,EAAa,YAAY,EAAE,MAAM,eAAe,CAAC;AAIjJ,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;;;;;IAY5C,8BAA+B;IAC7B,gCAAuD;IACzD,iBAAM;;;IAKJ,8BAAsB;IACpB,uBAAkC;IAClC,yBAAG;IAAA,iDAAiC;IACtC,AADsC,iBAAI,EACpC;;;;IAOF,+BACkC;IAAlC,oOAAa,0BAAmB,KAAC;IAAC,iBAAM;;;;IAItC,AADF,+BAAmE,+BAKf;IAAhD,AADA,iPAAc,yBAAkB,KAAC,sPACb,iCAA0B,KAAC;IAEnD,AADE,iBAAuB,EACnB;;;IAPyB,sDAAmC;IAE9D,cAAqB;IACrB,AADA,0CAAqB,yDACqB;;;IAVlD,8BAA0B;IACxB,4BAAmD;IACnD,sHAAoB;IAIpB,sHAAoB;IAUtB,iBAAM;;;IAdJ,eAGC;IAHD,8CAGC;IACD,cASC;IATD,8CASC;;;IAvBL,wGAAoC;IAOpC,wGAAiC;;;IAPjC,qEAKC;IAED,cAkBC;IAlBD,kEAkBC;;AAzCT;;GAEG;AA8HH,MAAM,OAAO,wBAAwB;IAC1B,KAAK,GAAmB,EAAE,CAAC;IAEpC,qCAAqC;IACrC,IAAa,KAAK,CAAC,KAAqB;QACtC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IACD,qCAAqC;IACrC,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IACQ,gBAAgB,GAA6B,EAAE,CAAC;IAEzD,gDAAgD;IAChD,IAAa,gBAAgB,CAAC,KAA+B;QAC3D,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAChC,CAAC;IACD,gDAAgD;IAChD,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IACQ,WAAW,CAAuB;IAE3C,2CAA2C;IAC3C,IAAa,WAAW,CAAC,KAAsC;QAC7D,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IACD,2CAA2C;IAC3C,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC,CAAC,4BAA4B;IACpB,WAAW,GAAG,IAAI,YAAY,EAAgB,CAAC;IAEzD;;;;;;OAMG;IACO,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IAC/B,gBAAgB,GAAG,IAAI,YAAY,EAA4C,CAAC;IAE1F;;;;;;OAMG;IACO,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;IAEH,cAAc,CAA8B;IAE5F,8CAA8C;IAC9C,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IACD,8CAA8C;IAC9C,IAAI,cAAc,CAAC,KAAiC;QAClD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;IAC9B,CAAC;IAEM,YAAY,GAAwB,IAAI,CAAC;IAEhD,4CAA4C;IAC5C,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IACD,4CAA4C;IAC5C,IAAW,YAAY,CAAC,KAA0B;QAChD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC5B,CAAC;IACM,gBAAgB,GAAW,GAAG,CAAC;IAEtC,gDAAgD;IAChD,IAAW,gBAAgB;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IACD,gDAAgD;IAChD,IAAW,gBAAgB,CAAC,KAAa;QACvC,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAChC,CAAC;IACM,cAAc,GAAG,IAAI,CAAC;IAErB,QAAQ,GAAuB,IAAI,CAAC;IACpC,gBAAgB,GAAG,KAAK,CAAC;IACzB,UAAU,GAAG,KAAK,CAAC;IACnB,YAAY,GAAG,CAAC,CAAC;IACjB,gBAAgB,GAAG,CAAC,CAAC;IAE7B,KAAK,CAAC,eAAe;QACnB,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE;YACvC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;YAClC,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc;SACpC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAC5C,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;YAC7B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAE5B,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC/D,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,WAAW;QACT,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE;YACnC,WAAW,EAAE,IAAI,CAAC,gBAAgB;YAClC,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc;YACnC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;SACnC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,yBAAyB;QAErD,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACjD,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChG,wEAAwE;YACxE,OAAO,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAC;YAChG,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAED,WAAW;QACT,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3C,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAChC,CAAC;IACH,CAAC;IAEO,SAAS;QACf,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;YAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,QAAS,CAAC;YAEzB,8CAA8C;YAC9C,CAAC,CAAC,QAAQ,EAAE,CAAC;YAEb,wCAAwC;YACxC,CAAC,CAAC,MAAM,CAAC,WAAW,GAAG,gBAAgB,CAAC;YACxC,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC;YAC5B,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC;YAC9B,CAAC,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;YACxB,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC;YAC9B,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;YAC3B,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;YAC3B,CAAC,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,oBAAoB;YAC9C,CAAC,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,6BAA6B;YAExD,+EAA+E;YAC/E,CAAC,CAAC,MAAM,CAAC,eAAe,GAAG,KAAK,CAAC;YAEjC,qBAAqB;YACrB,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,GAAG,CAAC;YAC1B,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;YACzB,CAAC,CAAC,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,mDAAmD;YAE9E,oDAAoD;YACpD,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG;gBAChB,GAAG,EAAE,iBAAiB;gBACtB,IAAI,EAAE;oBACJ;wBACE,IAAI,EAAE;4BACJ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE;4BACtD,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;4BAC3B,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE;4BAChE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE;yBAC1D;qBACF;oBACD,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE;iBAC5D;aACF,CAAC;YAEF,0DAA0D;YAC1D,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG;gBACjB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE;aAC7D,CAAC;YAEF,oCAAoC;YACpC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;YAC1C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAE7B,qBAAqB;YACrB,CAAC,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC,EAAU,EAAE,EAAE;gBAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;gBAChE,IAAI,YAAY,EAAE,CAAC;oBACjB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;oBACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACtC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,YAAY;YACZ,IAAI,CAAC,eAAe,EAAE,CAAC;YAEvB,0DAA0D;YAC1D,UAAU,CAAC,GAAG,EAAE;gBACd,CAAC,CAAC,QAAQ,EAAE,CAAC;YACf,CAAC,EAAE,CAAC,CAAC,CAAC;YAEN,2CAA2C;YAC3C,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,CAAC,EAAE,GAAG,CAAC,CAAC;YAER,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAEnC,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACvE,MAAM,CAAC,GAAG,IAAI,CAAC,QAAS,CAAC;YAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxD,CAAC,CAAC,QAAQ,EAAE,CAAC;YACb,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAEnB,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE;gBACxC,KAAK,EAAE,CAAC,CAAC,aAAa,EAAE;gBACxB,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE;aACpB,CAAC,CAAC;YAEH,iCAAiC;YACjC,UAAU,CAAC,GAAG,EAAE;gBACd,CAAC,CAAC,QAAQ,EAAE,CAAC;YACf,CAAC,EAAE,CAAC,CAAC,CAAC;YAEN,2CAA2C;YAC3C,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,CAAC,EAAE,GAAG,CAAC,CAAC;YAER,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,KAAqB;QAChD,MAAM,IAAI,GAAgB,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAgB,EAAE,CAAC;QAE9B,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAE5D,kDAAkD;QAClD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;QAChD,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAEzC,+DAA+D;QAC/D,MAAM,aAAa,GAAG,IAAI,GAAG,EAAoB,CAAC;QAClD,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YAClC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACpC,CAAC;YACD,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,8CAA8C;QAC9C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAgB,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC;QAC5B,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAE9B,wDAAwD;QACxD,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAE,UAAU,IAAI,GAAG,EAAU,EAAQ,EAAE;YAC/E,gCAAgC;YAChC,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxB,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAEpB,mCAAmC;YACnC,IAAI,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/B,OAAO,cAAc,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;YACrC,CAAC;YAED,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;YAErC,MAAM,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAErD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC9B,8DAA8D;gBAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACjF,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;gBACtC,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,4DAA4D;YAC5D,IAAI,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnC,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;gBACjC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACnC,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;oBACpD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAClC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,CAAC;oBAE/C,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;wBACvB,SAAS,GAAG,MAAM,CAAC;oBACrB,CAAC;gBACH,CAAC;YACH,CAAC;YAED,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACtC,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,sCAAsC;QACtC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAEnD,qDAAqD;QACrD,IAAI,OAAO,GAAgB,IAAI,CAAC;QAChC,IAAI,OAAO,GAAgB,IAAI,CAAC;QAEhC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACnB,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9C,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBAC9C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;gBACpC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC;gBAE9C,IAAI,CAAC,OAAO,IAAI,SAAS,GAAG,OAAO,EAAE,CAAC;oBACpC,OAAO,GAAG,SAAS,CAAC;gBACtB,CAAC;gBACD,IAAI,CAAC,OAAO,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;oBAClC,OAAO,GAAG,OAAO,CAAC;gBACpB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,qCAAqC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAS,CAAC;QACzB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;YACtC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YAC/C,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,WAAW,CAAC;QACpC,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;YACpC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YAC3C,CAAC,CAAC,MAAM,CAAC,QAAQ,GAAG,SAAS,CAAC;QAChC,CAAC;QAED,+CAA+C;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACrB,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE;gBACjC,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC;YAEH,4CAA4C;YAC5C,IAAI,QAAQ,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;YACjD,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC/B,QAAQ,GAAG,CAAC,CAAC;YACf,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC9C,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;YAEpE,MAAM,SAAS,GAA+C;gBAC5D,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,eAAe;gBAClC,UAAU,EAAE,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAoB;gBAClE,QAAQ,EAAE,QAAQ;gBAClB,QAAQ,EAAE,QAAQ;aACnB,CAAC;YAEF,8DAA8D;YAC9D,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACN,4BAA4B;gBAC5B,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;YACvB,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,SAAS,CAAC,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,SAAsB,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,mDAAmD;QACnD,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YAC3C,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,QAAQ,KAAK,EAAE;gBAC7B,MAAM,EAAE,GAAG,CAAC,eAAe,EAAE,6BAA6B;gBAC1D,MAAM,EAAE,GAAG,CAAC,MAAM,EAAY,8BAA8B;gBAC5D,IAAI,EAAE,GAAG,CAAC,kCAAkC;aAC7C,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,CAAC,eAAe,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;IAEO,iBAAiB,CAAC,IAAkB;QAC1C,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACnG,CAAC;QACD,OAAO,CAAC,CAAC,CAAC,mBAAmB;IAC/B,CAAC;IAEO,mBAAmB,CAAC,IAAU;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACpD,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,QAAQ,CAAC;IACzC,CAAC;IAEM,aAAa,CAAC,IAAkB;QACrC,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;IAChD,CAAC;IAED,6CAA6C;IACtC,aAAa,CAAC,IAAkB;QACrC,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAEM,gBAAgB;QACrB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED,gDAAgD;IACzC,gBAAgB;QACrB,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;IAEM,kBAAkB,CAAC,KAA+C;QACvE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,kDAAkD;IAC3C,kBAAkB,CAAC,KAA+C;QACvE,OAAO,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAEM,WAAW,CAAC,KAAiB;QAClC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC9C,KAAK,CAAC,cAAc,EAAE,CAAC;IACzB,CAAC;IAED,2CAA2C;IACpC,WAAW,CAAC,KAAiB;QAClC,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAGD,YAAY,CAAC,KAAiB;QAC5B,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAE7B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAE/C,sCAAsC;QACtC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjE,CAAC;IAGD,UAAU;QACR,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,kDAAkD;YAClD,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAC3C,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBAC3B,CAAC;YACH,CAAC,EAAE,CAAC,CAAC,CAAC;QACR,CAAC;IACH,CAAC;IAEO,sBAAsB;QAC5B,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,IAAI,CAAC,QAAS,CAAC;YAEzB,mBAAmB;YACnB,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAe,EAAE,EAAE;gBAC7B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;YAEH,uDAAuD;YACvD,IAAI,UAAU,GAA2B,IAAI,CAAC;YAC9C,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAe,EAAE,EAAE;gBAC7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC7C,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC;oBACrB,OAAO,KAAK,CAAC,CAAC,iBAAiB;gBACjC,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;gBACvB,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;gBACzB,gDAAgD;gBAChD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAChF,IAAI,YAAY,EAAE,CAAC;oBACjB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;oBACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,yCAAyC,EAAE,UAAU,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;kHAvgBU,wBAAwB;6DAAxB,wBAAwB;;;;;;YAAxB,2GAAA,wBAAoB,0BAAI,oFAAxB,gBAAY,0BAAY;;YAxHjC,8BAA+B;YAC7B,0FAAsB;YAMtB,gFAAuB;YA4BzB,iBAAM;;YAlCJ,cAIC;YAJD,6CAIC;YAED,cA2BC;YA3BD,8CA2BC;4BApCK,wBAAwB,EAAE,mBAAmB;;iFA0H5C,wBAAwB;cA7HpC,SAAS;2BACE,sBAAsB,cACpB,IAAI,WACP,CAAC,wBAAwB,EAAE,mBAAmB,CAAC,YAC9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqCP;;kBAqFF,KAAK;;kBAGL,KAAK;;kBAOL,KAAK;;kBAGL,KAAK;;kBAOL,KAAK;;kBAGL,KAAK;;kBAOL,MAAM;;kBASN,MAAM;;kBACN,MAAM;;kBASN,MAAM;;kBAEN,SAAS;mBAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;;kBA2Z7C,YAAY;mBAAC,oBAAoB,EAAE,CAAC,QAAQ,CAAC;;kBAW7C,YAAY;mBAAC,kBAAkB;;kFA1drB,wBAAwB","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, AfterViewInit, ElementRef, ViewChild, OnDestroy, HostListener } from '@angular/core';\n\nimport { MJTaskEntity, MJTaskDependencyEntity } from '@memberjunction/core-entities';\nimport type { GanttStatic, Task as GanttTask, Link as GanttLink } from 'dhtmlx-gantt';\nimport { TaskDetailPanelComponent } from './task-detail-panel.component';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * Gantt chart view for tasks using DHTMLX Gantt\n */\n@Component({\n selector: 'mj-gantt-task-viewer',\n standalone: true,\n imports: [TaskDetailPanelComponent, SharedGenericModule],\n template: `\n <div class=\"gantt-task-viewer\">\n @if (IsGanttLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading Gantt chart...\"></mj-loading>\n </div>\n }\n\n @if (!IsGanttLoading) {\n @if (!tasks || tasks.length === 0) {\n <div class=\"no-tasks\">\n <i class=\"fas fa-chart-gantt\"></i>\n <p>No tasks to display in Gantt view</p>\n </div>\n }\n\n @if (tasks && tasks.length > 0) {\n <div class=\"gantt-layout\">\n <div #ganttContainer class=\"gantt-container\"></div>\n @if (selectedTask) {\n <div class=\"gantt-resizer\"\n (mousedown)=\"startResize($event)\"></div>\n }\n @if (selectedTask) {\n <div class=\"task-detail-panel\" [style.width.px]=\"detailPanelWidth\">\n <mj-task-detail-panel\n [task]=\"selectedTask\"\n [agentRunId]=\"getAgentRunId(selectedTask)\"\n (closePanel)=\"closeDetailPanel()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-task-detail-panel>\n </div>\n }\n </div>\n }\n }\n </div>\n `,\n styles: [`\n .gantt-task-viewer {\n height: 100%;\n background: var(--mj-bg-surface);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .gantt-layout {\n display: flex;\n height: 600px;\n position: relative;\n }\n\n .gantt-container {\n flex: 1;\n min-width: 400px;\n height: 100%;\n position: relative;\n }\n\n .gantt-resizer {\n width: 4px;\n background: var(--mj-border-default);\n cursor: col-resize;\n flex-shrink: 0;\n transition: background 0.2s;\n }\n\n .gantt-resizer:hover {\n background: var(--mj-brand-primary);\n }\n\n .task-detail-panel {\n min-width: 300px;\n max-width: 600px;\n height: 100%;\n border-left: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n /* Override DHTMLX Gantt default styles */\n :host ::ng-deep .gantt_container {\n font-family: inherit;\n font-size: 13px;\n }\n\n :host ::ng-deep .gantt_grid_scale,\n :host ::ng-deep .gantt_task_scale {\n background: var(--mj-bg-surface-sunken);\n border-bottom: 2px solid var(--mj-border-default);\n }\n\n :host ::ng-deep .gantt_task .gantt_task_content {\n font-weight: 500;\n }\n\n .loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 80px 20px;\n }\n\n .no-tasks {\n text-align: center;\n padding: 80px 20px;\n color: var(--mj-text-disabled);\n }\n\n .no-tasks i {\n font-size: 64px;\n opacity: 0.3;\n margin-bottom: 16px;\n }\n\n .no-tasks p {\n margin: 0;\n font-size: 14px;\n }\n `]\n})\nexport class GanttTaskViewerComponent implements OnChanges, AfterViewInit, OnDestroy {\n @Input() Tasks: MJTaskEntity[] = [];\n\n /** @deprecated Use {@link Tasks}. */\n @Input() set tasks(value: MJTaskEntity[]) {\n this.Tasks = value;\n }\n /** @deprecated Use {@link Tasks}. */\n get tasks(): MJTaskEntity[] {\n return this.Tasks;\n }\n @Input() TaskDependencies: MJTaskDependencyEntity[] = [];\n\n /** @deprecated Use {@link TaskDependencies}. */\n @Input() set taskDependencies(value: MJTaskDependencyEntity[]) {\n this.TaskDependencies = value;\n }\n /** @deprecated Use {@link TaskDependencies}. */\n get taskDependencies(): MJTaskDependencyEntity[] {\n return this.TaskDependencies;\n }\n @Input() AgentRunMap?: Map<string, string>;\n\n /** @deprecated Use {@link AgentRunMap}. */\n @Input() set agentRunMap(value: Map<string, string> | undefined) {\n this.AgentRunMap = value;\n }\n /** @deprecated Use {@link AgentRunMap}. */\n get agentRunMap(): Map<string, string> | undefined {\n return this.AgentRunMap;\n } // Maps TaskID -> AgentRunID\n @Output() TaskClicked = new EventEmitter<MJTaskEntity>();\n\n /**\n * @deprecated Use {@link TaskClicked}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (taskClicked) keeps working. Must stay AFTER TaskClicked: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() taskClicked = this.TaskClicked;\n @Output() OpenEntityRecord = new EventEmitter<{ entityName: string; recordId: string }>();\n\n /**\n * @deprecated Use {@link OpenEntityRecord}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() openEntityRecord = this.OpenEntityRecord;\n\n @ViewChild('ganttContainer', { static: false }) GanttContainer!: ElementRef<HTMLDivElement>;\n\n /** @deprecated Use {@link GanttContainer}. */\n get ganttContainer(): ElementRef<HTMLDivElement> {\n return this.GanttContainer;\n }\n /** @deprecated Use {@link GanttContainer}. */\n set ganttContainer(value: ElementRef<HTMLDivElement>) {\n this.GanttContainer = value;\n }\n\n public SelectedTask: MJTaskEntity | null = null;\n\n /** @deprecated Use {@link SelectedTask}. */\n public get selectedTask(): MJTaskEntity | null {\n return this.SelectedTask;\n }\n /** @deprecated Use {@link SelectedTask}. */\n public set selectedTask(value: MJTaskEntity | null) {\n this.SelectedTask = value;\n }\n public DetailPanelWidth: number = 400;\n\n /** @deprecated Use {@link DetailPanelWidth}. */\n public get detailPanelWidth(): number {\n return this.DetailPanelWidth;\n }\n /** @deprecated Use {@link DetailPanelWidth}. */\n public set detailPanelWidth(value: number) {\n this.DetailPanelWidth = value;\n }\n public IsGanttLoading = true;\n\n private ganttLib: GanttStatic | null = null;\n private ganttInitialized = false;\n private isResizing = false;\n private resizeStartX = 0;\n private resizeStartWidth = 0;\n\n async ngAfterViewInit() {\n console.log('🔧 ngAfterViewInit called', {\n taskCount: this.Tasks?.length || 0,\n hasContainer: !!this.GanttContainer\n });\n\n try {\n const module = await import('dhtmlx-gantt');\n this.ganttLib = module.gantt;\n this.IsGanttLoading = false;\n\n if (this.Tasks && this.Tasks.length > 0 && this.GanttContainer) {\n this.initGantt();\n }\n } catch (error) {\n console.error('Failed to load dhtmlx-gantt:', error);\n this.IsGanttLoading = false;\n }\n }\n\n ngOnChanges() {\n console.log('🔄 ngOnChanges called', {\n initialized: this.ganttInitialized,\n hasContainer: !!this.GanttContainer,\n taskCount: this.Tasks?.length || 0\n });\n\n if (!this.ganttLib) return; // Library not yet loaded\n\n if (this.ganttInitialized && this.GanttContainer) {\n this.updateGanttData();\n } else if (!this.ganttInitialized && this.GanttContainer && this.Tasks && this.Tasks.length > 0) {\n // Initialize if we have container and tasks but haven't initialized yet\n console.log('🎨 Late initialization - gantt not initialized but container and tasks available');\n this.initGantt();\n }\n }\n\n ngOnDestroy() {\n if (this.ganttInitialized && this.ganttLib) {\n this.ganttLib.clearAll();\n this.ganttInitialized = false;\n }\n }\n\n private initGantt(): void {\n try {\n console.log('🎨 Initializing DHTMLX Gantt');\n const g = this.ganttLib!;\n\n // IMPORTANT: Clear any previous configuration\n g.clearAll();\n\n // Configure Gantt layout and appearance\n g.config.date_format = '%Y-%m-%d %H:%i';\n g.config.scale_unit = 'day';\n g.config.date_scale = '%d %M';\n g.config.subscales = [];\n g.config.show_progress = true;\n g.config.show_links = true;\n g.config.auto_types = true;\n g.config.readonly = true; // Read-only for now\n g.config.fit_tasks = true; // Auto-fit timeline to tasks\n\n // Disable auto-scheduling - we calculate dates ourselves based on dependencies\n g.config.auto_scheduling = false;\n\n // Grid configuration\n g.config.grid_width = 350;\n g.config.row_height = 36;\n g.config.scale_height = 0; // Hide date scale - dates are just for positioning\n\n // Layout configuration - ensure timeline is visible\n g.config.layout = {\n css: \"gantt_container\",\n rows: [\n {\n cols: [\n { view: \"grid\", group: \"grids\", scrollY: \"scrollVer\" },\n { resizer: true, width: 1 },\n { view: \"timeline\", scrollX: \"scrollHor\", scrollY: \"scrollVer\" },\n { view: \"scrollbar\", id: \"scrollVer\", group: \"vertical\" }\n ]\n },\n { view: \"scrollbar\", id: \"scrollHor\", group: \"horizontal\" }\n ]\n };\n\n // Column configuration - only show task names, hide dates\n g.config.columns = [\n { name: 'text', label: 'Task name', tree: true, width: '*' }\n ];\n\n // Initialize Gantt in the container\n g.init(this.GanttContainer.nativeElement);\n this.ganttInitialized = true;\n\n // Attach click event\n g.attachEvent('onTaskClick', (id: string) => {\n const originalTask = this.Tasks.find(t => UUIDsEqual(t.ID, id));\n if (originalTask) {\n this.SelectedTask = originalTask;\n this.TaskClicked.emit(originalTask);\n }\n return true;\n });\n\n // Load data\n this.updateGanttData();\n\n // Force resize after data load to ensure proper rendering\n setTimeout(() => {\n g.setSizes();\n }, 0);\n\n // Expand and select after render completes\n setTimeout(() => {\n this.expandAllAndSelectRoot();\n }, 100);\n\n console.log('✅ DHTMLX Gantt initialized successfully');\n } catch (error) {\n console.error('❌ Error initializing Gantt:', error);\n }\n }\n\n private updateGanttData(): void {\n if (!this.ganttInitialized) return;\n\n try {\n console.log('📊 Updating Gantt data with', this.Tasks.length, 'tasks');\n const g = this.ganttLib!;\n\n const ganttData = this.convertToGanttFormat(this.Tasks);\n g.clearAll();\n g.parse(ganttData);\n\n // Log final parsed data for debugging\n console.log('📋 Gantt data after parse:', {\n tasks: g.getTaskByTime(),\n links: g.getLinks()\n });\n\n // Force resize after data update\n setTimeout(() => {\n g.setSizes();\n }, 0);\n\n // Expand and select after render completes\n setTimeout(() => {\n this.expandAllAndSelectRoot();\n }, 100);\n\n console.log('✅ Gantt data updated');\n } catch (error) {\n console.error('❌ Error updating Gantt data:', error);\n }\n }\n\n private convertToGanttFormat(tasks: MJTaskEntity[]): { data: GanttTask[], links: GanttLink[] } {\n const data: GanttTask[] = [];\n const links: GanttLink[] = [];\n\n console.log('🔍 Converting tasks:', tasks);\n console.log('🔗 Task dependencies:', this.TaskDependencies);\n\n // Build a map of task ID to task for quick lookup\n const taskMap = new Map<string, MJTaskEntity>();\n tasks.forEach(t => taskMap.set(t.ID, t));\n\n // Build dependency map: taskId -> array of tasks it depends on\n const dependencyMap = new Map<string, string[]>();\n this.TaskDependencies.forEach(dep => {\n if (!dependencyMap.has(dep.TaskID)) {\n dependencyMap.set(dep.TaskID, []);\n }\n dependencyMap.get(dep.TaskID)!.push(dep.DependsOnTaskID);\n });\n\n // Calculate start dates based on dependencies\n const taskStartDates = new Map<string, Date>();\n const baseDate = new Date();\n baseDate.setHours(0, 0, 0, 0);\n\n // Recursive function to calculate start date for a task\n const calculateStartDate = (taskId: string, visited = new Set<string>()): Date => {\n // Prevent circular dependencies\n if (visited.has(taskId)) {\n return new Date(baseDate);\n }\n visited.add(taskId);\n\n // If already calculated, return it\n if (taskStartDates.has(taskId)) {\n return taskStartDates.get(taskId)!;\n }\n\n const task = taskMap.get(taskId);\n if (!task) return new Date(baseDate);\n\n const dependencies = dependencyMap.get(taskId) || [];\n\n if (dependencies.length === 0) {\n // No dependencies - use base date or task's actual start date\n const startDate = task.StartedAt ? new Date(task.StartedAt) : new Date(baseDate);\n taskStartDates.set(taskId, startDate);\n return startDate;\n }\n\n // Has dependencies - start after the latest dependency ends\n let latestEnd = new Date(baseDate);\n for (const depId of dependencies) {\n const depTask = taskMap.get(depId);\n if (depTask) {\n const depStart = calculateStartDate(depId, new Set(visited));\n const depDuration = this.calculateDuration(depTask);\n const depEnd = new Date(depStart);\n depEnd.setDate(depEnd.getDate() + depDuration);\n\n if (depEnd > latestEnd) {\n latestEnd = depEnd;\n }\n }\n }\n\n taskStartDates.set(taskId, latestEnd);\n return latestEnd;\n };\n\n // Calculate start dates for all tasks\n tasks.forEach(task => calculateStartDate(task.ID));\n\n // Calculate min/max dates for timeline display range\n let minDate: Date | null = null;\n let maxDate: Date | null = null;\n\n tasks.forEach(task => {\n const startDate = taskStartDates.get(task.ID);\n if (startDate) {\n const duration = this.calculateDuration(task);\n const endDate = new Date(startDate);\n endDate.setDate(endDate.getDate() + duration);\n\n if (!minDate || startDate < minDate) {\n minDate = startDate;\n }\n if (!maxDate || endDate > maxDate) {\n maxDate = endDate;\n }\n }\n });\n\n // Add 1 day padding before and after\n const g = this.ganttLib!;\n if (minDate) {\n const paddedStart = new Date(minDate);\n paddedStart.setDate(paddedStart.getDate() - 1);\n g.config.start_date = paddedStart;\n }\n if (maxDate) {\n const paddedEnd = new Date(maxDate);\n paddedEnd.setDate(paddedEnd.getDate() + 1);\n g.config.end_date = paddedEnd;\n }\n\n // Now create Gantt tasks with calculated dates\n tasks.forEach((task) => {\n console.log('📝 Processing task:', {\n ID: task.ID,\n Name: task.Name,\n ParentID: task.ParentID\n });\n\n // Calculate progress (0-1 scale for DHTMLX)\n let progress = (task.PercentComplete || 0) / 100;\n if (task.Status === 'Complete') {\n progress = 1;\n }\n\n const duration = this.calculateDuration(task);\n const startDate = taskStartDates.get(task.ID) || new Date(baseDate);\n\n const ganttTask: Partial<GanttTask> & Pick<GanttTask, 'id'> = {\n id: task.ID,\n text: task.Name || 'Untitled Task',\n start_date: this.formatDateForDHTMLX(startDate) as unknown as Date,\n duration: duration,\n progress: progress\n };\n\n // Add parent relationship for tree structure (not dependency)\n if (task.ParentID) {\n ganttTask.parent = task.ParentID;\n } else {\n // Root tasks need parent: 0\n ganttTask.parent = 0;\n }\n\n console.log('✅ Created Gantt task:', ganttTask);\n data.push(ganttTask as GanttTask);\n });\n\n // Create links from MJTaskDependencyEntity records\n this.TaskDependencies.forEach((dep, index) => {\n links.push({\n id: dep.ID || `link_${index}`,\n source: dep.DependsOnTaskID, // The task being depended on\n target: dep.TaskID, // The task that depends on it\n type: '0' // finish-to-start (DHTMLX type 0)\n });\n console.log(`🔗 Created link: ${dep.DependsOnTaskID} -> ${dep.TaskID}`);\n });\n\n console.log('📊 Final DHTMLX format:', { data, links });\n return { data, links };\n }\n\n private calculateDuration(task: MJTaskEntity): number {\n if (task.StartedAt && task.DueAt) {\n const startDate = new Date(task.StartedAt);\n const endDate = new Date(task.DueAt);\n return Math.max(1, Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)));\n }\n return 1; // Default to 1 day\n }\n\n private formatDateForDHTMLX(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day} 00:00`;\n }\n\n public GetAgentRunId(task: MJTaskEntity): string | null {\n return this.AgentRunMap?.get(task.ID) || null;\n }\n\n /** @deprecated Use {@link GetAgentRunId}. */\n public getAgentRunId(task: MJTaskEntity): string | null {\n return this.GetAgentRunId(task);\n }\n\n public CloseDetailPanel(): void {\n this.SelectedTask = null;\n }\n\n /** @deprecated Use {@link CloseDetailPanel}. */\n public closeDetailPanel(): void {\n return this.CloseDetailPanel();\n }\n\n public OnOpenEntityRecord(event: { entityName: string; recordId: string }): void {\n this.OpenEntityRecord.emit(event);\n }\n\n /** @deprecated Use {@link OnOpenEntityRecord}. */\n public onOpenEntityRecord(event: { entityName: string; recordId: string }): void {\n return this.OnOpenEntityRecord(event);\n }\n\n public StartResize(event: MouseEvent): void {\n this.isResizing = true;\n this.resizeStartX = event.clientX;\n this.resizeStartWidth = this.DetailPanelWidth;\n event.preventDefault();\n }\n\n /** @deprecated Use {@link StartResize}. */\n public startResize(event: MouseEvent): void {\n return this.StartResize(event);\n }\n\n @HostListener('document:mousemove', ['$event'])\n handleResize(event: MouseEvent): void {\n if (!this.isResizing) return;\n\n const delta = this.resizeStartX - event.clientX;\n const newWidth = this.resizeStartWidth + delta;\n\n // Constrain width between min and max\n this.DetailPanelWidth = Math.max(300, Math.min(600, newWidth));\n }\n\n @HostListener('document:mouseup')\n stopResize(): void {\n if (this.isResizing) {\n this.isResizing = false;\n // Resize gantt chart after panel resize completes\n setTimeout(() => {\n if (this.ganttInitialized && this.ganttLib) {\n this.ganttLib.setSizes();\n }\n }, 0);\n }\n }\n\n private expandAllAndSelectRoot(): void {\n try {\n const g = this.ganttLib!;\n\n // Expand all tasks\n g.eachTask((task: GanttTask) => {\n g.open(task.id);\n });\n\n // Find and select the root task (task with parent = 0)\n let rootTaskId: string | number | null = null;\n g.eachTask((task: GanttTask) => {\n if (task.parent === 0 || task.parent === '0') {\n rootTaskId = task.id;\n return false; // Stop iteration\n }\n });\n\n if (rootTaskId != null) {\n g.selectTask(rootTaskId);\n // Trigger task click event to open detail panel\n const originalTask = this.Tasks.find(t => UUIDsEqual(t.ID, String(rootTaskId)));\n if (originalTask) {\n this.SelectedTask = originalTask;\n this.TaskClicked.emit(originalTask);\n }\n }\n\n console.log('✅ Expanded all tasks and selected root:', rootTaskId);\n } catch (error) {\n console.error('❌ Error expanding/selecting tasks:', error);\n }\n }\n}\n"]}
@@ -5,33 +5,83 @@ import * as i0 from "@angular/core";
5
5
  * Simple list view for tasks
6
6
  */
7
7
  export declare class SimpleTaskViewerComponent implements OnChanges {
8
- tasks: MJTaskEntity[];
9
- agentRunMap?: Map<string, string>;
8
+ Tasks: MJTaskEntity[];
9
+ /** @deprecated Use {@link Tasks}. */
10
+ set tasks(value: MJTaskEntity[]);
11
+ /** @deprecated Use {@link Tasks}. */
12
+ get tasks(): MJTaskEntity[];
13
+ AgentRunMap?: Map<string, string>;
14
+ /** @deprecated Use {@link AgentRunMap}. */
15
+ set agentRunMap(value: Map<string, string> | undefined);
16
+ /** @deprecated Use {@link AgentRunMap}. */
17
+ get agentRunMap(): Map<string, string> | undefined;
18
+ TaskClicked: EventEmitter<MJTaskEntity>;
19
+ /**
20
+ * @deprecated Use {@link TaskClicked}.
21
+ *
22
+ * The same emitter under the old binding name, so a template still binding
23
+ * (taskClicked) keeps working. Must stay AFTER TaskClicked: class fields
24
+ * initialise in order, and the other way round this captures undefined.
25
+ */
10
26
  taskClicked: EventEmitter<MJTaskEntity>;
27
+ OpenEntityRecord: EventEmitter<{
28
+ entityName: string;
29
+ recordId: string;
30
+ }>;
31
+ /**
32
+ * @deprecated Use {@link OpenEntityRecord}.
33
+ *
34
+ * The same emitter under the old binding name, so a template still binding
35
+ * (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields
36
+ * initialise in order, and the other way round this captures undefined.
37
+ */
11
38
  openEntityRecord: EventEmitter<{
12
39
  entityName: string;
13
40
  recordId: string;
14
41
  }>;
15
- selectedTask: MJTaskEntity | null;
42
+ SelectedTask: MJTaskEntity | null;
43
+ /** @deprecated Use {@link SelectedTask}. */
44
+ get selectedTask(): MJTaskEntity | null;
45
+ /** @deprecated Use {@link SelectedTask}. */
46
+ set selectedTask(value: MJTaskEntity | null);
16
47
  IsTaskSelected(task: MJTaskEntity): boolean;
17
- detailPanelWidth: number;
48
+ DetailPanelWidth: number;
49
+ /** @deprecated Use {@link DetailPanelWidth}. */
50
+ get detailPanelWidth(): number;
51
+ /** @deprecated Use {@link DetailPanelWidth}. */
52
+ set detailPanelWidth(value: number);
18
53
  private isResizing;
19
54
  private resizeStartX;
20
55
  private resizeStartWidth;
21
56
  ngOnChanges(): void;
57
+ OnTaskClick(task: MJTaskEntity): void;
58
+ /** @deprecated Use {@link OnTaskClick}. */
22
59
  onTaskClick(task: MJTaskEntity): void;
60
+ GetAgentRunId(task: MJTaskEntity): string | null;
61
+ /** @deprecated Use {@link GetAgentRunId}. */
23
62
  getAgentRunId(task: MJTaskEntity): string | null;
63
+ CloseDetailPanel(): void;
64
+ /** @deprecated Use {@link CloseDetailPanel}. */
24
65
  closeDetailPanel(): void;
66
+ OnOpenEntityRecord(event: {
67
+ entityName: string;
68
+ recordId: string;
69
+ }): void;
70
+ /** @deprecated Use {@link OnOpenEntityRecord}. */
25
71
  onOpenEntityRecord(event: {
26
72
  entityName: string;
27
73
  recordId: string;
28
74
  }): void;
75
+ StartResize(event: MouseEvent): void;
76
+ /** @deprecated Use {@link StartResize}. */
29
77
  startResize(event: MouseEvent): void;
30
78
  handleResize(event: MouseEvent): void;
31
79
  stopResize(): void;
80
+ GetStatusIcon(status: string): string;
81
+ /** @deprecated Use {@link GetStatusIcon}. */
32
82
  getStatusIcon(status: string): string;
33
83
  formatDate(date: Date | null): string;
34
84
  static ɵfac: i0.ɵɵFactoryDeclaration<SimpleTaskViewerComponent, never>;
35
- static ɵcmp: i0.ɵɵComponentDeclaration<SimpleTaskViewerComponent, "mj-simple-task-viewer", never, { "tasks": { "alias": "tasks"; "required": false; }; "agentRunMap": { "alias": "agentRunMap"; "required": false; }; }, { "taskClicked": "taskClicked"; "openEntityRecord": "openEntityRecord"; }, never, never, true, never>;
85
+ static ɵcmp: i0.ɵɵComponentDeclaration<SimpleTaskViewerComponent, "mj-simple-task-viewer", never, { "Tasks": { "alias": "Tasks"; "required": false; }; "tasks": { "alias": "tasks"; "required": false; }; "AgentRunMap": { "alias": "AgentRunMap"; "required": false; }; "agentRunMap": { "alias": "agentRunMap"; "required": false; }; }, { "TaskClicked": "TaskClicked"; "taskClicked": "taskClicked"; "OpenEntityRecord": "OpenEntityRecord"; "openEntityRecord": "openEntityRecord"; }, never, never, true, never>;
36
86
  }
37
87
  //# sourceMappingURL=simple-task-viewer.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"simple-task-viewer.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/simple-task-viewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,SAAS,EAAgB,MAAM,eAAe,CAAC;AAEhG,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;;AAI7D;;GAEG;AACH,qBAgTa,yBAA0B,YAAW,SAAS;IAChD,KAAK,EAAE,YAAY,EAAE,CAAM;IAC3B,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,6BAAoC;IAC/C,gBAAgB;oBAAkC,MAAM;kBAAY,MAAM;OAAM;IAEnF,YAAY,EAAE,YAAY,GAAG,IAAI,CAAQ;IAEzC,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO;IAG3C,gBAAgB,EAAE,MAAM,CAAO;IAEtC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,gBAAgB,CAAK;IAE7B,WAAW;IAIJ,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAKrC,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI;IAIhD,gBAAgB,IAAI,IAAI;IAIxB,kBAAkB,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAIzE,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAQ3C,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAWrC,UAAU,IAAI,IAAI;IAIX,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAWrC,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM;yCAxEjC,yBAAyB;2CAAzB,yBAAyB;CA6ErC"}
1
+ {"version":3,"file":"simple-task-viewer.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/simple-task-viewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,SAAS,EAAgB,MAAM,eAAe,CAAC;AAEhG,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;;AAI7D;;GAEG;AACH,qBAgTa,yBAA0B,YAAW,SAAS;IAChD,KAAK,EAAE,YAAY,EAAE,CAAM;IAEpC,qCAAqC;IACrC,IAAa,KAAK,CAAC,KAAK,EAAE,YAAY,EAAE,EAEvC;IACD,qCAAqC;IACrC,IAAI,KAAK,IAAI,YAAY,EAAE,CAE1B;IACQ,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE3C,2CAA2C;IAC3C,IAAa,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAE9D;IACD,2CAA2C;IAC3C,IAAI,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAEjD;IACS,WAAW,6BAAoC;IAEzD;;;;;;OAMG;IACO,WAAW,6BAAoB;IAC/B,gBAAgB;oBAAkC,MAAM;kBAAY,MAAM;OAAM;IAE1F;;;;;;OAMG;IACO,gBAAgB;oBATkC,MAAM;kBAAY,MAAM;OASjC;IAE5C,YAAY,EAAE,YAAY,GAAG,IAAI,CAAQ;IAEhD,4CAA4C;IAC5C,IAAW,YAAY,IAAI,YAAY,GAAG,IAAI,CAE7C;IACD,4CAA4C;IAC5C,IAAW,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,EAEjD;IAEM,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO;IAG3C,gBAAgB,EAAE,MAAM,CAAO;IAEtC,gDAAgD;IAChD,IAAW,gBAAgB,IAAI,MAAM,CAEpC;IACD,gDAAgD;IAChD,IAAW,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAExC;IAED,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,gBAAgB,CAAK;IAE7B,WAAW;IAIJ,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAK5C,2CAA2C;IACpC,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAIrC,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI;IAIvD,6CAA6C;IACtC,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI;IAIhD,gBAAgB,IAAI,IAAI;IAI/B,gDAAgD;IACzC,gBAAgB,IAAI,IAAI;IAIxB,kBAAkB,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAIhF,kDAAkD;IAC3C,kBAAkB,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAIzE,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAO3C,2CAA2C;IACpC,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAK3C,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAWrC,UAAU,IAAI,IAAI;IAIX,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAW5C,6CAA6C;IACtC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIrC,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM;yCA5JjC,yBAAyB;2CAAzB,yBAAyB;CAiKrC"}
@@ -109,52 +109,120 @@ function SimpleTaskViewerComponent_Conditional_7_Template(rf, ctx) { if (rf & 1)
109
109
  * Simple list view for tasks
110
110
  */
111
111
  export class SimpleTaskViewerComponent {
112
- tasks = [];
113
- agentRunMap; // Maps TaskID -> AgentRunID
114
- taskClicked = new EventEmitter();
115
- openEntityRecord = new EventEmitter();
116
- selectedTask = null;
112
+ Tasks = [];
113
+ /** @deprecated Use {@link Tasks}. */
114
+ set tasks(value) {
115
+ this.Tasks = value;
116
+ }
117
+ /** @deprecated Use {@link Tasks}. */
118
+ get tasks() {
119
+ return this.Tasks;
120
+ }
121
+ AgentRunMap;
122
+ /** @deprecated Use {@link AgentRunMap}. */
123
+ set agentRunMap(value) {
124
+ this.AgentRunMap = value;
125
+ }
126
+ /** @deprecated Use {@link AgentRunMap}. */
127
+ get agentRunMap() {
128
+ return this.AgentRunMap;
129
+ } // Maps TaskID -> AgentRunID
130
+ TaskClicked = new EventEmitter();
131
+ /**
132
+ * @deprecated Use {@link TaskClicked}.
133
+ *
134
+ * The same emitter under the old binding name, so a template still binding
135
+ * (taskClicked) keeps working. Must stay AFTER TaskClicked: class fields
136
+ * initialise in order, and the other way round this captures undefined.
137
+ */
138
+ taskClicked = this.TaskClicked;
139
+ OpenEntityRecord = new EventEmitter();
140
+ /**
141
+ * @deprecated Use {@link OpenEntityRecord}.
142
+ *
143
+ * The same emitter under the old binding name, so a template still binding
144
+ * (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields
145
+ * initialise in order, and the other way round this captures undefined.
146
+ */
147
+ openEntityRecord = this.OpenEntityRecord;
148
+ SelectedTask = null;
149
+ /** @deprecated Use {@link SelectedTask}. */
150
+ get selectedTask() {
151
+ return this.SelectedTask;
152
+ }
153
+ /** @deprecated Use {@link SelectedTask}. */
154
+ set selectedTask(value) {
155
+ this.SelectedTask = value;
156
+ }
117
157
  IsTaskSelected(task) {
118
- return UUIDsEqual(this.selectedTask?.ID, task.ID);
158
+ return UUIDsEqual(this.SelectedTask?.ID, task.ID);
159
+ }
160
+ DetailPanelWidth = 400;
161
+ /** @deprecated Use {@link DetailPanelWidth}. */
162
+ get detailPanelWidth() {
163
+ return this.DetailPanelWidth;
164
+ }
165
+ /** @deprecated Use {@link DetailPanelWidth}. */
166
+ set detailPanelWidth(value) {
167
+ this.DetailPanelWidth = value;
119
168
  }
120
- detailPanelWidth = 400;
121
169
  isResizing = false;
122
170
  resizeStartX = 0;
123
171
  resizeStartWidth = 0;
124
172
  ngOnChanges() {
125
173
  // Tasks are already loaded
126
174
  }
175
+ OnTaskClick(task) {
176
+ this.SelectedTask = task;
177
+ this.TaskClicked.emit(task);
178
+ }
179
+ /** @deprecated Use {@link OnTaskClick}. */
127
180
  onTaskClick(task) {
128
- this.selectedTask = task;
129
- this.taskClicked.emit(task);
181
+ return this.OnTaskClick(task);
182
+ }
183
+ GetAgentRunId(task) {
184
+ return this.AgentRunMap?.get(task.ID) || null;
130
185
  }
186
+ /** @deprecated Use {@link GetAgentRunId}. */
131
187
  getAgentRunId(task) {
132
- return this.agentRunMap?.get(task.ID) || null;
188
+ return this.GetAgentRunId(task);
133
189
  }
190
+ CloseDetailPanel() {
191
+ this.SelectedTask = null;
192
+ }
193
+ /** @deprecated Use {@link CloseDetailPanel}. */
134
194
  closeDetailPanel() {
135
- this.selectedTask = null;
195
+ return this.CloseDetailPanel();
196
+ }
197
+ OnOpenEntityRecord(event) {
198
+ this.OpenEntityRecord.emit(event);
136
199
  }
200
+ /** @deprecated Use {@link OnOpenEntityRecord}. */
137
201
  onOpenEntityRecord(event) {
138
- this.openEntityRecord.emit(event);
202
+ return this.OnOpenEntityRecord(event);
139
203
  }
140
- startResize(event) {
204
+ StartResize(event) {
141
205
  this.isResizing = true;
142
206
  this.resizeStartX = event.clientX;
143
- this.resizeStartWidth = this.detailPanelWidth;
207
+ this.resizeStartWidth = this.DetailPanelWidth;
144
208
  event.preventDefault();
145
209
  }
210
+ /** @deprecated Use {@link StartResize}. */
211
+ startResize(event) {
212
+ return this.StartResize(event);
213
+ }
146
214
  handleResize(event) {
147
215
  if (!this.isResizing)
148
216
  return;
149
217
  const delta = this.resizeStartX - event.clientX;
150
218
  const newWidth = this.resizeStartWidth + delta;
151
219
  // Constrain width between min and max
152
- this.detailPanelWidth = Math.max(300, Math.min(600, newWidth));
220
+ this.DetailPanelWidth = Math.max(300, Math.min(600, newWidth));
153
221
  }
154
222
  stopResize() {
155
223
  this.isResizing = false;
156
224
  }
157
- getStatusIcon(status) {
225
+ GetStatusIcon(status) {
158
226
  switch (status) {
159
227
  case 'Complete': return 'fa-check-circle';
160
228
  case 'In Progress': return 'fa-spinner';
@@ -164,6 +232,10 @@ export class SimpleTaskViewerComponent {
164
232
  default: return 'fa-circle';
165
233
  }
166
234
  }
235
+ /** @deprecated Use {@link GetStatusIcon}. */
236
+ getStatusIcon(status) {
237
+ return this.GetStatusIcon(status);
238
+ }
167
239
  formatDate(date) {
168
240
  if (!date)
169
241
  return '';
@@ -173,7 +245,7 @@ export class SimpleTaskViewerComponent {
173
245
  static ɵfac = function SimpleTaskViewerComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SimpleTaskViewerComponent)(); };
174
246
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SimpleTaskViewerComponent, selectors: [["mj-simple-task-viewer"]], hostBindings: function SimpleTaskViewerComponent_HostBindings(rf, ctx) { if (rf & 1) {
175
247
  i0.ɵɵlistener("mousemove", function SimpleTaskViewerComponent_mousemove_HostBindingHandler($event) { return ctx.handleResize($event); }, i0.ɵɵresolveDocument)("mouseup", function SimpleTaskViewerComponent_mouseup_HostBindingHandler() { return ctx.stopResize(); }, i0.ɵɵresolveDocument);
176
- } }, inputs: { tasks: "tasks", agentRunMap: "agentRunMap" }, outputs: { taskClicked: "taskClicked", openEntityRecord: "openEntityRecord" }, features: [i0.ɵɵNgOnChangesFeature], decls: 8, vars: 5, consts: [[1, "simple-task-viewer"], [1, "list-layout"], [1, "task-list"], [1, "task-item", 3, "completed", "selected"], [1, "no-tasks"], [1, "list-resizer"], [1, "task-detail-panel", 3, "width"], [1, "task-item", 3, "click"], [1, "status-icon"], [1, "fas", 3, "ngClass"], [1, "task-content"], [1, "task-header"], [1, "task-title-row"], [1, "task-title"], [1, "fas", "fa-check", "completed-check"], [1, "task-progress-compact"], [1, "task-meta"], [1, "due-date"], [1, "assigned-to"], [1, "progress-bar-compact"], [1, "progress-fill-compact"], [1, "progress-text-compact"], [1, "far", "fa-calendar"], [1, "far", "fa-user"], [1, "fas", "fa-tasks"], [1, "list-resizer", 3, "mousedown"], [1, "task-detail-panel"], [3, "closePanel", "openEntityRecord", "task", "agentRunId"]], template: function SimpleTaskViewerComponent_Template(rf, ctx) { if (rf & 1) {
248
+ } }, inputs: { Tasks: "Tasks", tasks: "tasks", AgentRunMap: "AgentRunMap", agentRunMap: "agentRunMap" }, outputs: { TaskClicked: "TaskClicked", taskClicked: "taskClicked", OpenEntityRecord: "OpenEntityRecord", openEntityRecord: "openEntityRecord" }, features: [i0.ɵɵNgOnChangesFeature], decls: 8, vars: 5, consts: [[1, "simple-task-viewer"], [1, "list-layout"], [1, "task-list"], [1, "task-item", 3, "completed", "selected"], [1, "no-tasks"], [1, "list-resizer"], [1, "task-detail-panel", 3, "width"], [1, "task-item", 3, "click"], [1, "status-icon"], [1, "fas", 3, "ngClass"], [1, "task-content"], [1, "task-header"], [1, "task-title-row"], [1, "task-title"], [1, "fas", "fa-check", "completed-check"], [1, "task-progress-compact"], [1, "task-meta"], [1, "due-date"], [1, "assigned-to"], [1, "progress-bar-compact"], [1, "progress-fill-compact"], [1, "progress-text-compact"], [1, "far", "fa-calendar"], [1, "far", "fa-user"], [1, "fas", "fa-tasks"], [1, "list-resizer", 3, "mousedown"], [1, "task-detail-panel"], [3, "closePanel", "openEntityRecord", "task", "agentRunId"]], template: function SimpleTaskViewerComponent_Template(rf, ctx) { if (rf & 1) {
177
249
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
178
250
  i0.ɵɵrepeaterCreate(3, SimpleTaskViewerComponent_For_4_Template, 13, 18, "div", 3, i0.ɵɵrepeaterTrackByIdentity);
179
251
  i0.ɵɵconditionalCreate(5, SimpleTaskViewerComponent_Conditional_5_Template, 4, 0, "div", 4);
@@ -280,12 +352,20 @@ export class SimpleTaskViewerComponent {
280
352
  </div>
281
353
  </div>
282
354
  `, styles: ["\n .simple-task-viewer {\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .list-layout {\n display: flex;\n height: 100%;\n position: relative;\n }\n\n .task-list {\n flex: 1;\n min-width: 400px;\n padding: 16px;\n overflow-y: auto;\n }\n\n .task-list.with-detail {\n border-right: 1px solid var(--mj-border-default);\n }\n\n .list-resizer {\n width: 4px;\n background: var(--mj-border-default);\n cursor: col-resize;\n flex-shrink: 0;\n transition: background 0.2s;\n }\n\n .list-resizer:hover {\n background: var(--mj-brand-primary);\n }\n\n .task-detail-panel {\n min-width: 300px;\n max-width: 600px;\n height: 100%;\n flex-shrink: 0;\n }\n\n .task-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 8px;\n transition: all 0.2s;\n cursor: pointer;\n }\n\n .task-item:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n transform: translateY(-1px);\n }\n\n .task-item.selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-sm);\n }\n\n .task-item.completed {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n }\n\n .status-icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n flex-shrink: 0;\n }\n\n .status-icon.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n\n /* Failed and Blocked are distinct outcomes: Failed is this task's own error, Blocked\n means an upstream dependency can never be satisfied. Both previously rendered with\n the default (pending) treatment, so a dead graph looked like a waiting one. */\n .status-icon.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n\n .status-icon.blocked {\n background: color-mix(in srgb, var(--mj-text-muted) 15%, var(--mj-bg-surface));\n color: var(--mj-text-muted);\n }\n\n .task-content {\n flex: 1;\n min-width: 0;\n }\n\n .task-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 6px;\n }\n\n .task-title-row {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n }\n\n .task-title {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 14px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .task-title.completed-text {\n color: var(--mj-text-muted);\n text-decoration: line-through;\n text-decoration-thickness: 1.5px;\n }\n\n .completed-check {\n color: var(--mj-status-success);\n font-size: 12px;\n }\n\n .task-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n }\n\n .task-meta i {\n margin-right: 4px;\n }\n\n .task-description {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-bottom: 8px;\n line-height: 1.5;\n }\n\n .task-progress-compact {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n }\n\n .progress-bar-compact {\n width: 80px;\n height: 4px;\n background: var(--mj-border-default);\n border-radius: 2px;\n overflow: hidden;\n }\n\n .progress-fill-compact {\n height: 100%;\n background: var(--mj-brand-primary);\n transition: width 0.3s ease;\n }\n\n .progress-fill-compact.complete {\n background: var(--mj-status-success);\n }\n\n .progress-text-compact {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-muted);\n min-width: 30px;\n text-align: right;\n }\n\n .no-tasks {\n text-align: center;\n padding: 60px 20px;\n color: var(--mj-text-disabled);\n }\n\n .no-tasks i {\n font-size: 48px;\n opacity: 0.3;\n margin-bottom: 12px;\n }\n\n .no-tasks p {\n margin: 0;\n font-size: 14px;\n }\n "] }]
283
- }], null, { tasks: [{
355
+ }], null, { Tasks: [{
356
+ type: Input
357
+ }], tasks: [{
358
+ type: Input
359
+ }], AgentRunMap: [{
284
360
  type: Input
285
361
  }], agentRunMap: [{
286
362
  type: Input
363
+ }], TaskClicked: [{
364
+ type: Output
287
365
  }], taskClicked: [{
288
366
  type: Output
367
+ }], OpenEntityRecord: [{
368
+ type: Output
289
369
  }], openEntityRecord: [{
290
370
  type: Output
291
371
  }], handleResize: [{
@@ -1 +1 @@
1
- {"version":3,"file":"simple-task-viewer.component.js","sourceRoot":"","sources":["../../../src/lib/components/simple-task-viewer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, HostListener } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MJTaskEntity } from '@memberjunction/core-entities';\nimport { TaskDetailPanelComponent } from './task-detail-panel.component';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * Simple list view for tasks\n */\n@Component({\n selector: 'mj-simple-task-viewer',\n standalone: true,\n imports: [CommonModule, TaskDetailPanelComponent],\n template: `\n <div class=\"simple-task-viewer\">\n <div class=\"list-layout\">\n <div class=\"task-list\" [class.with-detail]=\"selectedTask\">\n @for (task of tasks; track task) {\n <div\n class=\"task-item\"\n [class.completed]=\"task.Status === 'Complete'\"\n [class.selected]=\"IsTaskSelected(task)\"\n (click)=\"onTaskClick(task)\">\n <!-- Status Icon -->\n <div class=\"status-icon\"\n [class.complete]=\"task.Status === 'Complete'\"\n [class.failed]=\"task.Status === 'Failed'\"\n [class.blocked]=\"task.Status === 'Blocked'\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon(task.Status)\"></i>\n </div>\n <!-- Task Content -->\n <div class=\"task-content\">\n <div class=\"task-header\">\n <div class=\"task-title-row\">\n <span class=\"task-title\" [class.completed-text]=\"task.Status === 'Complete'\">\n {{ task.Name }}\n @if (task.Status === 'Complete') {\n <i class=\"fas fa-check completed-check\"></i>\n }\n </span>\n <!-- Compact progress indicator for all tasks -->\n @if (task.PercentComplete != null) {\n <div class=\"task-progress-compact\">\n <div class=\"progress-bar-compact\">\n <div class=\"progress-fill-compact\"\n [style.width.%]=\"task.PercentComplete\"\n [class.complete]=\"task.Status === 'Complete'\"></div>\n </div>\n <span class=\"progress-text-compact\">{{ task.PercentComplete }}%</span>\n </div>\n }\n </div>\n <span class=\"task-meta\">\n @if (task.DueAt) {\n <span class=\"due-date\">\n <i class=\"far fa-calendar\"></i>\n {{ formatDate(task.DueAt) }}\n </span>\n }\n @if (task.User) {\n <span class=\"assigned-to\">\n <i class=\"far fa-user\"></i>\n {{ task.User }}\n </span>\n }\n </span>\n </div>\n </div>\n </div>\n }\n \n @if (!tasks || tasks.length === 0) {\n <div class=\"no-tasks\">\n <i class=\"fas fa-tasks\"></i>\n <p>No tasks to display</p>\n </div>\n }\n </div>\n \n @if (selectedTask) {\n <div class=\"list-resizer\"\n (mousedown)=\"startResize($event)\"></div>\n }\n \n @if (selectedTask) {\n <div class=\"task-detail-panel\" [style.width.px]=\"detailPanelWidth\">\n <mj-task-detail-panel\n [task]=\"selectedTask\"\n [agentRunId]=\"getAgentRunId(selectedTask)\"\n (closePanel)=\"closeDetailPanel()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-task-detail-panel>\n </div>\n }\n </div>\n </div>\n `,\n styles: [`\n .simple-task-viewer {\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .list-layout {\n display: flex;\n height: 100%;\n position: relative;\n }\n\n .task-list {\n flex: 1;\n min-width: 400px;\n padding: 16px;\n overflow-y: auto;\n }\n\n .task-list.with-detail {\n border-right: 1px solid var(--mj-border-default);\n }\n\n .list-resizer {\n width: 4px;\n background: var(--mj-border-default);\n cursor: col-resize;\n flex-shrink: 0;\n transition: background 0.2s;\n }\n\n .list-resizer:hover {\n background: var(--mj-brand-primary);\n }\n\n .task-detail-panel {\n min-width: 300px;\n max-width: 600px;\n height: 100%;\n flex-shrink: 0;\n }\n\n .task-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 8px;\n transition: all 0.2s;\n cursor: pointer;\n }\n\n .task-item:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n transform: translateY(-1px);\n }\n\n .task-item.selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-sm);\n }\n\n .task-item.completed {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n }\n\n .status-icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n flex-shrink: 0;\n }\n\n .status-icon.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n\n /* Failed and Blocked are distinct outcomes: Failed is this task's own error, Blocked\n means an upstream dependency can never be satisfied. Both previously rendered with\n the default (pending) treatment, so a dead graph looked like a waiting one. */\n .status-icon.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n\n .status-icon.blocked {\n background: color-mix(in srgb, var(--mj-text-muted) 15%, var(--mj-bg-surface));\n color: var(--mj-text-muted);\n }\n\n .task-content {\n flex: 1;\n min-width: 0;\n }\n\n .task-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 6px;\n }\n\n .task-title-row {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n }\n\n .task-title {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 14px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .task-title.completed-text {\n color: var(--mj-text-muted);\n text-decoration: line-through;\n text-decoration-thickness: 1.5px;\n }\n\n .completed-check {\n color: var(--mj-status-success);\n font-size: 12px;\n }\n\n .task-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n }\n\n .task-meta i {\n margin-right: 4px;\n }\n\n .task-description {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-bottom: 8px;\n line-height: 1.5;\n }\n\n .task-progress-compact {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n }\n\n .progress-bar-compact {\n width: 80px;\n height: 4px;\n background: var(--mj-border-default);\n border-radius: 2px;\n overflow: hidden;\n }\n\n .progress-fill-compact {\n height: 100%;\n background: var(--mj-brand-primary);\n transition: width 0.3s ease;\n }\n\n .progress-fill-compact.complete {\n background: var(--mj-status-success);\n }\n\n .progress-text-compact {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-muted);\n min-width: 30px;\n text-align: right;\n }\n\n .no-tasks {\n text-align: center;\n padding: 60px 20px;\n color: var(--mj-text-disabled);\n }\n\n .no-tasks i {\n font-size: 48px;\n opacity: 0.3;\n margin-bottom: 12px;\n }\n\n .no-tasks p {\n margin: 0;\n font-size: 14px;\n }\n `]\n})\nexport class SimpleTaskViewerComponent implements OnChanges {\n @Input() tasks: MJTaskEntity[] = [];\n @Input() agentRunMap?: Map<string, string>; // Maps TaskID -> AgentRunID\n @Output() taskClicked = new EventEmitter<MJTaskEntity>();\n @Output() openEntityRecord = new EventEmitter<{ entityName: string; recordId: string }>();\n\n public selectedTask: MJTaskEntity | null = null;\n\n public IsTaskSelected(task: MJTaskEntity): boolean {\n return UUIDsEqual(this.selectedTask?.ID, task.ID);\n }\n public detailPanelWidth: number = 400;\n\n private isResizing = false;\n private resizeStartX = 0;\n private resizeStartWidth = 0;\n\n ngOnChanges() {\n // Tasks are already loaded\n }\n\n public onTaskClick(task: MJTaskEntity): void {\n this.selectedTask = task;\n this.taskClicked.emit(task);\n }\n\n public getAgentRunId(task: MJTaskEntity): string | null {\n return this.agentRunMap?.get(task.ID) || null;\n }\n\n public closeDetailPanel(): void {\n this.selectedTask = null;\n }\n\n public onOpenEntityRecord(event: { entityName: string; recordId: string }): void {\n this.openEntityRecord.emit(event);\n }\n\n public startResize(event: MouseEvent): void {\n this.isResizing = true;\n this.resizeStartX = event.clientX;\n this.resizeStartWidth = this.detailPanelWidth;\n event.preventDefault();\n }\n\n @HostListener('document:mousemove', ['$event'])\n handleResize(event: MouseEvent): void {\n if (!this.isResizing) return;\n\n const delta = this.resizeStartX - event.clientX;\n const newWidth = this.resizeStartWidth + delta;\n\n // Constrain width between min and max\n this.detailPanelWidth = Math.max(300, Math.min(600, newWidth));\n }\n\n @HostListener('document:mouseup')\n stopResize(): void {\n this.isResizing = false;\n }\n\n public getStatusIcon(status: string): string {\n switch (status) {\n case 'Complete': return 'fa-check-circle';\n case 'In Progress': return 'fa-spinner';\n case 'Pending': return 'fa-clock';\n case 'Blocked': return 'fa-ban';\n case 'Failed': return 'fa-times-circle';\n default: return 'fa-circle';\n }\n }\n\n public formatDate(date: Date | null): string {\n if (!date) return '';\n const d = new Date(date);\n return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });\n }\n}\n"]}
1
+ {"version":3,"file":"simple-task-viewer.component.js","sourceRoot":"","sources":["../../../src/lib/components/simple-task-viewer.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnChanges, HostListener } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MJTaskEntity } from '@memberjunction/core-entities';\nimport { TaskDetailPanelComponent } from './task-detail-panel.component';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * Simple list view for tasks\n */\n@Component({\n selector: 'mj-simple-task-viewer',\n standalone: true,\n imports: [CommonModule, TaskDetailPanelComponent],\n template: `\n <div class=\"simple-task-viewer\">\n <div class=\"list-layout\">\n <div class=\"task-list\" [class.with-detail]=\"selectedTask\">\n @for (task of tasks; track task) {\n <div\n class=\"task-item\"\n [class.completed]=\"task.Status === 'Complete'\"\n [class.selected]=\"IsTaskSelected(task)\"\n (click)=\"onTaskClick(task)\">\n <!-- Status Icon -->\n <div class=\"status-icon\"\n [class.complete]=\"task.Status === 'Complete'\"\n [class.failed]=\"task.Status === 'Failed'\"\n [class.blocked]=\"task.Status === 'Blocked'\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon(task.Status)\"></i>\n </div>\n <!-- Task Content -->\n <div class=\"task-content\">\n <div class=\"task-header\">\n <div class=\"task-title-row\">\n <span class=\"task-title\" [class.completed-text]=\"task.Status === 'Complete'\">\n {{ task.Name }}\n @if (task.Status === 'Complete') {\n <i class=\"fas fa-check completed-check\"></i>\n }\n </span>\n <!-- Compact progress indicator for all tasks -->\n @if (task.PercentComplete != null) {\n <div class=\"task-progress-compact\">\n <div class=\"progress-bar-compact\">\n <div class=\"progress-fill-compact\"\n [style.width.%]=\"task.PercentComplete\"\n [class.complete]=\"task.Status === 'Complete'\"></div>\n </div>\n <span class=\"progress-text-compact\">{{ task.PercentComplete }}%</span>\n </div>\n }\n </div>\n <span class=\"task-meta\">\n @if (task.DueAt) {\n <span class=\"due-date\">\n <i class=\"far fa-calendar\"></i>\n {{ formatDate(task.DueAt) }}\n </span>\n }\n @if (task.User) {\n <span class=\"assigned-to\">\n <i class=\"far fa-user\"></i>\n {{ task.User }}\n </span>\n }\n </span>\n </div>\n </div>\n </div>\n }\n \n @if (!tasks || tasks.length === 0) {\n <div class=\"no-tasks\">\n <i class=\"fas fa-tasks\"></i>\n <p>No tasks to display</p>\n </div>\n }\n </div>\n \n @if (selectedTask) {\n <div class=\"list-resizer\"\n (mousedown)=\"startResize($event)\"></div>\n }\n \n @if (selectedTask) {\n <div class=\"task-detail-panel\" [style.width.px]=\"detailPanelWidth\">\n <mj-task-detail-panel\n [task]=\"selectedTask\"\n [agentRunId]=\"getAgentRunId(selectedTask)\"\n (closePanel)=\"closeDetailPanel()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-task-detail-panel>\n </div>\n }\n </div>\n </div>\n `,\n styles: [`\n .simple-task-viewer {\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .list-layout {\n display: flex;\n height: 100%;\n position: relative;\n }\n\n .task-list {\n flex: 1;\n min-width: 400px;\n padding: 16px;\n overflow-y: auto;\n }\n\n .task-list.with-detail {\n border-right: 1px solid var(--mj-border-default);\n }\n\n .list-resizer {\n width: 4px;\n background: var(--mj-border-default);\n cursor: col-resize;\n flex-shrink: 0;\n transition: background 0.2s;\n }\n\n .list-resizer:hover {\n background: var(--mj-brand-primary);\n }\n\n .task-detail-panel {\n min-width: 300px;\n max-width: 600px;\n height: 100%;\n flex-shrink: 0;\n }\n\n .task-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 8px;\n transition: all 0.2s;\n cursor: pointer;\n }\n\n .task-item:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n transform: translateY(-1px);\n }\n\n .task-item.selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-sm);\n }\n\n .task-item.completed {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n }\n\n .status-icon {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n flex-shrink: 0;\n }\n\n .status-icon.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n\n /* Failed and Blocked are distinct outcomes: Failed is this task's own error, Blocked\n means an upstream dependency can never be satisfied. Both previously rendered with\n the default (pending) treatment, so a dead graph looked like a waiting one. */\n .status-icon.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n\n .status-icon.blocked {\n background: color-mix(in srgb, var(--mj-text-muted) 15%, var(--mj-bg-surface));\n color: var(--mj-text-muted);\n }\n\n .task-content {\n flex: 1;\n min-width: 0;\n }\n\n .task-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 6px;\n }\n\n .task-title-row {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n }\n\n .task-title {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 14px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .task-title.completed-text {\n color: var(--mj-text-muted);\n text-decoration: line-through;\n text-decoration-thickness: 1.5px;\n }\n\n .completed-check {\n color: var(--mj-status-success);\n font-size: 12px;\n }\n\n .task-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n }\n\n .task-meta i {\n margin-right: 4px;\n }\n\n .task-description {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-bottom: 8px;\n line-height: 1.5;\n }\n\n .task-progress-compact {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n }\n\n .progress-bar-compact {\n width: 80px;\n height: 4px;\n background: var(--mj-border-default);\n border-radius: 2px;\n overflow: hidden;\n }\n\n .progress-fill-compact {\n height: 100%;\n background: var(--mj-brand-primary);\n transition: width 0.3s ease;\n }\n\n .progress-fill-compact.complete {\n background: var(--mj-status-success);\n }\n\n .progress-text-compact {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-muted);\n min-width: 30px;\n text-align: right;\n }\n\n .no-tasks {\n text-align: center;\n padding: 60px 20px;\n color: var(--mj-text-disabled);\n }\n\n .no-tasks i {\n font-size: 48px;\n opacity: 0.3;\n margin-bottom: 12px;\n }\n\n .no-tasks p {\n margin: 0;\n font-size: 14px;\n }\n `]\n})\nexport class SimpleTaskViewerComponent implements OnChanges {\n @Input() Tasks: MJTaskEntity[] = [];\n\n /** @deprecated Use {@link Tasks}. */\n @Input() set tasks(value: MJTaskEntity[]) {\n this.Tasks = value;\n }\n /** @deprecated Use {@link Tasks}. */\n get tasks(): MJTaskEntity[] {\n return this.Tasks;\n }\n @Input() AgentRunMap?: Map<string, string>;\n\n /** @deprecated Use {@link AgentRunMap}. */\n @Input() set agentRunMap(value: Map<string, string> | undefined) {\n this.AgentRunMap = value;\n }\n /** @deprecated Use {@link AgentRunMap}. */\n get agentRunMap(): Map<string, string> | undefined {\n return this.AgentRunMap;\n } // Maps TaskID -> AgentRunID\n @Output() TaskClicked = new EventEmitter<MJTaskEntity>();\n\n /**\n * @deprecated Use {@link TaskClicked}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (taskClicked) keeps working. Must stay AFTER TaskClicked: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() taskClicked = this.TaskClicked;\n @Output() OpenEntityRecord = new EventEmitter<{ entityName: string; recordId: string }>();\n\n /**\n * @deprecated Use {@link OpenEntityRecord}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() openEntityRecord = this.OpenEntityRecord;\n\n public SelectedTask: MJTaskEntity | null = null;\n\n /** @deprecated Use {@link SelectedTask}. */\n public get selectedTask(): MJTaskEntity | null {\n return this.SelectedTask;\n }\n /** @deprecated Use {@link SelectedTask}. */\n public set selectedTask(value: MJTaskEntity | null) {\n this.SelectedTask = value;\n }\n\n public IsTaskSelected(task: MJTaskEntity): boolean {\n return UUIDsEqual(this.SelectedTask?.ID, task.ID);\n }\n public DetailPanelWidth: number = 400;\n\n /** @deprecated Use {@link DetailPanelWidth}. */\n public get detailPanelWidth(): number {\n return this.DetailPanelWidth;\n }\n /** @deprecated Use {@link DetailPanelWidth}. */\n public set detailPanelWidth(value: number) {\n this.DetailPanelWidth = value;\n }\n\n private isResizing = false;\n private resizeStartX = 0;\n private resizeStartWidth = 0;\n\n ngOnChanges() {\n // Tasks are already loaded\n }\n\n public OnTaskClick(task: MJTaskEntity): void {\n this.SelectedTask = task;\n this.TaskClicked.emit(task);\n }\n\n /** @deprecated Use {@link OnTaskClick}. */\n public onTaskClick(task: MJTaskEntity): void {\n return this.OnTaskClick(task);\n }\n\n public GetAgentRunId(task: MJTaskEntity): string | null {\n return this.AgentRunMap?.get(task.ID) || null;\n }\n\n /** @deprecated Use {@link GetAgentRunId}. */\n public getAgentRunId(task: MJTaskEntity): string | null {\n return this.GetAgentRunId(task);\n }\n\n public CloseDetailPanel(): void {\n this.SelectedTask = null;\n }\n\n /** @deprecated Use {@link CloseDetailPanel}. */\n public closeDetailPanel(): void {\n return this.CloseDetailPanel();\n }\n\n public OnOpenEntityRecord(event: { entityName: string; recordId: string }): void {\n this.OpenEntityRecord.emit(event);\n }\n\n /** @deprecated Use {@link OnOpenEntityRecord}. */\n public onOpenEntityRecord(event: { entityName: string; recordId: string }): void {\n return this.OnOpenEntityRecord(event);\n }\n\n public StartResize(event: MouseEvent): void {\n this.isResizing = true;\n this.resizeStartX = event.clientX;\n this.resizeStartWidth = this.DetailPanelWidth;\n event.preventDefault();\n }\n\n /** @deprecated Use {@link StartResize}. */\n public startResize(event: MouseEvent): void {\n return this.StartResize(event);\n }\n\n @HostListener('document:mousemove', ['$event'])\n handleResize(event: MouseEvent): void {\n if (!this.isResizing) return;\n\n const delta = this.resizeStartX - event.clientX;\n const newWidth = this.resizeStartWidth + delta;\n\n // Constrain width between min and max\n this.DetailPanelWidth = Math.max(300, Math.min(600, newWidth));\n }\n\n @HostListener('document:mouseup')\n stopResize(): void {\n this.isResizing = false;\n }\n\n public GetStatusIcon(status: string): string {\n switch (status) {\n case 'Complete': return 'fa-check-circle';\n case 'In Progress': return 'fa-spinner';\n case 'Pending': return 'fa-clock';\n case 'Blocked': return 'fa-ban';\n case 'Failed': return 'fa-times-circle';\n default: return 'fa-circle';\n }\n }\n\n /** @deprecated Use {@link GetStatusIcon}. */\n public getStatusIcon(status: string): string {\n return this.GetStatusIcon(status);\n }\n\n public formatDate(date: Date | null): string {\n if (!date) return '';\n const d = new Date(date);\n return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });\n }\n}\n"]}
@@ -7,21 +7,54 @@ import * as i0 from "@angular/core";
7
7
  * Reusable across list and Gantt views
8
8
  */
9
9
  export declare class TaskDetailPanelComponent implements OnInit, OnChanges {
10
- task: MJTaskEntity;
10
+ Task: MJTaskEntity;
11
+ /** @deprecated Use {@link Task}. */
12
+ set task(value: MJTaskEntity);
13
+ /** @deprecated Use {@link Task}. */
14
+ get task(): MJTaskEntity;
11
15
  agentRunId: string | null;
16
+ ClosePanel: EventEmitter<void>;
17
+ /**
18
+ * @deprecated Use {@link ClosePanel}.
19
+ *
20
+ * The same emitter under the old binding name, so a template still binding
21
+ * (closePanel) keeps working. Must stay AFTER ClosePanel: class fields
22
+ * initialise in order, and the other way round this captures undefined.
23
+ */
12
24
  closePanel: EventEmitter<void>;
25
+ OpenEntityRecord: EventEmitter<{
26
+ entityName: string;
27
+ recordId: string;
28
+ }>;
29
+ /**
30
+ * @deprecated Use {@link OpenEntityRecord}.
31
+ *
32
+ * The same emitter under the old binding name, so a template still binding
33
+ * (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields
34
+ * initialise in order, and the other way round this captures undefined.
35
+ */
13
36
  openEntityRecord: EventEmitter<{
14
37
  entityName: string;
15
38
  recordId: string;
16
39
  }>;
17
- agent: MJAIAgentEntityExtended | null;
40
+ Agent: MJAIAgentEntityExtended | null;
41
+ /** @deprecated Use {@link Agent}. */
42
+ get agent(): MJAIAgentEntityExtended | null;
43
+ /** @deprecated Use {@link Agent}. */
44
+ set agent(value: MJAIAgentEntityExtended | null);
18
45
  ngOnInit(): void;
19
46
  ngOnChanges(): void;
20
47
  private loadAgentInfo;
48
+ FormatDateTime(date: Date | null): string;
49
+ /** @deprecated Use {@link FormatDateTime}. */
21
50
  formatDateTime(date: Date | null): string;
51
+ OpenAgent(): void;
52
+ /** @deprecated Use {@link OpenAgent}. */
22
53
  openAgent(): void;
54
+ OpenAgentRun(): void;
55
+ /** @deprecated Use {@link OpenAgentRun}. */
23
56
  openAgentRun(): void;
24
57
  static ɵfac: i0.ɵɵFactoryDeclaration<TaskDetailPanelComponent, never>;
25
- static ɵcmp: i0.ɵɵComponentDeclaration<TaskDetailPanelComponent, "mj-task-detail-panel", never, { "task": { "alias": "task"; "required": false; }; "agentRunId": { "alias": "agentRunId"; "required": false; }; }, { "closePanel": "closePanel"; "openEntityRecord": "openEntityRecord"; }, never, never, true, never>;
58
+ static ɵcmp: i0.ɵɵComponentDeclaration<TaskDetailPanelComponent, "mj-task-detail-panel", never, { "Task": { "alias": "Task"; "required": false; }; "task": { "alias": "task"; "required": false; }; "agentRunId": { "alias": "agentRunId"; "required": false; }; }, { "ClosePanel": "ClosePanel"; "closePanel": "closePanel"; "OpenEntityRecord": "OpenEntityRecord"; "openEntityRecord": "openEntityRecord"; }, never, never, true, never>;
26
59
  }
27
60
  //# sourceMappingURL=task-detail-panel.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"task-detail-panel.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/task-detail-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1F,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;;AAGvE;;;GAGG;AACH,qBA8Pa,wBAAyB,YAAW,MAAM,EAAE,SAAS;IACvD,IAAI,EAAG,YAAY,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,UAAU,qBAA4B;IACtC,gBAAgB;oBAAkC,MAAM;kBAAY,MAAM;OAAM;IAEnF,KAAK,EAAE,uBAAuB,GAAG,IAAI,CAAQ;IAEpD,QAAQ,IAAI,IAAI;IAIhB,WAAW,IAAI,IAAI;YAIL,aAAa;IAYpB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM;IAYzC,SAAS,IAAI,IAAI;IASjB,YAAY,IAAI,IAAI;yCAjDhB,wBAAwB;2CAAxB,wBAAwB;CAyDpC"}
1
+ {"version":3,"file":"task-detail-panel.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/task-detail-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1F,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;;AAGvE;;;GAGG;AACH,qBA8Pa,wBAAyB,YAAW,MAAM,EAAE,SAAS;IACvD,IAAI,EAAG,YAAY,CAAC;IAE7B,oCAAoC;IACpC,IAAa,IAAI,CAAC,KAAK,EAAE,YAAY,EAEpC;IACD,oCAAoC;IACpC,IAAI,IAAI,IAAI,YAAY,CAEvB;IACQ,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,UAAU,qBAA4B;IAEhD;;;;;;OAMG;IACO,UAAU,qBAAmB;IAC7B,gBAAgB;oBAAkC,MAAM;kBAAY,MAAM;OAAM;IAE1F;;;;;;OAMG;IACO,gBAAgB;oBATkC,MAAM;kBAAY,MAAM;OASjC;IAE5C,KAAK,EAAE,uBAAuB,GAAG,IAAI,CAAQ;IAEpD,qCAAqC;IACrC,IAAW,KAAK,IAAI,uBAAuB,GAAG,IAAI,CAEjD;IACD,qCAAqC;IACrC,IAAW,KAAK,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,EAErD;IAED,QAAQ,IAAI,IAAI;IAIhB,WAAW,IAAI,IAAI;YAIL,aAAa;IAYpB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM;IAYhD,8CAA8C;IACvC,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM;IAIzC,SAAS,IAAI,IAAI;IASxB,yCAAyC;IAClC,SAAS,IAAI,IAAI;IAIjB,YAAY,IAAI,IAAI;IAS3B,4CAA4C;IACrC,YAAY,IAAI,IAAI;yCAzGhB,wBAAwB;2CAAxB,wBAAwB;CA4GpC"}