/** * Tasks — Surface Entry Point (v0.1.0) * * Task management surface using the v0.2.3 SDK: * sw.api.ext('tasks') — scoped API client * sw.ui.* — primitive components * sw.slots — statusbar widget * sw.actions — create-task action */ (async function () { 'use strict'; var mount = document.getElementById('extension-mount'); if (!mount) return; var base = window.__BASE__ || ''; var ver = window.__VERSION__ || '0'; // ── Boot SDK ─────────────────────────────── try { if (!window.preact) { var { h, render } = await import(base + '/js/sw/vendor/preact.module.js'); var hooksModule = await import(base + '/js/sw/vendor/hooks.module.js'); var htmModule = await import(base + '/js/sw/vendor/htm.module.js'); window.preact = { h, render }; window.hooks = hooksModule; window.html = htmModule.default.bind(h); } var sdk = await import(base + '/js/sw/sdk/index.js?v=' + ver); await sdk.boot(); } catch (e) { mount.innerHTML = '
SDK boot failed: ' + e.message + '
'; return; } var { html } = window; var { useState, useEffect, useCallback, useRef } = hooks; var { render } = preact; // ── SDK modules ──────────────────────────── var api = sw.api.ext('tasks'); var { Button, FormField, Dialog, Spinner, Dropdown, Tabs, Banner } = sw.ui; // ── Constants ────────────────────────────── var STATUSES = ['todo', 'in_progress', 'done', 'cancelled']; var PRIORITIES = ['low', 'medium', 'high', 'urgent']; var STATUS_LABELS = { todo: 'To Do', in_progress: 'In Progress', done: 'Done', cancelled: 'Cancelled' }; var PRIORITY_COLORS = { low: 'var(--text-3)', medium: 'var(--accent)', high: 'var(--warning)', urgent: 'var(--danger)' }; // ═══════════════════════════════════════════ // TaskForm — create / edit dialog // ═══════════════════════════════════════════ function TaskForm({ task, onSave, onClose }) { var [title, setTitle] = useState(task ? task.title : ''); var [desc, setDesc] = useState(task ? task.description : ''); var [status, setStatus] = useState(task ? task.status : STATUSES[0]); var [priority, setPriority] = useState(task ? task.priority : 'medium'); var [dueDate, setDueDate] = useState(task ? task.due_date : ''); var [tags, setTags] = useState(task ? task.tags : ''); var [saving, setSaving] = useState(false); var [error, setError] = useState(''); async function handleSubmit(e) { e.preventDefault(); if (!title.trim()) { setError('Title is required'); return; } setSaving(true); setError(''); try { var data = { title: title.trim(), description: desc, status, priority, due_date: dueDate, tags }; if (task) { await api.put('/items/' + task.id, data); } else { await api.post('/items', data); } onSave(); } catch (err) { setError(err.message || 'Save failed'); } finally { setSaving(false); } } return html` <${Dialog} open onClose=${onClose} title=${task ? 'Edit Task' : 'New Task'}> /> `; } // ═══════════════════════════════════════════ // TaskList — filterable task table // ═══════════════════════════════════════════ function TaskList({ items, loading, onEdit, onRefresh }) { var [filter, setFilter] = useState('all'); var filtered = items; if (filter !== 'all') { filtered = items.filter(function(t) { return t.status === filter; }); } async function handleDelete(id) { if (!confirm('Delete this task?')) return; await api.del('/items/' + id); onRefresh(); } async function handleQuickStatus(id, newStatus) { await api.put('/items/' + id, { status: newStatus }); onRefresh(); } return html`