feat(ui): add ascending/descending toggle to work-item ordering - #269
Conversation
The saved-view order-by control only offered single-direction sorts. Adds an ascending/descending toggle: orderDirection is persisted with the rest of the display settings and threaded through sortIssuesByOrder, where descending is the ascending result reversed so the toggle behaves the same for every order key. ViewDetailPage now reuses the shared sorter instead of its own copy. Closes Devlaner#181 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds an ascending/descending order direction setting to saved views. Extends ChangesOrder Direction Feature
Estimated code review effort: 2 (Simple) | ~12 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant ProjectSavedViewDisplayDropdown
participant SavedViewSettings as projectSavedViewDisplay
participant ViewDetailPage
participant sortIssuesByOrder
User->>ProjectSavedViewDisplayDropdown: Click direction button (asc/desc)
ProjectSavedViewDisplayDropdown->>SavedViewSettings: update settings.orderDirection
SavedViewSettings->>SavedViewSettings: serializeSettings() persists orderDirection
ViewDetailPage->>SavedViewSettings: read settings.orderDirection
ViewDetailPage->>sortIssuesByOrder: sortIssuesByOrder(list, orderBy, orderDirection)
sortIssuesByOrder->>sortIssuesByOrder: sortAscending(list, orderBy)
sortIssuesByOrder-->>ViewDetailPage: return ordered/reversed list
ViewDetailPage-->>User: render grouped, ordered issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
apps/web/src/components/project-saved-view/ProjectSavedViewDisplayDropdown.tsx (1)
265-285: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSolid implementation with correct accessibility semantics.
aria-pressedandrole="group"/aria-labelare correctly applied for the toggle buttons, and the direction is wired intosettings.orderDirectionconsistently with the rest of the dropdown's update pattern.One minor observation: this button-group is a bespoke inline implementation distinct from the existing
RadioRowcomponent used forgroupBy/orderByjust above it. Since there are only two mutually-exclusive options, extracting a shared toggle-button-group helper (or reusingRadioRowstyled differently) could reduce style duplication, but given the small footprint this is optional.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/project-saved-view/ProjectSavedViewDisplayDropdown.tsx` around lines 265 - 285, No functional issue needs to be fixed here; the `ProjectSavedViewDisplayDropdown` direction buttons already use the correct accessibility and state-update patterns. If you want to address the minor style duplication noted in the review, consider extracting this inline toggle-button group into a shared helper or reusing `RadioRow` alongside the existing `settings.orderDirection` wiring, but this is optional and not required for correctness.apps/web/src/pages/ViewDetailPage.tsx (1)
434-669: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftGrouping logic is fully duplicated from
buildGroupedIssues.Only the sort step was switched to the shared
sortIssuesByOrder; the entire groupBy switch (states/priority/cycle/module/labels/assignees/created_by, ~220 lines) is copy-pasted fromissueListGroupAndSort.ts. This PR needed to updateorderDirectionhandling in two places to stay consistent — evidence that this duplication already causes double maintenance. Consider callingbuildGroupedIssuesfrom this file directly (reconciling the minortitle()/isFlatdifferences) instead of keeping a parallel implementation.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/pages/ViewDetailPage.tsx` around lines 434 - 669, The groupedSections useMemo in ViewDetailPage is duplicating the same groupBy logic that already exists in buildGroupedIssues, creating a second source of truth for grouping and ordering. Replace the local states/priority/cycle/module/labels/assignees/created_by switch with a call to buildGroupedIssues, and adapt its result here for the local title/isFlat needs instead of maintaining a parallel implementation. Keep the shared sortIssuesByOrder behavior, and ensure settings.groupBy, settings.orderBy, and settings.orderDirection still flow through the shared helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@apps/web/src/components/project-saved-view/ProjectSavedViewDisplayDropdown.tsx`:
- Around line 265-285: No functional issue needs to be fixed here; the
`ProjectSavedViewDisplayDropdown` direction buttons already use the correct
accessibility and state-update patterns. If you want to address the minor style
duplication noted in the review, consider extracting this inline toggle-button
group into a shared helper or reusing `RadioRow` alongside the existing
`settings.orderDirection` wiring, but this is optional and not required for
correctness.
In `@apps/web/src/pages/ViewDetailPage.tsx`:
- Around line 434-669: The groupedSections useMemo in ViewDetailPage is
duplicating the same groupBy logic that already exists in buildGroupedIssues,
creating a second source of truth for grouping and ordering. Replace the local
states/priority/cycle/module/labels/assignees/created_by switch with a call to
buildGroupedIssues, and adapt its result here for the local title/isFlat needs
instead of maintaining a parallel implementation. Keep the shared
sortIssuesByOrder behavior, and ensure settings.groupBy, settings.orderBy, and
settings.orderDirection still flow through the shared helper.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: dc7d88f0-a26f-4c57-adbb-42a1a18e70c2
📒 Files selected for processing (4)
apps/web/src/components/project-saved-view/ProjectSavedViewDisplayDropdown.tsxapps/web/src/lib/issueListGroupAndSort.tsapps/web/src/lib/projectSavedViewDisplay.tsapps/web/src/pages/ViewDetailPage.tsx
Feature summary
Adds an ascending/descending toggle to the saved-view order-by control, so the same order key can be viewed in either direction.
Linked issues / discussion
Closes #181
User-facing behavior
In the saved-view Display dropdown, under "Order by", there's now an Ascending / Descending toggle. Picking Descending reverses the current ordering; the choice is remembered with the rest of the display settings (persisted per view in localStorage).
What changed
UI (
apps/web/)projectSavedViewDisplay.ts: newSavedViewOrderDirection('asc' | 'desc') onSavedViewDisplaySettings, wired through the defaults, clone, and the persist parse/serialize (defaults toasc, older persisted settings included).issueListGroupAndSort.ts:sortIssuesByOrdertakes adirection; descending is the ascending result reversed, so the toggle behaves consistently for every order key.buildGroupedIssuesaccepts and forwardsorderDirection.ProjectSavedViewDisplayDropdown.tsx: the Ascending/Descending toggle.ViewDetailPage.tsx: reuses the sharedsortIssuesByOrder(removing a duplicate local sorter) and passes the direction.Database
Why this design
Reversing the ascending result keeps the toggle predictable regardless of a key's natural direction (e.g. "last created" is newest-first ascending, oldest-first descending), and reuses one sort implementation instead of two.
Test plan
npm run typecheck,npm run lint,npm run build,prettier --checkall green.Out of scope (follow-ups)
Rollout notes
None.
AI assistance
Claude Code— and AI-assisted commits include aCo-Authored-By:trailerChecklist
--no-verifybypassSummary by CodeRabbit
New Features
Bug Fixes