diff --git a/.changeset/fn-7296-quick-add-workflow-icons.md b/.changeset/fn-7296-quick-add-workflow-icons.md
new file mode 100644
index 0000000000..b207c7a897
--- /dev/null
+++ b/.changeset/fn-7296-quick-add-workflow-icons.md
@@ -0,0 +1,7 @@
+---
+"@runfusion/fusion": patch
+---
+
+summary: Show workflow icons and wider names in the Quick Add workflow selector.
+category: fix
+dev: Reuses WorkflowIcon in QuickEntryBox and widens the tokenized selector/menu styles.
diff --git a/packages/dashboard/app/components/QuickEntryBox.css b/packages/dashboard/app/components/QuickEntryBox.css
index b112fa8fbf..29a4392181 100644
--- a/packages/dashboard/app/components/QuickEntryBox.css
+++ b/packages/dashboard/app/components/QuickEntryBox.css
@@ -138,15 +138,30 @@ The global `.description-with-refine textarea { padding-right: 70px }` (styles.c
/*
FNXC:QuickAddWorkflow 2026-06-30-00:00:
Quick-add workflow targeting sits in the action row as a compact existing-button dropdown. Use tokenized sizing/colors so the selector wraps with Save/Plan controls on narrow Board and List surfaces without introducing a separate visual hierarchy.
+
+FNXC:QuickAddWorkflow 2026-06-30-12:38:
+Operators need workflow identity at quick-add time. Keep the trigger wide enough for realistic names, render shared WorkflowIcon output inline, and let no-icon custom workflows collapse without blank icon shells.
*/
.quick-entry-workflow-wrap {
position: relative;
display: inline-flex;
+ flex: 1 1 calc(var(--space-xl) * 8);
min-width: 0;
+ max-width: min(calc(var(--space-xl) * 11), 100%);
}
.quick-entry-workflow-trigger {
- max-width: calc(var(--space-xl) * 8);
+ display: inline-flex;
+ align-items: center;
+ justify-content: flex-start;
+ gap: var(--space-xs);
+ width: 100%;
+ min-width: 0;
+ max-width: min(calc(var(--space-xl) * 11), calc(100vw - var(--space-lg)));
+}
+
+.quick-entry-workflow-icon {
+ flex: 0 0 auto;
}
.quick-entry-workflow-label {
@@ -160,7 +175,8 @@ Quick-add workflow targeting sits in the action row as a compact existing-button
position: absolute;
inset-block-start: calc(100% + var(--space-xs));
inset-inline-start: 0;
- min-width: min(calc(var(--space-xl) * 10), calc(100vw - var(--space-lg)));
+ width: min(calc(var(--space-xl) * 16), calc(100vw - var(--space-lg)));
+ min-width: min(calc(var(--space-xl) * 14), calc(100vw - var(--space-lg)));
max-width: calc(100vw - var(--space-lg));
max-height: min(calc(var(--space-xl) * 10), calc(100vh - var(--space-xl) * 2));
overflow-y: auto;
@@ -173,6 +189,28 @@ Quick-add workflow targeting sits in the action row as a compact existing-button
background: transparent;
color: inherit;
text-align: left;
+ align-items: flex-start;
+}
+
+.quick-entry-workflow-option-copy {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2xs);
+ min-width: 0;
+}
+
+.quick-entry-workflow-option-name,
+.quick-entry-workflow-option-id {
+ min-width: 0;
+ max-width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.quick-entry-workflow-option-id {
+ color: var(--text-muted);
+ font-family: var(--font-mono);
}
@media (max-width: 768px) {
@@ -182,7 +220,8 @@ Quick-add workflow targeting sits in the action row as a compact existing-button
}
.quick-entry-workflow-menu {
- min-width: min(calc(var(--space-xl) * 9), calc(100vw - var(--space-lg)));
+ width: min(calc(var(--space-xl) * 14), calc(100vw - var(--space-lg)));
+ min-width: min(calc(var(--space-xl) * 11), calc(100vw - var(--space-lg)));
}
}
diff --git a/packages/dashboard/app/components/QuickEntryBox.tsx b/packages/dashboard/app/components/QuickEntryBox.tsx
index 18aed75475..8c9358cc66 100644
--- a/packages/dashboard/app/components/QuickEntryBox.tsx
+++ b/packages/dashboard/app/components/QuickEntryBox.tsx
@@ -16,6 +16,7 @@ import { useNodes } from "../hooks/useNodes";
import { NodeHealthDot } from "./NodeHealthDot";
import { ProviderIcon } from "./ProviderIcon";
import { WorkflowOptionalStepsDropdown } from "./WorkflowOptionalStepsDropdown";
+import { WorkflowIcon } from "./WorkflowIcon";
const STORAGE_KEY = "kb-quick-entry-text";
const ALLOWED_IMAGE_TYPES = ["image/png", "image/jpeg", "image/gif", "image/webp"];
@@ -309,6 +310,7 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels,
}, [realWorkflowOptions]);
const showWorkflowSelector = workflowId !== undefined && realWorkflowOptions.length >= 2 && quickEntryWorkflowId !== null;
const quickEntryWorkflowLabel = selectedQuickEntryWorkflow?.name ?? t("tasks.workflow", "Workflow");
+ const selectedQuickEntryWorkflowIcon = selectedQuickEntryWorkflow?.icon;
const selectedWorkflowForCreate = workflowId === undefined ? undefined : quickEntryWorkflowId;
useEffect(() => {
@@ -1693,6 +1695,12 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels,
}}
title={t("tasks.quickEntryWorkflowTitle", "Workflow for the next task")}
>
+
{quickEntryWorkflowLabel}
@@ -1719,8 +1727,11 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels,
setShowWorkflowPicker(false);
}}
>
- {option.name}
- {duplicateName ? {option.id} : null}
+
+
+ {option.name}
+ {duplicateName ? {option.id} : null}
+
);
})}
diff --git a/packages/dashboard/app/components/__tests__/QuickEntryBox.test.tsx b/packages/dashboard/app/components/__tests__/QuickEntryBox.test.tsx
index 0643a46e9a..324ff697d1 100644
--- a/packages/dashboard/app/components/__tests__/QuickEntryBox.test.tsx
+++ b/packages/dashboard/app/components/__tests__/QuickEntryBox.test.tsx
@@ -1655,6 +1655,30 @@ describe("QuickEntryBox", () => {
expect(fetchWorkflowOptionalSteps).not.toHaveBeenCalledWith("__all_workflows__", TEST_PROJECT_ID);
});
+ it("renders built-in and custom workflow icons without blank custom-icon shells", () => {
+ renderQuickEntryBox({
+ workflowId: "builtin:coding",
+ defaultWorkflowId: "builtin:coding",
+ workflowOptions: [
+ { id: "builtin:coding", name: "Coding", columns: [] },
+ { id: "wf-custom", name: "Custom workflow", icon: "🚀", columns: [] },
+ { id: "wf-no-icon", name: "No icon workflow", columns: [] },
+ ],
+ });
+
+ const trigger = screen.getByTestId("quick-entry-workflow-trigger");
+ expect(trigger.querySelector(".workflow-icon--builtin")).toBeTruthy();
+ expect(trigger.querySelector(".quick-entry-workflow-label")).toHaveTextContent("Coding");
+
+ fireEvent.click(trigger);
+ const customOption = screen.getByTestId("quick-entry-workflow-option-wf-custom");
+ expect(customOption.querySelector(".workflow-icon--custom")).toHaveTextContent("🚀");
+ expect(screen.getByTestId("quick-entry-workflow-option-wf-no-icon").querySelector(".workflow-icon")).toBeNull();
+
+ fireEvent.click(customOption);
+ expect(screen.getByTestId("quick-entry-workflow-trigger").querySelector(".workflow-icon--custom")).toHaveTextContent("🚀");
+ });
+
it("hides the selector without real workflow choices and leaves no shell", () => {
renderQuickEntryBox({ workflowId: "wf-default", workflowOptions: [{ id: "wf-default", name: "Coding", columns: [] }] });
@@ -1662,11 +1686,18 @@ describe("QuickEntryBox", () => {
expect(screen.getByTestId("quick-entry-actions").querySelector(".quick-entry-workflow-wrap")).toBeNull();
});
- it("uses tokenized responsive CSS for the workflow selector", () => {
- const selectorRule = cssRuleBody(QUICK_ENTRY_BOX_CSS, ".quick-entry-workflow-menu");
- expect(selectorRule).toContain("var(--space-");
- expect(selectorRule).not.toMatch(/#[0-9a-f]{3,8}|rgb\(/i);
- expect(QUICK_ENTRY_BOX_CSS).toMatch(/@media \(max-width: 768px\) \{[\s\S]*?quick-entry-workflow/);
+ it("uses tokenized responsive CSS for the wider workflow selector", () => {
+ const triggerRule = cssRuleBody(QUICK_ENTRY_BOX_CSS, ".quick-entry-workflow-trigger");
+ const menuRule = cssRuleBody(QUICK_ENTRY_BOX_CSS, ".quick-entry-workflow-menu");
+ const optionCopyRule = cssRuleBody(QUICK_ENTRY_BOX_CSS, ".quick-entry-workflow-option-copy");
+
+ expect(triggerRule).toContain("max-width: min(calc(var(--space-xl) * 11), calc(100vw - var(--space-lg)))");
+ expect(triggerRule).toContain("gap: var(--space-xs)");
+ expect(menuRule).toContain("width: min(calc(var(--space-xl) * 16), calc(100vw - var(--space-lg)))");
+ expect(menuRule).toContain("min-width: min(calc(var(--space-xl) * 14), calc(100vw - var(--space-lg)))");
+ expect(optionCopyRule).toContain("gap: var(--space-2xs)");
+ expect(`${triggerRule}\n${menuRule}\n${optionCopyRule}`).not.toMatch(/#[0-9a-f]{3,8}|rgb\(|\d+px/i);
+ expect(QUICK_ENTRY_BOX_CSS).toMatch(/@media \(max-width: 768px\) \{[\s\S]*?quick-entry-workflow-menu[\s\S]*?min-width: min\(calc\(var\(--space-xl\) \* 11\), calc\(100vw - var\(--space-lg\)\)\)/);
});
});