Skip to content

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

Open
aicarma-artyom-maslov wants to merge 23 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 23 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

1. Release notes

Fixed task completion output ordering and stale draft synchronization. Completion forms now follow template field order, stale localStorage values no longer replace changed server values, file fields resynchronize after task reopen, and file links remain visible in workflow logs.


2. Context

  • Issue: #48108
  • App Location: Tasks (/tasks, /tasks/:id) -> Task Completion Form and Workflow Log.
  • Related Changes: Integrated the task draft/upload lifecycle from #48107 with per-field server fingerprints, metadata-aware draft storage, and output rendering fixes.

3. Solution & Implementation Details

  • Correct output order: Added sortFieldsByOrder and apply descending template order before rendering completion fields.
  • Per-field server fingerprints: Added getTaskOutputFingerprint to detect submitted-value changes independently from presentation metadata changes.
  • Metadata-aware drafts: Output and fieldset drafts now store dateStarted and server field fingerprints alongside draft data.
  • Reject stale values: Draft values are retained only while their corresponding server field fingerprint remains valid. Changed or cleared server values replace stale local values.
  • Preserve valid sibling drafts: A server update to one field does not discard drafts for unchanged fields or fieldset siblings.
  • Restart handling: Draft state is cleared when the same task starts a new execution with a different dateStarted value.
  • Schema synchronization: Latest server field and fieldset definitions are preserved while valid draft values are merged by API name.
  • Legacy storage support: Existing draft entries without metadata remain readable without being incorrectly stamped with current fingerprints.
  • File field synchronization: Server markdownValue and attachments are normalized into the current file state, including removed attachments and uploads completing during a parent refresh.
  • Workflow log file links: File outputs backed only by markdownValue are retained by workflow-log filtering and rendered as attachments with their URLs.
  • Safe draft flushing: Uses the flushable debounce lifecycle from #48107 so pending edits are persisted before completion, return, synchronization, or unmount.
  • Return cleanup: Successful return clears output and fieldset drafts for all affected task IDs; failed requests keep drafts intact.

4. What to Test

4.1 Preconditions

  1. Log in as a user assigned to an active task.
  2. Use a task with multiple output field types, including URL, file, user, radio, and a fieldset.
  3. Ensure output fields have different template order values.
  4. Keep DevTools open to inspect tasks_outputs and tasks_fieldsets_outputs in localStorage.

4.2 Positive Scenarios / Testing Report

Scenario Description (Steps & Expected Result) Chrome Desktop Safari Desktop Chrome Mobile Safari Mobile
Completion field order Open the task completion form.
Result: Fields and fieldsets appear in the same order as configured in the template.
[ ] [ ] [ ] [ ]
Preserve unchanged draft Enter a draft in one field and refresh another field from the server.
Result: The unchanged field keeps its draft while the changed field displays its new server value.
[ ] [ ] [ ] [ ]
Server value replaces stale draft Save a local draft, then update or clear the same field on the server.
Result: The stale local value is discarded and the server value is shown.
[ ] [ ] [ ] [ ]
Presentation metadata update Change only field name, description, visibility, or order on the server.
Result: Metadata updates are rendered without discarding the valid entered value.
[ ] [ ] [ ] [ ]
Task restart Reopen the same task after it starts a new execution.
Result: Drafts from the previous dateStarted execution are not restored.
[ ] [ ] [ ] [ ]
Fieldset synchronization Add or update a field in the server fieldset definition while a sibling has a local draft.
Result: The latest fieldset schema is shown and valid sibling drafts remain.
[ ] [ ] [ ] [ ]
File field reopen Open a task with attachments, navigate away, and reopen it with updated server attachments.
Result: Only the current attachment list is displayed.
[ ] [ ] [ ] [ ]
Workflow log file URL Complete a task with a file output and inspect the workflow log.
Result: The file is visible and its link opens the expected URL.
[ ] [ ] [ ] [ ]
Upload during synchronization Start an upload, update attachments from the parent task, then finish the upload.
Result: The uploaded file is appended to the latest attachment list without duplication.
[ ] [ ] [ ] [ ]

4.3 Negative Scenarios & Edge Cases

Scenario Description (Steps & Expected Result) Chrome Desktop Safari Desktop Chrome Mobile Safari Mobile
Corrupted storage Put invalid JSON or an invalid structure into either draft key.
Result: The task loads from server data without crashing.
[ ] [ ] [ ] [ ]
Legacy draft entry Open a task with a pre-metadata draft entry.
Result: The draft remains readable and is not assigned an unverified current fingerprint.
[ ] [ ] [ ] [ ]
Server clears a value Keep a stale local draft and clear the same field on the server.
Result: The field is empty instead of restoring the stale draft.
[ ] [ ] [ ] [ ]
Empty radio value Open a radio field whose server or stored value is empty.
Result: The field normalizes to no selection and does not crash.
[ ] [ ] [ ] [ ]
Failed return or completion Simulate a failed request.
Result: Current drafts remain available for retry.
[ ] [ ] [ ] [ ]
Concurrent file uploads Start multiple uploads and complete only one.
Result: Actions remain blocked until all uploads finish; no attachment is duplicated.
[ ] [ ] [ ] [ ]

4.4 Verification Points

  • UI: Output fields and fieldsets match template order.
  • UI: File outputs remain visible in workflow logs and open the correct URL.
  • Storage: Entries contain data and metadata with dateStarted and fieldFingerprints.
  • Storage: Changed server fields are removed from stored drafts while unchanged fields remain.
  • Storage: Successful return/completion removes affected entries.
  • Console: No duplicate-key, stale-state, or state-update-after-unmount warnings.

4.5 API Verification

  • Task retrieval/update: Verify changed output values and definitions from the task response are reflected without being replaced by stale local data.
  • Complete task: The configured completion endpoint receives current output values in rendered template order.
  • Return task: Draft cleanup occurs only after a successful response and includes all affected return task IDs.
  • Workflow log: File output data containing markdownValue is rendered as an attachment with the original URL.

4.6 What Was NOT Tested

  • Manual browser matrix testing; all browser checkboxes remain unchecked.
  • Cross-tab synchronization of simultaneous edits to the same task.
  • Offline editing and recovery after browser termination.
  • Backend workflow business rules unrelated to output serialization.
  • High-volume file upload performance.

5. Affected Areas

Scenario Description Chrome Desktop Safari Desktop Chrome Mobile Safari Mobile
Task Completion Form Field order, output synchronization, and draft persistence. [ ] [ ] [ ] [ ]
Fieldset Outputs Schema synchronization and sibling draft preservation. [ ] [ ] [ ] [ ]
File Output Fields Reopen synchronization, concurrent uploads, and duplicate prevention. [ ] [ ] [ ] [ ]
Workflow Log Visibility and URL rendering for file outputs stored as Markdown. [ ] [ ] [ ] [ ]
Task Return/Completion Draft flushing and cleanup after successful actions. [ ] [ ] [ ] [ ]

6. Unit Tests

  • TaskCard.test.tsx: Covers output ordering, hidden fields, server synchronization, upload blocking, draft flushing, and return cleanup.
  • useTaskOutput.test.tsx: Covers stale draft filtering, task restarts, metadata-only changes, fieldset merging, sibling draft preservation, debounce persistence, and unmount flushing.
  • getTaskOutputFingerprint.test.ts: Covers stable fingerprints, metadata exclusions, normalized empty values, file attachments, and submitted-value changes.
  • storageOutputs.test.ts: Covers metadata persistence, legacy entries, isolated storage keys, replacement, removal, and corrupted data.
  • ExtraFieldsHelper.test.ts: Covers file normalization, removed attachments, stored values, user IDs, and empty radio values.
  • ExtraFieldFile.test.tsx: Covers attachment synchronization, in-flight uploads, and reopen behavior.
  • redux/task/saga.test.ts: Covers successful/failed return and completion draft cleanup.
  • FeedItemHeader.test.tsx / FeedItemComment.test.tsx: Covers workflow-log output and comment rendering.

Automated verification performed after the master merge: ESLint passed, 117 related tests passed, and the webpack build completed successfully.


7. Commits

  • 850fff2c48108 fix(tasks): correct output field order and stale draft handling
  • 2f199c0548108 fix(tasks): avoid output sync races and preserve file attachments
  • 1a14d92048108 fix(fields): normalize empty radio values
  • fb5bf00948108 fix(tasks): harden output synchronization and cleanup
  • 4574567e48108 fix(tasks): prevent stale output drafts during sync
  • 4cf8905948108 refactor(tasks): align output components with project rules
  • 7f269fac48108 fix(tasks): prevent stale resync state
  • d728403048108 fix(frontend): stabilize output and async updates
  • 9713e44c48108 fix(tasks): preserve pending output drafts
  • 2c2ef12348108 fix(tasks): clear fieldset drafts on restart
  • 935479a748108 fix(tasks): preserve valid output drafts
  • 50a54f4a48108 fix(tasks): merge fieldset drafts with server fields
  • def1cb7648108 fix(tasks): flush drafts and restore user selections
  • 077cadb148108 fix(tasks): preserve drafts across output updates
  • 7e28fc6548108 fix(tasks): preserve field drafts during sync
  • 4bcc8e6748108 fix(tasks): validate stored drafts on mount
  • 41217f0b48108 fix(tasks): sync output metadata safely
  • d9e70f6f48108 fix(tasks): normalize empty drafts on first render
  • 4f0d57ba48108 fix(tasks): avoid invalidating draft fingerprints
  • 397c0f3a — merge origin/master into frontend/tasks/48108__fix_task_output_fields

Note

Medium Risk
Touches task completion/return payloads and local draft persistence with nuanced server-sync rules; regressions could lose user edits or submit wrong output, but behavior is heavily tested.

Overview
Fixes task output display order and local draft behavior so in-progress edits stay correct when the server updates and when users complete or return tasks.

Task output drafts and ordering: New useTaskOutput hook owns output/fieldset state, sorts fields with sortFieldsByOrder, and persists debounced drafts to local storage with metadata fingerprints (getTaskOutputFingerprint) so stale drafts drop when server values, task restarts, or mismatched dateStarted change—while keeping valid drafts when only field metadata changes. flushOutputs runs before complete/return so pending edits are saved synchronously; drafts clear on successful revert only (setTaskReverted saga).

Field value merging: ExtraFieldsHelper now treats stored drafts explicitly (including file attachments, user/group ids, and empty values) instead of letting empty server values win incorrectly.

UI refactors: TaskCard splits into TaskActions, TaskCardHeader, TaskOutputFields, TaskPerformers, and TaskWorkflowLog; highlights FeedItemHeader delegates to FeedItemComment, FeedItemOutputs, and PerformerChange (comment truncation uses scrollHeight and remeasures on text change). FeedItemOutputs counts file fields via markdownValue. ExtraFieldFile syncs attachment state from props and avoids races during upload with a ref.

Tests cover the hook, fingerprints, storage metadata, file fields, and related sagas.

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

Note

Fix output field ordering and stale draft handling in task output storage

  • Output fields in useTaskOutput are now sorted by descending order via a new sortFieldsByOrder utility in workflows.ts.
  • Draft outputs and fieldsets in local storage are validated against per-field fingerprints (via getTaskOutputFingerprint) and task dateStarted; stale or mismatched drafts are discarded on task restart.
  • Debounced savers in useTaskOutput now write from pending refs rather than arguments, and a flushOutputs call on unmount ensures no edits are lost.
  • fieldsetsStorage and outputStorage are unified under a new createTaskStorage generic in storageOutputs.ts, adding corruption-tolerant reads, metadata persistence, and bulk removal.
  • ExtraFieldsHelper.getFieldValue now falls back to defaultValue when storage holds an empty string or empty array, and File field attachment resolution uses an expanded precedence chain.
  • FeedItemHeader is refactored into subcomponents (FeedItemOutputs, FeedItemComment, PerformerChange) and FeedItemComment remeasures expandability when text or attachments change.
  • Risk: outputStorage and fieldsetsStorage read/write behavior and key semantics have changed; existing stored drafts with the legacy output property are migrated automatically, but entries with unexpected shapes will silently return undefined.

Macroscope summarized 397c0f3.

Comment thread frontend/src/public/components/TaskCard/TaskCard.tsx Outdated
Comment thread frontend/src/public/components/TaskCard/TaskCard.tsx Outdated
Comment thread frontend/src/public/redux/task/saga.ts
Comment thread frontend/src/public/components/TaskCard/TaskCard.tsx Outdated
Comment thread frontend/src/public/components/TaskCard/utils/getTaskOutputFingerprint.ts Outdated
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts
Comment thread frontend/src/public/components/Highlights/FeedItemComment.tsx Outdated
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts
Comment thread frontend/src/public/components/Highlights/FeedItemComment.tsx Outdated
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts Outdated
EBirkenfeld
EBirkenfeld previously approved these changes Jul 15, 2026
…8__fix_task_output_fields

# Conflicts:
#	frontend/src/public/components/Highlights/FeedItemHeader.tsx
#	frontend/src/public/components/TaskCard/TaskCard.tsx
#	frontend/src/public/components/TaskCard/__tests__/TaskCard.test.tsx
#	frontend/src/public/components/Team/Users/CreateUserModal/__tests__/CreateUserModal.test.tsx
#	frontend/src/public/components/TemplateEdit/ExtraFields/File/ExtraFieldFile.tsx
#	frontend/src/public/components/TemplateEdit/ExtraFields/File/__tests__/ExtraFieldFile.test.tsx
#	frontend/src/public/redux/task/__tests__/saga.test.ts
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts Outdated
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts Outdated
Comment thread frontend/src/public/redux/task/saga.ts Outdated
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts Outdated
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts
Comment thread frontend/src/public/components/TemplateEdit/ExtraFields/File/ExtraFieldFile.tsx Outdated
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts Outdated
Comment thread frontend/src/public/components/TemplateEdit/ExtraFields/File/ExtraFieldFile.tsx Outdated
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts Outdated
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts Outdated
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts
Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts Outdated

@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 2 potential issues.

There are 4 total unresolved issues (including 2 from previous reviews).

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 d9e70f6. Configure here.

Comment thread frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts Outdated
…8__fix_task_output_fields

# Conflicts:
#	frontend/src/public/components/Highlights/types.ts
#	frontend/src/public/components/Team/Users/CreateUserModal/__tests__/CreateUserModal.test.tsx
…8__fix_task_output_fields

# Conflicts:
#	frontend/src/public/components/TaskCard/TaskActions.tsx
#	frontend/src/public/components/TaskCard/TaskCard.tsx
#	frontend/src/public/components/TaskCard/TaskCardHeader.tsx
#	frontend/src/public/components/TaskCard/TaskOutputFields.tsx
#	frontend/src/public/components/TaskCard/TaskPerformers.tsx
#	frontend/src/public/components/TaskCard/TaskWorkflowLog.tsx
#	frontend/src/public/components/TaskCard/__tests__/TaskCard.test.tsx
#	frontend/src/public/components/TaskCard/hooks/__tests__/useTaskOutput.test.tsx
#	frontend/src/public/components/TaskCard/hooks/useTaskOutput.ts
#	frontend/src/public/components/TaskCard/types.ts
#	frontend/src/public/components/TaskCard/utils/__tests__/storageOutputs.test.ts
#	frontend/src/public/components/TaskCard/utils/storageOutputs.ts
#	frontend/src/public/components/TemplateEdit/ExtraFields/File/ExtraFieldFile.tsx
#	frontend/src/public/components/TemplateEdit/ExtraFields/File/__tests__/ExtraFieldFile.test.tsx
#	frontend/src/public/redux/task/saga.ts
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.

3 participants