FN-8232: keep task attachment picker available across tabs
Keep the task-detail attachment picker functional outside the Definition tab. - Mount the shared hidden file input outside tab-specific content. - Cover attachment picker access from the Activity tab. - Add a patch changeset for the task-detail fix. Files changed: .../fn-8232-task-detail-attachment-picker.md | 7 +++++++ .../dashboard/app/components/TaskDetailModal.tsx | 20 ++++++++++++------- ...lModal.inline-editing-and-integrations.test.tsx | 23 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) Fusion-Task-Id: FN-8232 Fusion-Task-Lineage: a425a373-f15c-4e7f-a50e-e2eba592d2c9 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
7
.changeset/fn-8232-task-detail-attachment-picker.md
Normal file
7
.changeset/fn-8232-task-detail-attachment-picker.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@runfusion/fusion": patch
|
||||
---
|
||||
|
||||
summary: Fix the task-detail attach-file icon when the Definition tab is not open.
|
||||
category: fix
|
||||
dev: Keeps the shared fileInputRef input mounted outside tab-specific content.
|
||||
@@ -4490,6 +4490,19 @@ export function TaskDetailContent({
|
||||
<Zap size={14} aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
{/*
|
||||
FNXC:TaskDetailAttachments 2026-07-17-12:30:
|
||||
FN-8232: keep the hidden file input mounted independently of activeTab.
|
||||
The paperclip renders on every non-editing tab while task details default
|
||||
to Activity or Summary; a Definition-only input made that control a no-op.
|
||||
*/}
|
||||
<input
|
||||
className="detail-hidden-file-input"
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
accept="image/*"
|
||||
onChange={handleUpload}
|
||||
/>
|
||||
{overseerExplainOpen && (
|
||||
<div className="detail-overseer-explain-panel" data-testid="detail-overseer-explain-panel" role="region" aria-live="polite">
|
||||
{isLoadingOverseerExplain ? (
|
||||
@@ -5892,13 +5905,6 @@ export function TaskDetailContent({
|
||||
) : (
|
||||
<div className="detail-empty-inline">{t("taskDetail.attachments.none", "(no attachments)")}</div>
|
||||
)}
|
||||
<input
|
||||
className="detail-hidden-file-input"
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
accept="image/*"
|
||||
onChange={handleUpload}
|
||||
/>
|
||||
<button
|
||||
className="btn btn-sm"
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
|
||||
@@ -3372,6 +3372,29 @@ describe("TaskDetailModal inline action row parity (FN-8194)", () => {
|
||||
expect(fileInputClick).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("opens the shared file picker from Activity without rendering Definition", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
initialTab="chat"
|
||||
task={makeTask({ id: "FN-8232", column: "todo" })}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
const fileInputs = document.querySelectorAll<HTMLInputElement>('input[type="file"]');
|
||||
expect(fileInputs).toHaveLength(1);
|
||||
const fileInputClick = vi.spyOn(fileInputs[0], "click");
|
||||
|
||||
fireEvent.click(screen.getByTestId("detail-inline-attach"));
|
||||
|
||||
expect(fileInputClick).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("toggles GitHub tracking through the existing update path and reflects enabled state", async () => {
|
||||
const { updateTask } = await import("../../api");
|
||||
const mockUpdate = vi.mocked(updateTask);
|
||||
|
||||
Reference in New Issue
Block a user