From ddbf66a34cdef72def0632e9087246a5cb0a424b Mon Sep 17 00:00:00 2001 From: Kumar Aditya Raj Date: Fri, 18 Sep 2026 16:33:39 +0530 Subject: [PATCH 1/8] quarkus flow bugs in toast and side panel Signed-off-by: Kumar Aditya Raj --- .../src/lib/download.ts | 2 -- .../open-workflow-diagram-editor/src/styles.css | 17 ++++++++++++++--- .../tests/lib/download.test.ts | 8 ++------ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/open-workflow-diagram-editor/src/lib/download.ts b/packages/open-workflow-diagram-editor/src/lib/download.ts index 6daeb23c..fe67999f 100644 --- a/packages/open-workflow-diagram-editor/src/lib/download.ts +++ b/packages/open-workflow-diagram-editor/src/lib/download.ts @@ -24,9 +24,7 @@ export function downloadFile(content: string, filename: string, mimeType = "text const link = document.createElement("a"); link.href = url; link.download = filename; - document.body.appendChild(link); link.click(); - document.body.removeChild(link); setTimeout(() => { URL.revokeObjectURL(url); }, 100); diff --git a/packages/open-workflow-diagram-editor/src/styles.css b/packages/open-workflow-diagram-editor/src/styles.css index a0bed771..e6450848 100644 --- a/packages/open-workflow-diagram-editor/src/styles.css +++ b/packages/open-workflow-diagram-editor/src/styles.css @@ -15,6 +15,20 @@ */ /* layer order (Priority: lowest -> highest) */ + +@import 'tailwindcss' prefix(dec); +@import './components/ui/shadcn.css'; +@import 'sonner/dist/styles.css'; + +@layer base { + *, + ::before, + ::after, + ::backdrop{ + --tw-border-style: solid + } +} + @layer base, side-panel, react-flow-overrides, @@ -22,9 +36,6 @@ custom-edge-labels, sonner; -@import 'tailwindcss' prefix(dec); -@import './components/ui/shadcn.css'; - @custom-variant dark (&:where(.dec-root.dark, .dec-root.dark *)); /* diff --git a/packages/open-workflow-diagram-editor/tests/lib/download.test.ts b/packages/open-workflow-diagram-editor/tests/lib/download.test.ts index d113d092..f33ef7ca 100644 --- a/packages/open-workflow-diagram-editor/tests/lib/download.test.ts +++ b/packages/open-workflow-diagram-editor/tests/lib/download.test.ts @@ -24,8 +24,6 @@ describe("downloadFile", () => { it("creates and triggers file download", () => { const mockClick = vi.fn(); - const mockAppendChild = vi.fn(); - const mockRemoveChild = vi.fn(); const mockElement = { click: mockClick, href: "", @@ -35,8 +33,6 @@ describe("downloadFile", () => { vi.spyOn(document, "createElement").mockReturnValue( mockElement as unknown as HTMLAnchorElement, ); - vi.spyOn(document.body, "appendChild").mockImplementation(mockAppendChild); - vi.spyOn(document.body, "removeChild").mockImplementation(mockRemoveChild); vi.spyOn(URL, "createObjectURL").mockReturnValue("blob:mock-url"); vi.spyOn(URL, "revokeObjectURL").mockImplementation(vi.fn()); @@ -44,8 +40,8 @@ describe("downloadFile", () => { downloadFile(testCode, "test.mmd"); expect(document.createElement).toHaveBeenCalledWith("a"); + expect(mockElement.href).toBe("blob:mock-url"); + expect(mockElement.download).toBe("test.mmd"); expect(mockClick).toHaveBeenCalled(); - expect(mockAppendChild).toHaveBeenCalled(); - expect(mockRemoveChild).toHaveBeenCalled(); }); }); From c628a7246c98602ffb1749248ffdd3c83b0e56cd Mon Sep 17 00:00:00 2001 From: Kumar Aditya Raj Date: Fri, 18 Sep 2026 16:56:09 +0530 Subject: [PATCH 2/8] copilot suggestions Signed-off-by: Kumar Aditya Raj --- .../open-workflow-diagram-editor/src/styles.css | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/open-workflow-diagram-editor/src/styles.css b/packages/open-workflow-diagram-editor/src/styles.css index e6450848..7468bb2b 100644 --- a/packages/open-workflow-diagram-editor/src/styles.css +++ b/packages/open-workflow-diagram-editor/src/styles.css @@ -21,11 +21,15 @@ @import 'sonner/dist/styles.css'; @layer base { - *, - ::before, - ::after, - ::backdrop{ - --tw-border-style: solid + .dec-root, + .dec-root *, + .dec-root::before, + .dec-root::after, + .dec-root::backdrop, + .dec-root *::before, + .dec-root *::after, + .dec-root *::backdrop { + --tw-border-style: solid; } } From a3b684e7ad67e7107b4557ec364503664fa1c2d0 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Raj Date: Tue, 22 Sep 2026 15:26:00 +0530 Subject: [PATCH 3/8] Removed toast notification Signed-off-by: Kumar Aditya Raj --- .../open-workflow-diagram-editor/package.json | 1 - .../src/components/ui/sonner.css | 40 ----------- .../src/components/ui/sonner.tsx | 51 -------------- .../src/diagram-editor/DiagramEditor.tsx | 2 - .../src/i18n/locales/en.ts | 5 +- .../src/side-panel/WorkflowActions.tsx | 67 ++++++++++++++----- .../src/styles.css | 2 - .../tests/side-panel/WorkflowActions.test.tsx | 32 +++------ pnpm-lock.yaml | 23 ------- pnpm-workspace.yaml | 1 - 10 files changed, 63 insertions(+), 161 deletions(-) delete mode 100644 packages/open-workflow-diagram-editor/src/components/ui/sonner.css delete mode 100644 packages/open-workflow-diagram-editor/src/components/ui/sonner.tsx diff --git a/packages/open-workflow-diagram-editor/package.json b/packages/open-workflow-diagram-editor/package.json index 3e5285e5..d77b79e8 100644 --- a/packages/open-workflow-diagram-editor/package.json +++ b/packages/open-workflow-diagram-editor/package.json @@ -52,7 +52,6 @@ "html-to-image": "catalog:", "js-yaml": "catalog:", "radix-ui": "catalog:", - "sonner": "catalog:", "use-sync-external-store": "catalog:" }, "devDependencies": { diff --git a/packages/open-workflow-diagram-editor/src/components/ui/sonner.css b/packages/open-workflow-diagram-editor/src/components/ui/sonner.css deleted file mode 100644 index 661b1784..00000000 --- a/packages/open-workflow-diagram-editor/src/components/ui/sonner.css +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021-Present The Open Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - @reference "../../styles.css"; - -@layer sonner { - /* sonner defaults unlayered, so these overrides need !important */ - .dec-root [data-sonner-toaster] { --width: 300px !important; } - .dec-root [data-sonner-toast] { background: var(--dec-toast-bg) !important; border-radius: 10px !important; border: 1px solid var(--dec-toast-border) !important; } - .dec-root [data-sonner-toast][data-type="success"] { border-left: 4px solid var(--dec-toast-success) !important; } - .dec-root [data-sonner-toast][data-type="error"] { border-left: 4px solid var(--dec-error-accent) !important; } - .dec-root [data-sonner-toast][data-type="warning"] { border-left: 4px solid var(--dec-toast-warning) !important; } - .dec-root [data-sonner-toast][data-type="info"] { border-left: 4px solid var(--dec-toast-info) !important; } - .dec-root [data-sonner-toast] [data-title], .dec-root [data-sonner-toast] [data-description] { color: var(--dec-toast-text) !important; } - .dec-root [data-sonner-toast] [data-close-button] { - position: absolute !important; - top: 50% !important; - right: 12px !important; - left: auto !important; - transform: translateY(-50%) !important; - background: transparent !important; - border: none !important; - box-shadow: none !important; - color: var(--dec-toast-close-btn); - cursor: pointer; - } -} diff --git a/packages/open-workflow-diagram-editor/src/components/ui/sonner.tsx b/packages/open-workflow-diagram-editor/src/components/ui/sonner.tsx deleted file mode 100644 index e8de5262..00000000 --- a/packages/open-workflow-diagram-editor/src/components/ui/sonner.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2021-Present The Open Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - CircleCheckIcon, - InfoIcon, - Loader2Icon, - OctagonXIcon, - TriangleAlertIcon, - XIcon, -} from "lucide-react"; -import { Toaster as Sonner, type ToasterProps } from "sonner"; -import "./sonner.css"; - -const Toaster = ({ ...props }: ToasterProps) => { - return ( - - ), - info: , - warning: ( - - ), - error: , - loading: , - close: , - }} - {...props} - /> - ); -}; - -export { Toaster }; diff --git a/packages/open-workflow-diagram-editor/src/diagram-editor/DiagramEditor.tsx b/packages/open-workflow-diagram-editor/src/diagram-editor/DiagramEditor.tsx index dafad7fe..572d0d07 100644 --- a/packages/open-workflow-diagram-editor/src/diagram-editor/DiagramEditor.tsx +++ b/packages/open-workflow-diagram-editor/src/diagram-editor/DiagramEditor.tsx @@ -27,7 +27,6 @@ import { useResolvedColorMode } from "../hooks/useResolvedColorMode"; import { SidebarProvider } from "@/components/ui/sidebar"; import { SidePanel } from "@/side-panel/SidePanel"; import { DiagramEditorErrorBoundary } from "./error-pages/DiagramEditorErrorBoundary"; -import { Toaster } from "@/components/ui/sonner"; /** * Imperative handle exposed by `DiagramEditor` via `ref`. @@ -184,7 +183,6 @@ export const DiagramEditor = React.forwardRef - ); }, diff --git a/packages/open-workflow-diagram-editor/src/i18n/locales/en.ts b/packages/open-workflow-diagram-editor/src/i18n/locales/en.ts index 4dbe7c83..008634d9 100644 --- a/packages/open-workflow-diagram-editor/src/i18n/locales/en.ts +++ b/packages/open-workflow-diagram-editor/src/i18n/locales/en.ts @@ -43,7 +43,9 @@ export const en = { "sidebar.exportMermaid.copy": "Copy Mermaid Code", "sidebar.exportMermaid.download": "Download as Mermaid File", "sidebar.exportMermaid.copied": "Copied!", + "sidebar.export.downloaded": "Downloaded", "sidebar.exportPng.download": "Download as PNG", + "sidebar.exportPng.downloading": "Downloading...", "aria.minimap.hide": "Hide minimap", "aria.minimap.show": "Show minimap", "aria.badge": "Badge:", @@ -53,9 +55,6 @@ export const en = { "aria.panel.exportActions": "Export actions", "workflowError.autoLayout.title": "Layout Error", "workflowError.autoLayout.message": "Failed to apply auto-layout to the diagram.", - "toast.clipboard.error": "Failed to copy", - "toast.download.success": "Download started", - "toast.download.error": "Download failed", } as const; export type TranslationKeys = keyof typeof en; diff --git a/packages/open-workflow-diagram-editor/src/side-panel/WorkflowActions.tsx b/packages/open-workflow-diagram-editor/src/side-panel/WorkflowActions.tsx index acc83562..b0e3e61c 100644 --- a/packages/open-workflow-diagram-editor/src/side-panel/WorkflowActions.tsx +++ b/packages/open-workflow-diagram-editor/src/side-panel/WorkflowActions.tsx @@ -16,7 +16,7 @@ import * as React from "react"; import { useI18n } from "@openworkflowspec/i18n"; -import { ClipboardPen, Download, ClipboardCheck, FileImage } from "lucide-react"; +import { ClipboardPen, Download, ClipboardCheck, FileImage, Import } from "lucide-react"; import { useReactFlow, useStore } from "@xyflow/react"; import { Button } from "@/components/ui/button"; import { exportToMermaid } from "@/core"; @@ -26,12 +26,13 @@ import { exportDiagramAsPng } from "@/lib/exportPng"; import { sanitizeFilename } from "@/lib/utils"; import { useDiagramEditorContext } from "@/store/DiagramEditorContext"; import type { Specification } from "@openworkflowspec/sdk"; -import { toast } from "sonner"; export function WorkflowActions({ model }: { model: Specification.Workflow }): React.JSX.Element { const { t } = useI18n(); const [isCopied, setIsCopied] = React.useState(false); + const [downloadedType, setDownloadedType] = React.useState<"mermaid" | "png" | null>(null); const copyTimeoutRef = React.useRef | null>(null); + const downloadTimeoutRef = React.useRef | null>(null); const reactFlowInstance = useReactFlow(); const diagramDomNode = useStore((s) => s.domNode); const { isExporting, setIsExporting } = useDiagramEditorContext(); @@ -41,6 +42,10 @@ export function WorkflowActions({ model }: { model: Specification.Workflow }): R if (copyTimeoutRef.current) { clearTimeout(copyTimeoutRef.current); } + + if (downloadTimeoutRef.current) { + clearTimeout(downloadTimeoutRef.current); + } }; }, []); @@ -59,9 +64,10 @@ export function WorkflowActions({ model }: { model: Specification.Workflow }): R copyTimeoutRef.current = null; }, 2000); } catch (error) { - toast.error(t("toast.clipboard.error"), { - description: error instanceof Error ? error.message : undefined, - }); + console.error( + "Failed to copy Mermaid code:", + error instanceof Error ? error.message : undefined, + ); } }; @@ -70,11 +76,21 @@ export function WorkflowActions({ model }: { model: Specification.Workflow }): R const mermaidCode = exportToMermaid(model); const filename = `${sanitizeFilename(model.document?.name)}.mmd`; downloadFile(mermaidCode, filename); - toast.success(t("toast.download.success")); + setDownloadedType("mermaid"); + + if (downloadTimeoutRef.current) { + clearTimeout(downloadTimeoutRef.current); + } + + downloadTimeoutRef.current = setTimeout(() => { + setDownloadedType(null); + downloadTimeoutRef.current = null; + }, 2000); } catch (error) { - toast.error(t("toast.download.error"), { - description: error instanceof Error ? error.message : undefined, - }); + console.error( + "Failed to download Mermaid file:", + error instanceof Error ? error.message : undefined, + ); } }; @@ -86,11 +102,22 @@ export function WorkflowActions({ model }: { model: Specification.Workflow }): R `${sanitizeFilename(model.document?.name)}.png`, diagramDomNode, ); - toast.success(t("toast.download.success")); + + setDownloadedType("png"); + + if (downloadTimeoutRef.current) { + clearTimeout(downloadTimeoutRef.current); + } + + downloadTimeoutRef.current = setTimeout(() => { + setDownloadedType(null); + downloadTimeoutRef.current = null; + }, 2000); } catch (error) { - toast.error(t("toast.download.error"), { - description: error instanceof Error ? error.message : undefined, - }); + console.error( + "Failed to export diagram as PNG:", + error instanceof Error ? error.message : undefined, + ); } finally { setIsExporting(false); } @@ -113,8 +140,10 @@ export function WorkflowActions({ model }: { model: Specification.Workflow }): R size="sm" className="dec:cursor-pointer" > - - {t("sidebar.exportMermaid.download")} + {downloadedType === "mermaid" ? : } + {downloadedType === "mermaid" + ? t("sidebar.export.downloaded") + : t("sidebar.exportMermaid.download")} ); diff --git a/packages/open-workflow-diagram-editor/src/styles.css b/packages/open-workflow-diagram-editor/src/styles.css index 7468bb2b..36d65935 100644 --- a/packages/open-workflow-diagram-editor/src/styles.css +++ b/packages/open-workflow-diagram-editor/src/styles.css @@ -18,7 +18,6 @@ @import 'tailwindcss' prefix(dec); @import './components/ui/shadcn.css'; -@import 'sonner/dist/styles.css'; @layer base { .dec-root, @@ -38,7 +37,6 @@ react-flow-overrides, custom-nodes, custom-edge-labels, - sonner; @custom-variant dark (&:where(.dec-root.dark, .dec-root.dark *)); diff --git a/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx b/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx index 6eb63bd7..3ad31c01 100644 --- a/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx +++ b/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx @@ -25,7 +25,6 @@ import * as clipboard from "../../src/lib/clipboard"; import * as core from "../../src/core"; import * as download from "../../src/lib/download"; import * as exportPng from "../../src/lib/exportPng"; -import * as sonner from "sonner"; describe("WorkflowActions", () => { const toastMock = vi.fn(); @@ -58,8 +57,6 @@ describe("WorkflowActions", () => { const { model } = parseWorkflow(WORKFLOW_WITH_METADATA_JSON); vi.spyOn(clipboard, "copyToClipboard").mockRejectedValue(new Error("Clipboard error")); vi.spyOn(core, "exportToMermaid").mockReturnValue(MERMAID_CODE); - vi.spyOn(sonner.toast, "error").mockImplementation(toastMock); - vi.spyOn(sonner.toast, "success").mockImplementation(toastMock); renderWithProviders(, { model }); @@ -69,7 +66,7 @@ describe("WorkflowActions", () => { await user.click(copyButton); - expect(toastMock).toHaveBeenCalledWith(expect.any(String), { description: "Clipboard error" }); + expect(clipboard.copyToClipboard).toHaveBeenCalledWith(MERMAID_CODE); }); it("should call downloadMermaidFile and show success toast when download button is clicked", async () => { @@ -77,8 +74,6 @@ describe("WorkflowActions", () => { const { model } = parseWorkflow(WORKFLOW_WITH_METADATA_JSON); const downloadSpy = vi.spyOn(download, "downloadFile").mockImplementation(() => {}); vi.spyOn(core, "exportToMermaid").mockReturnValue(MERMAID_CODE); - vi.spyOn(sonner.toast, "error").mockImplementation(toastMock); - vi.spyOn(sonner.toast, "success").mockImplementation(toastMock); renderWithProviders(, { model }); @@ -89,18 +84,16 @@ describe("WorkflowActions", () => { await user.click(downloadButton); expect(downloadSpy).toHaveBeenCalledWith(MERMAID_CODE, "test-wf.mmd"); - expect(toastMock).toHaveBeenCalledWith(expect.any(String)); + expect(screen.getByRole("button", { name: "Downloaded" })).toBeInTheDocument(); }); - it("should show error toast when download fails", async () => { + it("should handle download failure", async () => { const user = userEvent.setup(); const { model } = parseWorkflow(WORKFLOW_WITH_METADATA_JSON); vi.spyOn(download, "downloadFile").mockImplementation(() => { throw new Error("Download error"); }); vi.spyOn(core, "exportToMermaid").mockReturnValue(MERMAID_CODE); - vi.spyOn(sonner.toast, "error").mockImplementation(toastMock); - vi.spyOn(sonner.toast, "success").mockImplementation(toastMock); renderWithProviders(, { model }); @@ -110,7 +103,7 @@ describe("WorkflowActions", () => { await user.click(downloadButton); - expect(toastMock).toHaveBeenCalledWith(expect.any(String), { description: "Download error" }); + expect(download.downloadFile).toHaveBeenCalledWith(MERMAID_CODE, "test-wf.mmd"); }); it("should disable the PNG button when isExporting is true", () => { @@ -118,16 +111,17 @@ describe("WorkflowActions", () => { renderWithProviders(, { model, isExporting: true }); - expect(screen.getByRole("button", { name: /Download as PNG/i })).toBeDisabled(); + const pngButton = screen.getByRole("button", { + name: "Downloading...", + }); + expect(pngButton).toBeDisabled(); }); - it("should call exportDiagramAsPng with sanitized filename and show success toast", async () => { + it("should call exportDiagramAsPng with sanitized filename and show downloaded state", async () => { const user = userEvent.setup(); const { model } = parseWorkflow(WORKFLOW_WITH_METADATA_JSON); const exportSpy = vi.spyOn(exportPng, "exportDiagramAsPng").mockResolvedValue(undefined); const setIsExporting = vi.fn(); - vi.spyOn(sonner.toast, "error").mockImplementation(toastMock); - vi.spyOn(sonner.toast, "success").mockImplementation(toastMock); renderWithProviders(, { model, setIsExporting }); @@ -135,24 +129,20 @@ describe("WorkflowActions", () => { await vi.waitFor(() => expect(exportSpy).toHaveBeenCalled()); expect(exportSpy).toHaveBeenCalledWith(expect.anything(), "test-wf.png", null); - expect(toastMock).toHaveBeenCalledWith(expect.any(String)); + expect(screen.getByRole("button", { name: "Downloaded" })).toBeInTheDocument(); expect(setIsExporting).toHaveBeenCalledWith(true); expect(setIsExporting).toHaveBeenLastCalledWith(false); }); - it("should show error toast and still reset isExporting when PNG export fails", async () => { + it("should reset isExporting when PNG export fails", async () => { const user = userEvent.setup(); const { model } = parseWorkflow(WORKFLOW_WITH_METADATA_JSON); vi.spyOn(exportPng, "exportDiagramAsPng").mockRejectedValue(new Error("Export failed")); const setIsExporting = vi.fn(); - vi.spyOn(sonner.toast, "error").mockImplementation(toastMock); - vi.spyOn(sonner.toast, "success").mockImplementation(toastMock); renderWithProviders(, { model, setIsExporting }); await user.click(screen.getByRole("button", { name: /Download as PNG/i })); await vi.waitFor(() => expect(setIsExporting).toHaveBeenLastCalledWith(false)); - - expect(toastMock).toHaveBeenCalledWith(expect.any(String), { description: "Export failed" }); }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 811b2361..c325e1ea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,9 +132,6 @@ catalogs: rimraf: specifier: ^6.1.3 version: 6.1.3 - sonner: - specifier: ^2.0.8 - version: 2.0.8 storybook: specifier: ^10.6.0 version: 10.6.0 @@ -349,9 +346,6 @@ importers: radix-ui: specifier: 'catalog:' version: 1.6.7(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) - sonner: - specifier: 'catalog:' - version: 2.0.8(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) use-sync-external-store: specifier: 'catalog:' version: 1.7.0(react@19.3.0) @@ -3732,16 +3726,6 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - sonner@2.0.8: - resolution: {integrity: sha512-UM/ByIoFra8yzV75n1o0Puu0bw5U/9UNnDacrJNspekBewIfsQ3D6ez1nvlWpt7aTsO6rujQtifBpycwIivqlg==} - peerDependencies: - '@types/react': ^18.0.0 || ^19.0.0 - react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc - react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -7102,13 +7086,6 @@ snapshots: sisteransi@1.0.5: {} - sonner@2.0.8(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0): - dependencies: - react: 19.3.0 - react-dom: 19.3.0(react@19.3.0) - optionalDependencies: - '@types/react': 19.3.0 - source-map-js@1.2.1: {} source-map@0.6.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index d3d94c06..6e18b6c7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -44,7 +44,6 @@ catalog: react: ^19.3.0 react-dom: ^19.3.0 rimraf: ^6.1.3 - sonner: ^2.0.8 storybook: ^10.6.0 syncpack: ^15.3.3 tailwindcss: ^4.3.3 From 5bdac0df5b123ce2083190c46980f06efeb006c8 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Raj Date: Tue, 22 Sep 2026 15:28:26 +0530 Subject: [PATCH 4/8] changeset Signed-off-by: Kumar Aditya Raj --- .changeset/toast-notification-removed.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/toast-notification-removed.md diff --git a/.changeset/toast-notification-removed.md b/.changeset/toast-notification-removed.md new file mode 100644 index 00000000..33829dd7 --- /dev/null +++ b/.changeset/toast-notification-removed.md @@ -0,0 +1,5 @@ +--- +"@openworkflowspec/diagram-editor": minor +--- + +Toast notification removed for side panel buttons From e2d378d82623d4946f0dc663052c5d3a1980c754 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Raj Date: Tue, 22 Sep 2026 15:35:23 +0530 Subject: [PATCH 5/8] copilot suggestions Signed-off-by: Kumar Aditya Raj --- packages/open-workflow-diagram-editor/src/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/open-workflow-diagram-editor/src/styles.css b/packages/open-workflow-diagram-editor/src/styles.css index 36d65935..7d28037f 100644 --- a/packages/open-workflow-diagram-editor/src/styles.css +++ b/packages/open-workflow-diagram-editor/src/styles.css @@ -36,7 +36,7 @@ side-panel, react-flow-overrides, custom-nodes, - custom-edge-labels, + custom-edge-labels; @custom-variant dark (&:where(.dec-root.dark, .dec-root.dark *)); From a4b593a38b346d1d23a32f3dba3ba872d23f20f6 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Raj Date: Fri, 25 Sep 2026 13:58:54 +0530 Subject: [PATCH 6/8] button text changes Signed-off-by: Kumar Aditya Raj --- .../src/i18n/locales/en.ts | 3 +-- .../src/side-panel/WorkflowActions.tsx | 24 +++++++++---------- .../tests/side-panel/WorkflowActions.test.tsx | 6 ++--- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/open-workflow-diagram-editor/src/i18n/locales/en.ts b/packages/open-workflow-diagram-editor/src/i18n/locales/en.ts index 008634d9..ff8cdae7 100644 --- a/packages/open-workflow-diagram-editor/src/i18n/locales/en.ts +++ b/packages/open-workflow-diagram-editor/src/i18n/locales/en.ts @@ -43,9 +43,8 @@ export const en = { "sidebar.exportMermaid.copy": "Copy Mermaid Code", "sidebar.exportMermaid.download": "Download as Mermaid File", "sidebar.exportMermaid.copied": "Copied!", - "sidebar.export.downloaded": "Downloaded", "sidebar.exportPng.download": "Download as PNG", - "sidebar.exportPng.downloading": "Downloading...", + "sidebar.export.downloading": "Downloading", "aria.minimap.hide": "Hide minimap", "aria.minimap.show": "Show minimap", "aria.badge": "Badge:", diff --git a/packages/open-workflow-diagram-editor/src/side-panel/WorkflowActions.tsx b/packages/open-workflow-diagram-editor/src/side-panel/WorkflowActions.tsx index b0e3e61c..fa456e40 100644 --- a/packages/open-workflow-diagram-editor/src/side-panel/WorkflowActions.tsx +++ b/packages/open-workflow-diagram-editor/src/side-panel/WorkflowActions.tsx @@ -30,7 +30,7 @@ import type { Specification } from "@openworkflowspec/sdk"; export function WorkflowActions({ model }: { model: Specification.Workflow }): React.JSX.Element { const { t } = useI18n(); const [isCopied, setIsCopied] = React.useState(false); - const [downloadedType, setDownloadedType] = React.useState<"mermaid" | "png" | null>(null); + const [downloadingType, setDownloadingType] = React.useState<"mermaid" | "png" | null>(null); const copyTimeoutRef = React.useRef | null>(null); const downloadTimeoutRef = React.useRef | null>(null); const reactFlowInstance = useReactFlow(); @@ -76,14 +76,14 @@ export function WorkflowActions({ model }: { model: Specification.Workflow }): R const mermaidCode = exportToMermaid(model); const filename = `${sanitizeFilename(model.document?.name)}.mmd`; downloadFile(mermaidCode, filename); - setDownloadedType("mermaid"); + setDownloadingType("mermaid"); if (downloadTimeoutRef.current) { clearTimeout(downloadTimeoutRef.current); } downloadTimeoutRef.current = setTimeout(() => { - setDownloadedType(null); + setDownloadingType(null); downloadTimeoutRef.current = null; }, 2000); } catch (error) { @@ -103,14 +103,14 @@ export function WorkflowActions({ model }: { model: Specification.Workflow }): R diagramDomNode, ); - setDownloadedType("png"); + setDownloadingType("png"); if (downloadTimeoutRef.current) { clearTimeout(downloadTimeoutRef.current); } downloadTimeoutRef.current = setTimeout(() => { - setDownloadedType(null); + setDownloadingType(null); downloadTimeoutRef.current = null; }, 2000); } catch (error) { @@ -140,9 +140,9 @@ export function WorkflowActions({ model }: { model: Specification.Workflow }): R size="sm" className="dec:cursor-pointer" > - {downloadedType === "mermaid" ? : } - {downloadedType === "mermaid" - ? t("sidebar.export.downloaded") + {downloadingType === "mermaid" ? : } + {downloadingType === "mermaid" + ? t("sidebar.export.downloading") : t("sidebar.exportMermaid.download")} diff --git a/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx b/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx index 3ad31c01..faa8c0a4 100644 --- a/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx +++ b/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx @@ -84,7 +84,7 @@ describe("WorkflowActions", () => { await user.click(downloadButton); expect(downloadSpy).toHaveBeenCalledWith(MERMAID_CODE, "test-wf.mmd"); - expect(screen.getByRole("button", { name: "Downloaded" })).toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Downloading" })).toBeInTheDocument(); }); it("should handle download failure", async () => { @@ -112,7 +112,7 @@ describe("WorkflowActions", () => { renderWithProviders(, { model, isExporting: true }); const pngButton = screen.getByRole("button", { - name: "Downloading...", + name: "Downloading", }); expect(pngButton).toBeDisabled(); }); @@ -129,7 +129,7 @@ describe("WorkflowActions", () => { await vi.waitFor(() => expect(exportSpy).toHaveBeenCalled()); expect(exportSpy).toHaveBeenCalledWith(expect.anything(), "test-wf.png", null); - expect(screen.getByRole("button", { name: "Downloaded" })).toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Downloading" })).toBeInTheDocument(); expect(setIsExporting).toHaveBeenCalledWith(true); expect(setIsExporting).toHaveBeenLastCalledWith(false); }); From 846cf757f9835f5d256e4fd1c1880e7d270350c5 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Raj Date: Fri, 25 Sep 2026 14:15:49 +0530 Subject: [PATCH 7/8] removed redundant code related to toast notification Signed-off-by: Kumar Aditya Raj --- .../src/styles.css | 18 ------------------ .../tests/side-panel/WorkflowActions.test.tsx | 6 ++---- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/packages/open-workflow-diagram-editor/src/styles.css b/packages/open-workflow-diagram-editor/src/styles.css index 7d28037f..94522092 100644 --- a/packages/open-workflow-diagram-editor/src/styles.css +++ b/packages/open-workflow-diagram-editor/src/styles.css @@ -93,15 +93,6 @@ --dec-minimap-node-stroke: #64748b; --dec-minimap-border: #cbd5e1; --dec-minimap-shadow: rgba(15, 23, 42, 0.12); - - /* toast */ - --dec-toast-bg: #ffffff; - --dec-toast-border: #e9edf4; - --dec-toast-success: #22c55e; - --dec-toast-warning: #f97316; - --dec-toast-info: #3b82f6; - --dec-toast-close-btn: #6b7280; - --dec-toast-text: #1f2328; } .dec-root.dark { @@ -126,15 +117,6 @@ --dec-minimap-node-stroke: #cbd5e1; --dec-minimap-border: var(--dec-surface-dark-elevated); --dec-minimap-shadow: rgba(0, 0, 0, 0.5); - - /* toast */ - --dec-toast-bg: #2d3748; - --dec-toast-border: #4a5568; - --dec-toast-success: #4ade80; - --dec-toast-warning: #fb923c; - --dec-toast-info: #60a5fa; - --dec-toast-close-btn: #ffffff; - --dec-toast-text: #ffffff; } .dec-root .dec-diagram-content { diff --git a/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx b/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx index faa8c0a4..ead1ccc1 100644 --- a/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx +++ b/packages/open-workflow-diagram-editor/tests/side-panel/WorkflowActions.test.tsx @@ -27,11 +27,9 @@ import * as download from "../../src/lib/download"; import * as exportPng from "../../src/lib/exportPng"; describe("WorkflowActions", () => { - const toastMock = vi.fn(); const MERMAID_CODE = "mermaid code"; afterEach(() => { - toastMock.mockClear(); vi.restoreAllMocks(); }); @@ -52,7 +50,7 @@ describe("WorkflowActions", () => { expect(copySpy).toHaveBeenCalledWith(MERMAID_CODE); }); - it("should show error toast when clipboard copy fails", async () => { + it("should show error message when clipboard copy fails", async () => { const user = userEvent.setup(); const { model } = parseWorkflow(WORKFLOW_WITH_METADATA_JSON); vi.spyOn(clipboard, "copyToClipboard").mockRejectedValue(new Error("Clipboard error")); @@ -69,7 +67,7 @@ describe("WorkflowActions", () => { expect(clipboard.copyToClipboard).toHaveBeenCalledWith(MERMAID_CODE); }); - it("should call downloadMermaidFile and show success toast when download button is clicked", async () => { + it("should call downloadMermaidFile and show Downloading when download button is clicked", async () => { const user = userEvent.setup(); const { model } = parseWorkflow(WORKFLOW_WITH_METADATA_JSON); const downloadSpy = vi.spyOn(download, "downloadFile").mockImplementation(() => {}); From 9627aeee17168aa201f0a1837c0b2e87580d171c Mon Sep 17 00:00:00 2001 From: Kumar Aditya Raj Date: Fri, 25 Sep 2026 14:26:33 +0530 Subject: [PATCH 8/8] css changes Signed-off-by: Kumar Aditya Raj --- .../open-workflow-diagram-editor/src/styles.css | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/open-workflow-diagram-editor/src/styles.css b/packages/open-workflow-diagram-editor/src/styles.css index 94522092..0d087859 100644 --- a/packages/open-workflow-diagram-editor/src/styles.css +++ b/packages/open-workflow-diagram-editor/src/styles.css @@ -16,9 +16,17 @@ /* layer order (Priority: lowest -> highest) */ +@layer base, + side-panel, + react-flow-overrides, + custom-nodes, + custom-edge-labels; + @import 'tailwindcss' prefix(dec); @import './components/ui/shadcn.css'; +@custom-variant dark (&:where(.dec-root.dark, .dec-root.dark *)); + @layer base { .dec-root, .dec-root *, @@ -32,13 +40,6 @@ } } -@layer base, - side-panel, - react-flow-overrides, - custom-nodes, - custom-edge-labels; - -@custom-variant dark (&:where(.dec-root.dark, .dec-root.dark *)); /* This file defines global styles for the editor.