import { api } from '../../lib/api.mjs'; const PRIORITIES = ['low', 'normal', 'high', 'urgent']; class ProfileForm extends HTMLElement { #onSave = null; connectedCallback() { if (!this.shadowRoot) { this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = ``; } } open(profile, onSave) { this.#onSave = onSave; const isEdit = !!profile; const d = this.shadowRoot.querySelector('dialog'); d.innerHTML = `
${isEdit ? 'Edit Profile' : 'New Profile'}
${isEdit ? `
Active
` : ''}
Default Steps
${(profile?.steps || []).length === 0 ? '
No steps yet — add steps below
' : (profile?.steps || []).map((s, i) => this.#stepRowHTML(s, i)).join('')}
`; if (window.lucide) lucide.createIcons({ root: d }); // Local step state (not saved until the profile save) const profileId = profile?.id || null; let pendingSteps = (profile?.steps || []).map(s => ({ ...s })); const renderSteps = () => { const list = d.querySelector('#step-list'); const empty = pendingSteps.length === 0; list.innerHTML = empty ? '
No steps yet — add steps below
' : pendingSteps.map((s, i) => this.#stepRowHTML(s, i)).join(''); list.querySelectorAll('.step-title-input').forEach((inp, i) => { inp.addEventListener('input', () => { pendingSteps[i].title = inp.value; }); inp.addEventListener('change', () => { pendingSteps[i].title = inp.value; }); }); list.querySelectorAll('.step-req-check').forEach((cb, i) => { cb.addEventListener('change', () => { pendingSteps[i].required = cb.checked; }); }); list.querySelectorAll('.step-del').forEach((btn, i) => { btn.addEventListener('click', () => { pendingSteps.splice(i, 1); renderSteps(); }); }); }; renderSteps(); d.querySelector('#add-step-btn').addEventListener('click', () => { const inp = d.querySelector('#new-step-title'); const title = inp.value.trim(); if (!title) { inp.focus(); return; } pendingSteps.push({ id: null, step_order: pendingSteps.length + 1, title, description: '', required: true }); inp.value = ''; renderSteps(); }); d.querySelector('#new-step-title').addEventListener('keydown', e => { if (e.key === 'Enter') { e.preventDefault(); d.querySelector('#add-step-btn').click(); } }); d.querySelector('#dlg-close').addEventListener('click', () => d.close()); d.querySelector('#dlg-cancel').addEventListener('click', () => d.close()); d.querySelector('#dlg-save').addEventListener('click', async () => { const name = d.querySelector('#p-name').value.trim(); const errEl = d.querySelector('#form-error'); if (!name) { errEl.textContent = 'Name is required'; d.querySelector('#p-name').focus(); return; } errEl.textContent = ''; const saveBtn = d.querySelector('#dlg-save'); saveBtn.disabled = true; saveBtn.textContent = 'Saving…'; const payload = { name, description: d.querySelector('#p-desc').value.trim(), category: d.querySelector('#p-cat').value.trim(), default_priority: d.querySelector('#p-pri').value, default_duration_hours: d.querySelector('#p-dur').value ? +d.querySelector('#p-dur').value : null, default_instructions: d.querySelector('#p-instr').value.trim(), active: isEdit ? d.querySelector('#p-active').checked : true, }; try { let savedProfile; if (isEdit) { savedProfile = await api.put(`/profiles/${profile.id}`, payload); } else { savedProfile = await api.post('/profiles', payload); } // Sync steps: delete removed, update existing, create new const savedId = savedProfile.id; const origIds = new Set((profile?.steps || []).map(s => s.id)); // Delete removed for (const orig of (profile?.steps || [])) { if (!pendingSteps.find(s => s.id === orig.id)) { await api.delete(`/profiles/${savedId}/steps/${orig.id}`); } } // Update or create, re-assigning order for (let i = 0; i < pendingSteps.length; i++) { const s = pendingSteps[i]; const stepPayload = { title: s.title, description: s.description || '', required: s.required !== false, step_order: i + 1 }; if (s.id && origIds.has(s.id)) { await api.put(`/profiles/${savedId}/steps/${s.id}`, stepPayload); } else { await api.post(`/profiles/${savedId}/steps`, stepPayload); } } d.close(); window.dispatchEvent(new CustomEvent('wo:toast', { detail: { message: isEdit ? 'Profile updated' : 'Profile created', type: 'success' } })); this.#onSave?.(); } catch (err) { errEl.textContent = err.message; saveBtn.disabled = false; saveBtn.textContent = isEdit ? 'Save Changes' : 'Create Profile'; } }); d.showModal(); d.querySelector('#p-name').focus(); } #stepRowHTML(s, i) { return `
${i + 1}
`; } #esc(s) { return (s || '').replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); } } customElements.define('profile-form', ProfileForm);