/** * GoingsOn - Tasks Module * Task CRUD, subtasks, annotations, event handlers. * Form definitions live in task-forms.js. * Board/view mode live in task-board.js. * Filter/sort/pagination/selection live in tasks-filter.js. * Row rendering lives in tasks-render.js. */ // ============ Tasks Module ============ (function() { 'use strict'; const esc = GoingsOn.utils.escapeHtml; const escAttr = GoingsOn.utils.escapeAttr; // ============ Task Selection & Pagination ============ const taskSelection = new GoingsOn.SelectionManager('task', '#task-list-container', 'task-bulk-actions'); const taskPagination = new GoingsOn.PaginationManager('task', GoingsOn.state.itemsPerPage); // Virtual scroller instance let taskScroller = null; // ============ Delegated references ============ const getTaskFormFields = (...args) => GoingsOn.taskForms.getTaskFormFields(...args); const setupMilestoneSelect = (...args) => GoingsOn.taskForms.setupMilestoneSelect(...args); const renderTaskBadges = (...args) => GoingsOn.tasksRender.renderTaskBadges(...args); const formatRecurrence = (...args) => GoingsOn.tasksRender.formatRecurrence(...args); const renderTaskRow = (...args) => GoingsOn.tasksRender.renderTaskRow(...args); const renderSubtasksModal = (...args) => GoingsOn.tasksRender.renderSubtasksModal(...args); // ============ Core Functions ============ /** * Load and render the task list for the current view mode (list or board). */ async function load() { if (GoingsOn.cache.isFresh('tasks')) return; GoingsOn.tasksFilter.populateProjectFilter(); // Phase 7 Tier 4 — restore filter state from URL on every load. This // makes reload, deep-link, and back-button preserve the user's view. // populateProjectFilter must run first so the project