Skip to content

48108 frontend [ tasks ] Correct output field order and stale draft handling#268

Open
aicarma-artyom-maslov wants to merge 2 commits into
masterfrom
frontend/tasks/48108__fix_task_output_fields
Open

48108 frontend [ tasks ] Correct output field order and stale draft handling#268
aicarma-artyom-maslov wants to merge 2 commits into
masterfrom
frontend/tasks/48108__fix_task_output_fields

Conversation

@aicarma-artyom-maslov

@aicarma-artyom-maslov aicarma-artyom-maslov commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Note

Medium Risk
Changes merge rules for server vs local draft output and when TaskCard resets field state; wrong precedence could drop in-progress edits, but scope is task UI and storage only.

Overview
Fixes task output UX: fields render in template order, server data wins over stale local drafts, and file outputs stay in sync after server updates.

Task card now sorts outputs with sortFieldsByOrder and only re-merges storage when the task changes, restarts (dateStarted), or server output changes (getTaskOutputFingerprint). Pending debounced saves are cancelled on task switch/restart so drafts do not bleed across tasks.

ExtraFieldsHelper prefers server values when present (hasServerValue); file fields use server markdownValue/attachments instead of local storage when the server already has data. ExtraFieldFile syncs its file list from props when attachments or markdownValue change.

Feed highlights treat file outputs with only markdownValue as non-empty. Task revert clears local output storage like task complete already does.

Reviewed by Cursor Bugbot for commit 2f199c0. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix output field order and stale draft handling in TaskCard

  • Output fields in TaskCard are now sorted by descending order to match the template, using a new sortFieldsByOrder utility in workflows.ts.
  • A new getTaskOutputFingerprint util detects server-side output changes so the component refreshes field values on task restart or remote update without resetting unchanged local drafts.
  • Server-provided field values now take precedence over local storage in ExtraFieldsHelper; File fields source attachments from markdownValue or field.attachments, falling back to storage only when the server has no value.
  • ExtraFieldFile now updates displayed files when field.attachments or field.markdownValue props change after initial render.
  • Reverting a task now calls removeOutputFromLocalStorage to clear stale drafts from local storage.

Macroscope summarized 2f199c0.

@@ -158,10 +159,12 @@ export function TaskCard({
useEffect(() => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium TaskCard/TaskCard.tsx:159

The useEffect that rebuilds outputValues now depends on task.output, which races with the 300 ms debounced draft write in handleEditField. When a user edits a field, handleEditField updates outputValues optimistically but defers the localStorage write by 300 ms. If task.output changes identity in that window (e.g. after a server sync), the effect runs before the debounced write completes, reads the stale localStorage draft via getOutputFromStorage(id), and overwrites outputValues with the older value. The pending saveOutputsToStorageDebounced then writes the newer value to localStorage, but the UI never re-reads it, so the stale value persists and setTaskCompleted can submit the rolled-back output. Consider not reading from localStorage when the update originates from a user edit, or flush the pending debounced write before rebuilding from task.output.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @frontend/src/public/components/TaskCard/TaskCard.tsx around line 159:

The `useEffect` that rebuilds `outputValues` now depends on `task.output`, which races with the 300 ms debounced draft write in `handleEditField`. When a user edits a field, `handleEditField` updates `outputValues` optimistically but defers the localStorage write by 300 ms. If `task.output` changes identity in that window (e.g. after a server sync), the effect runs before the debounced write completes, reads the stale localStorage draft via `getOutputFromStorage(id)`, and overwrites `outputValues` with the older value. The pending `saveOutputsToStorageDebounced` then writes the newer value to localStorage, but the UI never re-reads it, so the stale value persists and `setTaskCompleted` can submit the rolled-back output. Consider not reading from localStorage when the update originates from a user edit, or flush the pending debounced write before rebuilding from `task.output`.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 850fff2. Configure here.

Comment thread frontend/src/public/components/TaskCard/TaskCard.tsx Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Frontend Web client changes request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant