[pages] Paginate My Checks, migrate pages and add a burndown view - #2192
Merged
Conversation
Convert the page to script setup: Vuex getters as computeds, actions through store.dispatch, head() replaced by useHead, sectioned layout with sorted imports. Clean pass: the filter chain becomes a single functional predicate, the duplicated due-date comparator and thenBy tail are factored out, the three near-identical filter-list builders collapse into one taskEntities helper, and the arg-ignoring buildSelectionGrid wrapper is inlined. Dead CSS removed (.push-right, duplicated .data-list). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rework the page on the AllTasks model: filters (production, episode, task type, feedback status, person, due week) are sent to the paginated tasks-to-check route, results load page by page with a load more button, and the header count and footer totals come from the response stats instead of the loaded subset. A first request on the new filter-values route restricts every combo to the values actually present in the pool. The build playlist button shows a loaded/total indicator with an explanatory tooltip when the list is partial (new my_checks.build_playlist_loaded_only key, translated in all locales). The list itself moves to a dedicated ToCheckList component modeled on AllTaskList (selection, inline estimation and due date editing, load more, stats footer) instead of piggybacking on TodosList. Filter combos are pixel-aligned on a single control height, verified on the live page. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
My Checks now renders through its own ToCheckList component, so the isToCheck prop and its eleven template branches (assignees column, hidden description and start date, metadata guard, burned-estimation highlight) no longer have any consumer. TodosList goes back to being the plain todos/done list used by the Todos and Person pages. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert AllTasks and AllTaskList to script setup: getters as computeds, dispatches, useHead, socket task:update rebound through socket.on/off, mixins replaced by useFormat and the dom composable. Clean pass: unused getters, actions, data and methods removed (nbFrames, getTaskName, getDate, setScrollPosition, dead template refs, ten dead CSS selectors), the click guard copied from TodosList that matched nothing in this template dropped, alt-arrow navigation rewritten with a wrap-around modulo, stats prop default fixed to a real object, route query read at state init so filtered URLs no longer trigger a double load, and loadMore only bumps the page on success. Two migration-borne fixes: the avatar menu called a missing onUnassign handler (now dispatches unassignPersonFromTask), and the statusStats computed would have shadowed the StatusStats component tag (renamed statusStatsList). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
When the real costs view is active, the exported CSV now mirrors the on-screen columns: real cost per past month, real total, estimated so far and gap, estimated future months, remaining, real + remaining, estimated total and final gap. The expense computations (converted expenses, done and remaining previsional, extended departments) move from BudgetList to Budget so the export and the table share the same data. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B6ryRZGB1SLWdwD4wrw8Uj
SquareGrid moves to script setup with typed props. Origami was only reachable through Spinner's isStylish prop, which no component ever passes, so the file, the import and the prop are removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Standard script setup conversion. The hardDeleteTextComputed and hardDeleteLockTextComputed computeds become hardDeleteMessage and hardDeleteLockMessage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The composable returned the raw lib formatDate while the legacy mixin wraps it with the dateFormat and use12HourClock getters, so any migrated consumer would silently lose the user's date preferences. The reactive bundle now wraps it the same way (the pure named export stays raw) and exposes use12HourClock. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert both components to script setup: socket events rebound through named on/off handlers, template refs via useTemplateRef, useHead, and defineExpose on focusMessageBox so the parent ref call keeps working. Clean pass on the page: the chat list comparator returned a boolean (the list was barely sorted), it now orders by newest message first with a name tiebreaker; selectFirstChat picks the top of the sorted list; the mounted branch collapses into selectFromQuery which already falls back. On the chat itself: unused domMixin dropped, dead add-attachment-modal ref removed, entity prop default fixed to null, and the undeclared messageToDeleteId instance property becomes an explicit local. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert the page to script setup with the usual transforms and merge its two inconsistent silent flags into a single guard (the $options.silent one was never read by the watchers). The mounted block disappears: the production and studio refs read the route query at init, which also removes the double fetch on query-carrying URLs, and loadRoute now syncs the combobox strings so they follow browser history navigation. Clean pass: phantom weekString dropped, detail and unit options become locale-reactive computeds, currentPerson derives from the route, the filteredPeople do/while turns into a some(), and the router.push watcher blocks collapse onto the timesheets-<level> route names. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The table used auto layout, so column widths were recomputed from the cell contents at every reload (the tbody unmounts while loading) and jittered on each month or filter change. Fixed layout sizes them from the header row once, with overflow hidden on the name column. Cell durations go through a single cellDuration helper that rounds to at most two decimals without padding: the hour unit was not rounded at all (1.6666666666666667 for 100 minutes), the day unit showed padded zeros, and empty cells in day unit rendered NaN because '-' went through the hoursToDays division. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The timesheet table can now be dragged to scroll, wired like PeopleList (grabListMixin plus domMixin and the document move/stop listeners the mixin expects its host to register). Side panel: the duration column gets real room (flexible name column instead of a fixed 300px squeezing it), durations are rounded to one decimal in both units like the main grid, the nested paddings that stacked up around the table are removed, and the panel itself breathes more (1.5em top and sides). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ComboboxStudio deviated on both metrics of the centered header row: its label takes a 5px padding-top under the field class and its control renders 38px tall against 42px for its neighbors, so the row staggered it. Two page-scoped rules pin the label metrics and the control height, verified pixel-identical on the live page. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add a window keydown listener to PeopleTimesheetInfo that pushes the same closeRoute as the close button, keeping the URL in sync at every detail level. Remove the dead close emit and its unused parent handler. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert MainSchedule to script setup: getters as computeds, dispatch calls, useHead, and a scheduleRef template ref for the today scroll. zoomOptions becomes a computed so labels react to locale changes. Clean up on the way: drop the unused user getter, the never-mutated loading/errors flags (the template passes false explicitly since the Schedule widget defaults isLoading to true), the dead overall-man-days CSS and the stale header comment. Factor the two item converters around a shared toScheduleItem helper, inline the single-caller init and updateRoute bodies, and rewrite expandProductionElement with async/await. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The ComboboxNumber select renders 3em while Bulma fixes its select and control wrappers at 2.5em, so the flex child was shorter than the date blocks and the row centering shifted it, roughly compensated by an old margin-top hack. Pin the three levels to the 40px date-field input height instead; verified pixel-identical on the live row. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert Budget.vue to script setup: pageMixin becomes useHead, the socket events option becomes socket.on/off in the lifecycle hooks, and the Vuex maps become computed getters and store.dispatch calls. Clean up along the way: the computeds no longer mutate the store entries or each other's results, the eight loading/error wrappers share a runRequest helper, monthsBetweenProductionDates is derived from the production instead of reset by hand, the independent mount requests run in parallel and the duplicate entries request on mount is gone. Dead state (editBudget flags, department start_date/duration) is removed and the undeclared budgetEntryToDelete and createBudgetEntry flags are declared. The hard-delete modal now reads loading.deleteBudget (the template pointed at a key that never existed). Budget entries with a null exceptions field are normalised once when they enter state so BudgetList's in-place exception edits stay reactive. getMonthCost moves to src/lib/budget.js and replaces the copy in BudgetPersonRow. Co-Authored-By: Claude <noreply@anthropic.com>
Add a pressed toggle button at the right of the filter row that swaps the task list for a burndown chart, persisted in the URL as view=burndown and reloaded on every filter change. The data comes from the new open-tasks/burndown zou aggregate so the chart covers the whole filtered set, not only the loaded pages. The chart lives in a dedicated reusable BurndownChart widget: remaining tasks curve extended flat to today, dashed ideal line between the first start date and the last due date, and an estimations switch that turns the y axis into remaining man-days. Rendered with the chartkick setup already used by the budget pages. New burndown i18n keys are translated in all locales. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Measured on the live rows: the studio and department combos rendered a 38px control against the 42px of the Bulma selects and the person multiselect, the status and task-type labels carried a 5px padding-top the other labels lack (roughly compensated by an old 7px padding hack on the production combobox) and the status combo added its own 1px margin-top. Pin the two short combos to 42px, normalize the labels page-scoped and drop the two stray offsets; verified pixel-identical on the live rows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chart was squashed to 150px, the ideal line never drew and dark mode kept illegible defaults. Root causes: the page had no definite height for the flex chain, and chartkick pads every series with nulls on the merged x axis while its spanGaps default breaks lines there, which also cut the remaining curve into pieces on filtered views. Fix the height, span the gaps on all series, and keep the previous chart mounted during reloads since recreating the canvas mid layout could stall the first paint. Visual pass in the Kitsu language: gradient area fill under a thinner curve, HTML legend chips with the estimations toggle, rounded panel, theme-pinned canvas colors driven by the isDarkTheme getter, localized thousands separators from the browser locale like formatDuration, and a dashed today marker with a light wash over the future zone (small gated chart.js plugin, inert for the budget charts). The chart now ends at the schedule end instead of stretching to today when the production is over, the ideal anchors on the earliest of the schedule start and first activity and stays flat at zero when the chart runs past the deadline, and a dashed green projection extends the curve at the observed average velocity. The list recap moves to a TasksStatsLine widget shown under both views. New burndown.projection key translated in all locales. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert BudgetList.vue to script setup: the dom and grab-list mixins plus the hand-written document event table become useGrabList, and the Vuex maps become computed getters. The preference key is a single computed instead of being rebuilt in two places. Simplify the list's contract with its rows: the seven bindings repeated on all five row components collapse into one commonRowProps v-bind, BudgetDepartmentRow emits toggle-department and takes a boolean is-collapsed instead of a function prop and the whole map, the department and person rows read their store maps directly, and the two dead props on BudgetTotalRow are gone. Person rows are keyed on the budget entry or person id so expense-only persons no longer share a null key. The salary exception edit moves up to Budget.vue, which owns the entries: it replaces the entry's exceptions object and goes through runRequest like every other write, which drops the currentBudget prop and the in-place mutation of computed-derived person objects. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Solution
Depends on cgwire/zou#1205.