fix: resolve epic field showing unset when a task's epic isn't yet paginated - #338
Conversation
…anel for better pagination support
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — fixes the epic field silently rendering as unset when a task's epic is beyond the first 20 paginated results from #336, and corrects the parent-field classification that accidentally showed an epic as a generic "Parent" for the same reason.
- Merge missing epics into
displayEpicsinInteractionLayout— diffs on-screen taskparent_task_idvalues against loadedepicTasks, fetches missing epics individually viataskQueryOptions+useQueries, and merges them after confirmingtask_type_id === epicType?.id(so non-epic parents don't masquerade as epics). - Fix epic fallback in
PropertiesPanel— falls back toparentTask(always fetched directly) whenepicTasks.find(...)misses due to pagination, and switches the parent-field gating from!epicTasks.find(...)to a directparentTask.task_type_id !== epicTypeIdcheck.
Review notes
The missingEpicIds computation iterates all on-screen tasks and checks parent_task_id — this can include non-epic parents (story/task nesting), which triggers unnecessary taskQueryOptions fetches. These are filtered out by the displayEpics memo so they never reach the UI, and the redundant network calls are cheap and bounded by the visible task count. No action needed.
The parentTask query comment in task-detail/index.tsx:150 ("for non-epic parents") is now slightly stale since parentTask is also used for epic fallback, but this is a pre-existing comment, not part of the diff.
DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏
…allback logic and testing

Summary
—) on task cards/rows and the task detail page whenever a task's epic wasn't among the first pages loaded by Feature/implement pagination for epic picker #336's cursor-based epic pagination (20/page). The badge/field was resolved withepicTasks.find(...)against that paginated array, so any epic past whatever window happened to be loaded looked like "no epic" even though the task had one.InteractionLayoutnow diffs the epics referenced by on-screen tasks against the loaded epic pages, fetches whichever ones are missing directly (reusing the existing single-task query, so no duplicate requests when that task is already cached), and merges them into theepicslist passed down to board/list views.PropertiesPanelhad a second-order version of the same bug: it already fetches the task's parent directly (parentTask) for the "parent task" fallback field, but classified "is this parent an epic" by checking membership in the paginatedepicTasksarray. When the epic wasn't loaded, a task's real epic wasn't just unset — it was misrendered as a generic non-epic "Parent" field. Fixed by checkingparentTask.task_type_idagainst the epic type directly instead of paginated-list membership..find()-based relationship lookup in the app (statuses, task types, members, custom fields, sprints, roles, doc folders, plugins) — all resolve against fully-loaded, non-paginated lists, so epics were the only entity with this failure mode.Test plan
tsc -bcleanbiome checkcleanvitest runontask-card.test.tsx/board-view.test.tsx— 21/21 passing