Spaces:
Running
Running
| class TimelineTasks extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.render(); | |
| } | |
| render() { | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| background: #1f2937; | |
| border-left: 1px solid #374151; | |
| height: 100%; | |
| width: 300px; | |
| position: fixed; | |
| right: 0; | |
| top: 80px; | |
| overflow-y: auto; | |
| padding: 1rem; | |
| } | |
| h3 { | |
| margin-top: 0; | |
| color: #f97316; | |
| padding-bottom: 1rem; | |
| border-bottom: 1px solid #374151; | |
| } | |
| .task-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| } | |
| .task-item { | |
| background: #374151; | |
| border-radius: 6px; | |
| padding: 8px; | |
| cursor: grab; | |
| transition: all 0.2s ease; | |
| } | |
| .task-item:hover { | |
| background: #4b5563; | |
| transform: translateX(-4px); | |
| } | |
| .task-title { | |
| font-size: 14px; | |
| margin-bottom: 4px; | |
| } | |
| .task-time { | |
| font-size: 12px; | |
| color: #9ca3af; | |
| } | |
| </style> | |
| <h3>Timeline</h3> | |
| <div class="task-list" id="timeline-task-list"></div> | |
| `; | |
| } | |
| updateTasks(tasks) { | |
| const container = this.shadowRoot.getElementById('timeline-task-list'); | |
| container.innerHTML = tasks.map(task => ` | |
| <div class="task-item" draggable="true" data-task-id="${task.id}"> | |
| <div class="task-title">${task.title}</div> | |
| <div class="task-time">${formatTime(task.estimatedTime)}</div> | |
| </div> | |
| `).join(''); | |
| } | |
| } | |
| customElements.define('timeline-tasks', TimelineTasks); | |
| function formatTime(minutes) { | |
| const h = Math.floor(minutes / 60); | |
| const m = minutes % 60; | |
| return `${h}h ${m}m`; | |
| } |