FN-7479: route dock task clicks to popups

Make right-dock task list clicks follow the task popup preference.

- Thread popup routing into the right-dock Tasks list while preserving embedded dock detail when popups are disabled.
- Cover popup-enabled and popup-disabled dock list behavior with controller tests.
- Update settings copy, operator docs, and release notes for the expanded popup setting scope.

Files changed:
 .changeset/fn-7479-right-dock-task-popup.md        |   7 ++
 docs/dashboard-guide.md                            |   7 +-
 docs/settings-reference.md                         |   4 +-
 packages/dashboard/app/App.tsx                     |   2 +-
 .../app/components/__tests__/RightDock.test.tsx    | 129 +++++++++++++++++++++
 .../settings/sections/AppearanceSection.tsx        |   4 +-
 .../app/components/useRightDockController.tsx      |  21 +++-
 7 files changed, 163 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7479

Fusion-Task-Lineage: 953f6a77-8cb9-409e-be4b-f1dbdc6e1b42

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-07-03 16:53:29 -07:00
parent 50cdab17b9
commit a2b09f277d
7 changed files with 163 additions and 11 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Make right-dock task list clicks respect the task popup setting.
category: fix
dev: Threads openMobileTasksInPopup through the right-dock Tasks list route while preserving embedded dock detail when disabled.

View File

@@ -57,13 +57,14 @@ When enabled on desktop or tablet project screens, the right dock is a persisten
If **Settings → Appearance → Open tasks in the right sidebar** is enabled, board task-card clicks open task detail inside this right dock and keep the board visible. The setting is default off; mobile or hidden/inactive dock states automatically fall back to the existing full-panel task detail unless the task-popup setting below is enabled, and non-board task-open paths keep their existing behavior.
<!-- FNXC:MobileTaskPopups 2026-07-01-12:00: Board-card task opens have a separate default-off popup setting so operators on desktop, tablet, and mobile can opt into the existing FloatingWindow task popup when they want the board visible; ordinary popup routing takes precedence over the right dock, while deep-tab and non-board opens keep their existing paths.
FNXC:TaskPopupGeometry 2026-07-03-00:00: Desktop/tablet task popups share a persisted geometry key across task IDs so operators can size and place the popup once, then open other tasks without repeating that setup. Mobile remains a full-screen sheet regardless of saved desktop geometry. -->
**Settings → Appearance → Open tasks as popups** changes only ordinary board task-card clicks across desktop, tablet, and mobile viewports. When enabled, those clicks use the existing task popup/FloatingWindow surface instead of the full-panel task detail or right-dock task detail, keeping the board visible in the background. On desktop and tablet, task popups restore the last saved popup size and position between tasks; on mobile, task popups stay full-screen sheets. Deep `changes`/`retries`/`workflow` opens, list/task-detail links, plugin/graph opens, and explicit pop-out actions keep their existing paths.
FNXC:TaskPopupGeometry 2026-07-03-00:00: Desktop/tablet task popups share a persisted geometry key across task IDs so operators can size and place the popup once, then open other tasks without repeating that setup. Mobile remains a full-screen sheet regardless of saved desktop geometry.
FNXC:RightDockTaskPopup 2026-07-03-00:00: The same task-popup preference also applies to ordinary clicks in the right-dock Tasks list so that opted-in operators never lose the list to embedded detail by clicking a dock task row. -->
**Settings → Appearance → Open tasks as popups** changes ordinary board task-card clicks and right-dock Tasks-list clicks across desktop, tablet, and mobile viewports. When enabled, those clicks use the existing task popup/FloatingWindow surface instead of the full-panel task detail or right-dock task detail, keeping the board or dock list visible in the background. On desktop and tablet, task popups restore the last saved popup size and position between tasks; on mobile, task popups stay full-screen sheets. Deep `changes`/`retries`/`workflow` opens, list/task-detail links outside the right-dock Tasks list, plugin/graph opens, and explicit pop-out actions keep their existing paths.
<!-- FNXC:DashboardNavigationDocs 2026-06-27-00:00: The right dock now hosts Chat as an inline tool panel; keep this user-facing roster aligned with STATIC_OVERFLOW_VIEW_ENTRIES so users know Chat can also pop out from the dock. -->
<!-- FNXC:RightDockTasks 2026-06-28-19:55: The dock task-detail overlay is now anchored to the first-class Tasks tool tab. Document that Tasks is a dock-only auxiliary surface with a last-viewed detail/list fallback, not a new primary navigation destination. -->
<!-- FNXC:RightDockTasks 2026-06-28-21:08: The right-dock Tasks list is an active-work queue by default: completed tasks require the local Show Done toggle, archived tasks stay hidden, and both task-detail back affordances return to this list. -->
The dock toolbar has built-in inline tool panels for **Tasks**, **Files**, **Chat**, **Activity Log**, **Git Manager**, **Dev Server** when enabled, **Secrets**, **Todos** when enabled, and **Pull Requests**. These tools render in embedded mode inside the dock instead of opening fixed popup overlays; **Files** opens by default and is the fallback when browser storage points at a removed dock key. The **Tasks** tab shows the last task opened in the dock; when no dock task is active, it shows a compact clickable active-task list. Use **Show Done** to include completed tasks in that compact list; archived tasks stay hidden there. Either task-detail back button returns to the Tasks list. Inline dock views have an expand button that opens the same view in a resizable modal for more room. The right-dock **Files** viewer and its expanded pop-out match the Files modal for browser-previewable file types: image, video/movie, audio, and PDF selections render as native browser previews, while editable text files keep the editor and save flow. Plugin overflow views may add additional right-dock tool tabs, except plugin destinations that explicitly belong in the left sidebar.
The dock toolbar has built-in inline tool panels for **Tasks**, **Files**, **Chat**, **Activity Log**, **Git Manager**, **Dev Server** when enabled, **Secrets**, **Todos** when enabled, and **Pull Requests**. These tools render in embedded mode inside the dock instead of opening fixed popup overlays; **Files** opens by default and is the fallback when browser storage points at a removed dock key. The **Tasks** tab shows the last task opened in the dock; when no dock task is active, it shows a compact clickable active-task list. Use **Show Done** to include completed tasks in that compact list; archived tasks stay hidden there. If **Open tasks as popups** is off, clicking a task in this list opens embedded dock detail and either task-detail back button returns to the Tasks list; if the popup setting is on, the click opens the task popup and the list remains visible. Inline dock views have an expand button that opens the same view in a resizable modal for more room. The right-dock **Files** viewer and its expanded pop-out match the Files modal for browser-previewable file types: image, video/movie, audio, and PDF selections render as native browser previews, while editable text files keep the editor and save flow. Plugin overflow views may add additional right-dock tool tabs, except plugin destinations that explicitly belong in the left sidebar.
Use the desktop/tablet right dock this way:

View File

@@ -478,8 +478,8 @@ Sandbox backend precedence is:
| `buildCommand` | `string` | `undefined` | Merge-time build command (hard gate). |
| `recycleWorktrees` | `boolean` | `false` | Default: off (opt-in). Reuse worktrees from a pool for faster startup. |
| `showWorktreeGrouping` | `boolean` | `false` | Default: off. When off, WIP/processing columns render plain task cards without worktree group shells or worktree-name labels in both legacy and workflow-mode boards. When on, every WIP/processing column groups tasks by worktree and shows worktree names, including workflow-mode columns flagged as counting toward WIP. |
| `openTasksInRightSidebar` | `boolean` | `false` | Default: off. When off, board task-card clicks keep the existing full-panel task detail that replaces the board. When on and the right dock is active on desktop/tablet, board task-card clicks open the task detail in the right sidebar so the board stays visible; mobile or hidden/inactive right-dock states automatically fall back to the full-panel behavior. Non-board task-open paths, including list split detail, right-dock task cards, floating pop-outs, graph/plugin opens, and deep `changes`/`retries`/`workflow` opens, keep their existing behavior. |
| `openMobileTasksInPopup` | `boolean` | `false` | Default: off. When off, ordinary board task-card clicks keep the existing fallback behavior: the full-panel task detail, or the right dock when `openTasksInRightSidebar` is on and the dock is active. When on, ordinary board task-card clicks open the task in the existing task popup/FloatingWindow surface on desktop, tablet, and mobile so the board remains visible; this popup route takes precedence over right-dock routing for those ordinary clicks. Desktop/tablet task popups restore the last saved popup size and position across task IDs, while mobile task popups remain full-screen sheets. This setting remains board-only: right-dock task cards, list/detail opens, graph/plugin opens, nested task-detail opens, explicit pop-out actions, and deep `changes`/`retries`/`workflow` opens keep their existing behavior. |
| `openTasksInRightSidebar` | `boolean` | `false` | Default: off. When off, board task-card clicks keep the existing full-panel task detail that replaces the board. When on and the right dock is active on desktop/tablet, board task-card clicks open the task detail in the right sidebar so the board stays visible; mobile or hidden/inactive right-dock states automatically fall back to the full-panel behavior. Non-board task-open paths, including list split detail, floating pop-outs, graph/plugin opens, and deep `changes`/`retries`/`workflow` opens, keep their existing behavior; ordinary right-dock Tasks-list cards are governed by `openMobileTasksInPopup` first and otherwise use embedded dock detail. |
| `openMobileTasksInPopup` | `boolean` | `false` | Default: off. When off, ordinary board task-card clicks keep the existing fallback behavior: the full-panel task detail, or the right dock when `openTasksInRightSidebar` is on and the dock is active; ordinary right-dock Tasks-list clicks open embedded dock detail with the normal back-to-list controls. When on, ordinary board task-card clicks and right-dock Tasks-list clicks open the task in the existing task popup/FloatingWindow surface on desktop, tablet, and mobile so the board or dock list remains visible; this popup route takes precedence over right-dock routing for those ordinary clicks. Desktop/tablet task popups restore the last saved popup size and position across task IDs, while mobile task popups remain full-screen sheets. Deep `changes`/`retries`/`workflow` opens, list/detail opens outside the right-dock Tasks list, graph/plugin opens, nested task-detail opens, and explicit pop-out actions keep their existing behavior. |
| `executorAllowSiblingBranchRename` | `boolean` | `false` | Opt back into the legacy executor behavior that silently allocates sibling branches (`fusion/<task-id>-2`, `-2-2`, …) when the canonical task branch is already checked out elsewhere. When disabled (default), branch conflicts fail loudly and leave the task in `todo` with `status: "failed"` so operators can resolve conflicting branches/worktrees with git tooling before retrying. See [Task Management → Branch conflict handling](./task-management.md#branch-conflict-handling). The dashboard Settings modal exposes the same toggle with warning copy because this legacy mode is discouraged. |
| `worktreeNaming` | `"random" \| "task-id" \| "task-title"` | `"random"` | Naming mode for new worktree directories. |

View File

@@ -1146,7 +1146,7 @@ function AppInner() {
// Props for the extracted <MainContent> switch (see components/dashboard/MainContent.tsx).
// Every value is passed by its App name; the switch renders the same subtrees as before.
const rightDock = useRightDockController({ active: rightDockActive, projectId: currentProject?.id, addToast, settingsLoaded, researchReadinessVersion, goalAnchorId, tasks: isRemote && remoteData.tasks.length > 0 ? remoteData.tasks : tasks, workflowSteps, subscribePluginEvents, openDetailTask, openFileInBrowser, onMoveTask: moveTask, onDeleteTask: deleteTask, onArchiveTask: archiveTask, onMergeTask: mergeTask, onRetryTask: retryTask, onResetTask: resetTask, onDuplicateTask: duplicateTask, onTaskUpdated: (task: Task) => ingestCreatedTasks([task]), openSettings: (section?: string) => openSettingsWithNav(section as SectionId), onOpenUsage: openUsageWithNav, onOpenActivityLog: openActivityLogWithNav, onOpenGitHubImport: openGitHubImportWithNav, onOpenGitManager: openGitManagerWithNav, onOpenSchedules: openSchedulesWithNav, onSendSelectionToTask: modalManager.openNewTaskWithDescription, onCreateTaskFromInsight: handleInsightTaskCreate, onNavigateToMission: handleOpenMission, onTaskCreated: (task: Task) => ingestCreatedTasks([task]), prAuthAvailable, autoMerge, taskDetailChatFirst, visibilityOptions: { experimentalFeatures: { insights: insightsEnabled, memoryView: memoryEnabled, devServerView: devServerEnabled, researchView: researchEnabled, evalsView: evalsEnabled, goalsView: goalsEnabled }, showSkillsTab: skillsEnabled, todosEnabled, pluginDashboardViews }, footerVisible: executorFooterVisible });
const rightDock = useRightDockController({ active: rightDockActive, projectId: currentProject?.id, addToast, settingsLoaded, researchReadinessVersion, goalAnchorId, tasks: isRemote && remoteData.tasks.length > 0 ? remoteData.tasks : tasks, workflowSteps, subscribePluginEvents, openDetailTask, openTaskPopup: popOutTaskDetail, openMobileTasksInPopup, openFileInBrowser, onMoveTask: moveTask, onDeleteTask: deleteTask, onArchiveTask: archiveTask, onMergeTask: mergeTask, onRetryTask: retryTask, onResetTask: resetTask, onDuplicateTask: duplicateTask, onTaskUpdated: (task: Task) => ingestCreatedTasks([task]), openSettings: (section?: string) => openSettingsWithNav(section as SectionId), onOpenUsage: openUsageWithNav, onOpenActivityLog: openActivityLogWithNav, onOpenGitHubImport: openGitHubImportWithNav, onOpenGitManager: openGitManagerWithNav, onOpenSchedules: openSchedulesWithNav, onSendSelectionToTask: modalManager.openNewTaskWithDescription, onCreateTaskFromInsight: handleInsightTaskCreate, onNavigateToMission: handleOpenMission, onTaskCreated: (task: Task) => ingestCreatedTasks([task]), prAuthAvailable, autoMerge, taskDetailChatFirst, visibilityOptions: { experimentalFeatures: { insights: insightsEnabled, memoryView: memoryEnabled, devServerView: devServerEnabled, researchView: researchEnabled, evalsView: evalsEnabled, goalsView: goalsEnabled }, showSkillsTab: skillsEnabled, todosEnabled, pluginDashboardViews }, footerVisible: executorFooterVisible });
/*
FNXC:OpenTasksInRightSidebar 2026-06-28-00:00:

View File

@@ -271,6 +271,135 @@ describe("RightDock", () => {
expect(screen.getByTestId("dock-task-detail")).toHaveTextContent("Sidebar task");
});
it("routes right-dock Tasks list clicks to popups when task popups are enabled", () => {
const firstTask = { id: "FN-1", title: "First task", column: "todo" };
const openDetailTask = vi.fn();
const openTaskPopup = vi.fn();
const controllerInput = {
active: true,
projectId: "project-1",
addToast: vi.fn(),
settingsLoaded: true,
researchReadinessVersion: 0,
tasks: [firstTask],
workflowSteps: [],
subscribePluginEvents: () => () => {},
openDetailTask,
openTaskPopup,
openMobileTasksInPopup: true,
openFileInBrowser: vi.fn(),
onMoveTask: vi.fn(),
onDeleteTask: vi.fn(),
onMergeTask: vi.fn(),
openSettings: vi.fn(),
onSendSelectionToTask: vi.fn(),
onCreateTaskFromInsight: vi.fn(),
onNavigateToMission: vi.fn(),
onTaskCreated: vi.fn(),
prAuthAvailable: false,
autoMerge: false,
taskDetailChatFirst: false,
visibilityOptions: {},
footerVisible: false,
} as unknown as RightDockControllerInput;
function Harness() {
const controller = useRightDockController(controllerInput);
return (
<>
{controller.dock}
{controller.modal}
</>
);
}
render(<Harness />);
fireEvent.click(screen.getByTestId("right-dock-tab-tasks"));
expect(screen.getByTestId("dock-task-list")).toBeInTheDocument();
fireEvent.click(screen.getByTestId("mock-task-card-FN-1"));
expect(openTaskPopup).toHaveBeenCalledTimes(1);
expect(openTaskPopup).toHaveBeenCalledWith(firstTask);
expect(openDetailTask).not.toHaveBeenCalled();
expect(screen.getByTestId("dock-task-list")).toBeInTheDocument();
expect(screen.queryByTestId("dock-task-detail")).toBeNull();
expect(screen.queryByTestId("right-dock-close-task")).toBeNull();
expect(screen.queryByTestId("right-dock-header-back-task")).toBeNull();
fireEvent.click(screen.getByTestId("right-dock-expand"));
expect(screen.getByTestId("right-dock-expand-modal")).toHaveAttribute("aria-label", "Tasks expanded");
fireEvent.click(screen.getByTestId("mock-task-card-FN-1"));
expect(openTaskPopup).toHaveBeenCalledTimes(2);
expect(openTaskPopup).toHaveBeenLastCalledWith(firstTask);
expect(screen.queryByTestId("dock-task-detail")).toBeNull();
});
it("keeps right-dock Tasks list clicks embedded when task popups are disabled", () => {
const firstTask = { id: "FN-1", title: "First task", column: "todo" };
const openDetailTask = vi.fn();
const openTaskPopup = vi.fn();
const controllerInput = {
active: true,
projectId: "project-1",
addToast: vi.fn(),
settingsLoaded: true,
researchReadinessVersion: 0,
tasks: [firstTask],
workflowSteps: [],
subscribePluginEvents: () => () => {},
openDetailTask,
openTaskPopup,
openMobileTasksInPopup: false,
openFileInBrowser: vi.fn(),
onMoveTask: vi.fn(),
onDeleteTask: vi.fn(),
onMergeTask: vi.fn(),
openSettings: vi.fn(),
onSendSelectionToTask: vi.fn(),
onCreateTaskFromInsight: vi.fn(),
onNavigateToMission: vi.fn(),
onTaskCreated: vi.fn(),
prAuthAvailable: false,
autoMerge: false,
taskDetailChatFirst: false,
visibilityOptions: {},
footerVisible: false,
} as unknown as RightDockControllerInput;
function Harness() {
const controller = useRightDockController(controllerInput);
return <>{controller.dock}</>;
}
const { rerender } = render(<Harness />);
fireEvent.click(screen.getByTestId("right-dock-tab-tasks"));
fireEvent.click(screen.getByTestId("mock-task-card-FN-1"));
expect(openTaskPopup).not.toHaveBeenCalled();
expect(openDetailTask).not.toHaveBeenCalled();
expect(screen.getByTestId("dock-task-detail")).toHaveTextContent("First task");
expect(screen.getByTestId("right-dock-close-task")).toBeInTheDocument();
expect(screen.getByTestId("right-dock-header-back-task")).toBeInTheDocument();
fireEvent.click(screen.getByTestId("right-dock-tab-files"));
expect(screen.queryByTestId("dock-task-detail")).toBeNull();
fireEvent.click(screen.getByTestId("right-dock-tab-tasks"));
expect(screen.getByTestId("dock-task-detail")).toHaveTextContent("First task");
fireEvent.click(screen.getByTestId("right-dock-header-back-task"));
expect(screen.queryByTestId("dock-task-detail")).toBeNull();
expect(screen.getByTestId("dock-task-list")).toBeInTheDocument();
fireEvent.click(screen.getByTestId("mock-task-card-FN-1"));
expect(screen.getByTestId("dock-task-detail")).toHaveTextContent("First task");
fireEvent.click(screen.getByTestId("right-dock-close-task"));
rerender(<Harness />);
expect(screen.queryByTestId("dock-task-detail")).toBeNull();
expect(screen.getByTestId("dock-task-list")).toBeInTheDocument();
});
it("controller dock task opens, replaces, persists across tabs, and clears on close or inactive teardown", () => {
const firstTask = { id: "FN-1", title: "First task", column: "todo" };
const secondTask = { id: "FN-2", title: "Second task", column: "todo" };

View File

@@ -45,12 +45,12 @@ export function AppearanceSection({ scopeBanner, form, setForm, themeMode, color
<small className="form-text text-muted">{t("settings.appearance.openTasksInRightSidebarHelp", "When enabled, board task cards open detail in the right sidebar when it is available; mobile and hidden-sidebar states keep the full task panel.")}</small>
</div>
<div className="form-group">
{/* FNXC:MobileTaskPopups 2026-07-01-12:00: Keep the stored openMobileTasksInPopup key for compatibility, but present the setting as all-viewport board-card popup routing because desktop operators also need the board visible behind task detail. */}
{/* FNXC:MobileTaskPopups 2026-07-01-12:00: Keep the stored openMobileTasksInPopup key for compatibility, but present the setting as all-viewport ordinary task popup routing because desktop operators also need the board or right-dock Tasks list visible behind task detail. */}
<label className="checkbox-label">
<input type="checkbox" checked={form.openMobileTasksInPopup === true} onChange={(e) => setForm((f) => ({ ...f, openMobileTasksInPopup: e.target.checked }))}/>
<span>{t("settings.appearance.openMobileTasksInPopup", "Open tasks as popups")}</span>
</label>
<small className="form-text text-muted">{t("settings.appearance.openMobileTasksInPopupHelp", "When enabled, ordinary board task-card clicks open the existing task popup so the board remains visible. Deep-tab and non-board task opens keep their current behavior.")}</small>
<small className="form-text text-muted">{t("settings.appearance.openMobileTasksInPopupHelp", "When enabled, ordinary board task-card and right-dock Tasks-list clicks open the existing task popup so the board or list remains visible. Deep-tab and other task opens keep their current behavior.")}</small>
</div>
<div className="form-group">
{/* FNXC:TaskDetailActivityFirst 2026-06-30-23:59: The project setting is opt-in because task details now default to Activity-first; explicit Activity/Chat/Logs links keep their destination regardless of this checkbox. */}

View File

@@ -23,6 +23,8 @@ export interface RightDockControllerInput {
workflowSteps: WorkflowStep[];
subscribePluginEvents: (pluginId: string, onEvent: (event: { event: string; payload: unknown }) => void) => () => void;
openDetailTask: (task: Task | TaskDetail, initialTab?: DetailTaskTab) => void;
openTaskPopup: (task: Task | TaskDetail) => void;
openMobileTasksInPopup: boolean;
openFileInBrowser: (path: string, opts?: { workspace?: string; line?: number; col?: number }) => void;
onMoveTask: (id: string, column: ColumnId, optionsOrPosition?: { preserveProgress?: boolean } | number) => Promise<Task>;
onDeleteTask: (id: string, options?: { removeDependencyReferences?: boolean; removeLineageReferences?: boolean; githubIssueAction?: GithubIssueAction; allowResurrection?: boolean }) => Promise<Task>;
@@ -87,6 +89,19 @@ export function useRightDockController(input: RightDockControllerInput): RightDo
persistRightDockOpen(true);
}, []);
/*
FNXC:RightDockTaskPopup 2026-07-03-00:00:
Ordinary task opens from the right-dock Tasks list must honor the task-popup setting before creating an embedded dock-detail snapshot. Keep `openTaskInDock` intact for setting-off routing, board right-sidebar routing, and the Tasks-tab back/list detail lifecycle.
*/
const openTaskFromDockList = useCallback((task: Task | TaskDetail) => {
if (input.openMobileTasksInPopup === true) {
input.openTaskPopup(task);
return;
}
openTaskInDock(task);
}, [input, openTaskInDock]);
const resolvedDockTask = useMemo(() => {
if (!dockTaskSnapshot) return null;
return input.tasks.find((candidate) => candidate.id === dockTaskSnapshot.id) ?? dockTaskSnapshot;
@@ -189,9 +204,9 @@ export function useRightDockController(input: RightDockControllerInput): RightDo
},
/*
FNXC:RightDockTasks 2026-06-28-17:05:
DockTaskList rows must open the in-dock Tasks detail, not the canonical full task modal. Thread the existing dock snapshot setter into registry render props so both compact and expanded Tasks lists route TaskCard's internal open action to the Tasks tab.
DockTaskList rows must open through the controller's ordinary right-dock task route, not TaskCard's canonical full task modal. Thread one controller-level handler into registry render props so both compact and expanded Tasks lists share popup-setting routing and setting-off dock-detail behavior.
*/
onOpenTaskInDock: openTaskInDock,
onOpenTaskInDock: openTaskFromDockList,
onOpenDetail: input.openDetailTask,
onSendSelectionToTask: input.onSendSelectionToTask,
onCreateTaskFromInsight: input.onCreateTaskFromInsight,
@@ -201,7 +216,7 @@ export function useRightDockController(input: RightDockControllerInput): RightDo
renderTaskCard,
subscribePluginEvents: input.subscribePluginEvents,
openFile: input.openFileInBrowser,
}), [input, openTaskInDock, renderTaskCard]);
}), [input, openTaskFromDockList, renderTaskCard]);
const dockTaskContent = resolvedDockTask ? (
/*