Skip to content

OUT-3494 | Improve default sorting for subtasks#1211

Open
arpandhakal wants to merge 3 commits intomainfrom
OUT-3494
Open

OUT-3494 | Improve default sorting for subtasks#1211
arpandhakal wants to merge 3 commits intomainfrom
OUT-3494

Conversation

@arpandhakal
Copy link
Copy Markdown
Collaborator

@arpandhakal arpandhakal commented May 8, 2026

Summary

  • Adds sortSubtasksByPriority — sorts subtasks by status (startedunstartedcompletedbacklogcancelled), then dueDate ASC nulls last, then createdAt ASC (oldest first), with id as a stability tiebreaker.
  • Applies the new sort on the details page (Subtasks.tsx, including the optimistic-insert path) and on the board/list views via subtasksByTaskId in TaskBoard.tsx. List view inherits the order through the same dictionary.
  • Top-level task sort (sortTaskByDescendingOrder) is unchanged. Templates (Subtemplates.tsx) and the backend orderBy are not touched — every web subtask render path re-sorts client-side, so the DB order is irrelevant for what users see.

Linear: https://linear.app/assemblycom/issue/OUT-3494/improve-default-sorting-for-subtasks

Test plan

  • Open a task with subtasks in mixed states — verify In Progress items appear first, Todo next, Done after, Backlog/Cancelled last
  • Within a single status, verify subtasks with due dates sort earliest-first and subtasks without a due date appear after those with one
  • Within a single status with all-equal due dates (or none), verify subtasks created earlier appear above newer ones
  • Create three subtasks back-to-back in the details page — confirm they appear in creation order (optimistic insert respects the new sort)
  • Verify the board view and list view both reflect the new subtask ordering under each parent
  • Verify top-level task lists (board columns, list view sections) are unaffected

Sort subtasks by status (started, unstarted, completed, backlog,
cancelled), then due date ASC nulls last, then createdAt ASC. Applied
to the details page (incl. optimistic insert) and the board/list views
via subtasksByTaskId. Top-level task sort is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 8, 2026

OUT-3494

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tasks-app Ready Ready Preview, Comment May 8, 2026 11:46am

Request Review

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 8, 2026

Deployment failed with the following error:

Deploying Serverless Functions to multiple regions is restricted to the Pro and Enterprise plans.

Learn More: https://vercel.link/multiple-function-regions

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 8, 2026

Greptile Summary

This PR introduces a new sortSubtasksByPriority comparator and applies it to every client-side subtask render path — the details page (including the optimistic-create flow) and the board/list view dictionary.

  • New sort order (sortByDescending.ts): status bucket (started → unstarted → completed → backlog → cancelled), then due date ascending (nulls last), then createdAt ascending, with id as a tie-breaker.
  • Details page (Subtasks.tsx): replaces sortTaskByDescendingOrder on the optimistic-insert path; the optimistic-update path (handleSubTaskUpdate) is untouched and still does not re-sort after status or due-date changes.
  • Board/list view (TaskBoard.tsx): the subtasksByTaskId memo now sorts each group with the new comparator instead of the old descending-date one.

Confidence Score: 4/5

Safe to merge; the new sort logic is correct and the board/create paths work as described.

The sort comparator itself is correct — status priority, due-date ASC nulls last, createdAt ASC, and id tiebreaker are all implemented accurately. The gap is in handleSubTaskUpdate, which skips re-sorting and sets revalidate: false, so after a status or due-date change the list order stays wrong until the next natural data refresh. This is observable rather than data-corrupting, and the create path works correctly.

src/app/detail/ui/Subtasks.tsx — the optimistic-update path doesn't call the new sort, leaving ordering stale after status/due-date changes.

Important Files Changed

Filename Overview
src/utils/sortByDescending.ts Adds sortSubtasksByPriority with a correct status-priority map, ascending due-date (nulls last), ascending createdAt, and id tiebreaker; existing sort helpers are unchanged.
src/app/detail/ui/Subtasks.tsx Switches optimistic-create path to sortSubtasksByPriority; the optimistic-update path (handleSubTaskUpdate) still doesn't re-sort, leaving ordering stale after status/due-date changes until revalidation.
src/app/ui/TaskBoard.tsx Applies sortSubtasksByPriority to the subtasksByTaskId memo; straightforward import addition and one-line swap, logic is correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Subtask list needed] --> B{Which view?}
    B -->|Details page - create| C[getTempTask\nbuilds temp subtask]
    C --> D[sortSubtasksByPriority\ninserted into existing list]
    D --> E[optimisticData → mutate\nrevalidate: true]

    B -->|Details page - update| F[handleSubTaskUpdate\n.map applies changes]
    F --> G[optimisticData — NO re-sort\nrevalidate: false]
    G --> H[Stale order until\nnext natural refresh]

    B -->|Board / List view| I[subtasksByTaskId memo\naccessibleTasks grouped by parentId]
    I --> J[sortSubtasksByPriority\nper group]
    J --> K[Rendered in column/row]

    subgraph sortSubtasksByPriority
        S1[1. Workflow state type priority\nstarted→unstarted→completed→backlog→cancelled]
        S2[2. dueDate ASC, nulls last]
        S3[3. createdAt ASC]
        S4[4. id tiebreaker]
        S1 --> S2 --> S3 --> S4
    end
Loading

Comments Outside Diff (1)

  1. src/app/detail/ui/Subtasks.tsx, line 124-144 (link)

    P2 Optimistic update path skips re-sort

    handleSubTaskUpdate builds updatedTasks via a plain .map() and passes it as optimisticData without calling sortSubtasksByPriority. Because revalidate: false is set here (unlike the create path), the stale order persists until the next natural data refresh rather than just until the next tick. With the new status-first sort, a user changing a subtask from started to completed will see it stay at the top of the list until the full revalidation fires — making the optimistic state visually incorrect relative to the new sort contract.

Reviews (1): Last reviewed commit: "Merge branch 'main' into OUT-3494" | Re-trigger Greptile

The details page was rendering subtasks straight from SWR data without
client-side sorting, so revalidation reverted the order to the backend's
createdAt DESC. Sort the rendered list via useMemo so optimistic and
revalidated data both go through the same comparator.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@arpandhakal arpandhakal changed the title feat(OUT-3494): improve default sorting for subtasks OUT-3494 | Improve default sorting for subtasks May 8, 2026
@arpandhakal arpandhakal requested review from SandipBajracharya and priosshrsth and removed request for SandipBajracharya May 8, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant