/** * GoingsOn - Saved Views Module * * Save, apply, pin, and delete named presets of the task-list filters. Wired to the * "Save View" menu item (Cmd/Ctrl+S). Tasks view only (Run #27 UX remediation: the * backend commands shipped with no frontend). The DOM task filters map onto the * backend `ViewFilters`; the milestone filter is not part of a saved view. */ (function() { 'use strict'; const esc = GoingsOn.utils.escapeHtml; const escAttr = GoingsOn.utils.escapeAttrValue; const escArg = GoingsOn.utils.escapeHandlerArg; // DOM single-value filter controls <-> backend ViewFilters (Vec-valued) enums. const STATUS_TO_ENUM = { pending: 'Pending', started: 'Started', completed: 'Completed' }; const ENUM_TO_STATUS = { Pending: 'pending', Started: 'started', Completed: 'completed' }; const PRIORITY_TO_ENUM = { H: 'High', M: 'Medium', L: 'Low' }; const ENUM_TO_PRIORITY = { High: 'H', Medium: 'M', Low: 'L' }; // Last-listed views, so the inline onclick handlers can resolve by id. let viewCache = []; /** Map the current task filter DOM controls to a backend ViewFilters object. */ function currentFiltersToViewFilters() { const f = GoingsOn.tasks.getFilters(); const vf = {}; if (f.status && STATUS_TO_ENUM[f.status]) vf.status = [STATUS_TO_ENUM[f.status]]; if (f.projectId) vf.projectId = f.projectId; if (f.priority && PRIORITY_TO_ENUM[f.priority]) vf.priority = [PRIORITY_TO_ENUM[f.priority]]; if (f.showSnoozed) vf.isSnoozed = true; if (f.waitingOnly) vf.isWaiting = true; return vf; } /** Apply a saved view's filters back onto the task filter DOM, then reload. */ function applyView(view) { if (!view) return; const vf = view.filters || {}; const setVal = (id, val) => { const el = document.getElementById(id); if (el) el.value = val; }; const setChk = (id, val) => { const el = document.getElementById(id); if (el) el.checked = !!val; }; const status = Array.isArray(vf.status) && vf.status.length ? (ENUM_TO_STATUS[vf.status[0]] || '') : ''; const priority = Array.isArray(vf.priority) && vf.priority.length ? (ENUM_TO_PRIORITY[vf.priority[0]] || '') : ''; setVal('filter-status', status); setVal('filter-project', vf.projectId || ''); setVal('filter-priority', priority); setVal('filter-milestone', ''); setChk('filter-snoozed', vf.isSnoozed); setChk('filter-waiting', vf.isWaiting); GoingsOn.ui.closeModal(); GoingsOn.tasks.applyFilters(); GoingsOn.ui.showToast(`Applied view "${view.name}"`, 'success'); } /** Build the modal markup: a save row, then the list of existing views. */ function buildModalHtml() { let html = `
No saved views yet. Set your task filters, then save them here.
`; } html += `