From 04084049261c374db5e23b065baa56d77eaf973f Mon Sep 17 00:00:00 2001 From: yun Date: Mon, 6 Jul 2026 17:13:15 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=A4=A7=E5=B0=8F=E5=A4=84?= =?UTF-8?q?=E7=90=86=20=E7=82=B9=E5=87=BB=E7=94=BB=E5=B8=83=E5=A4=B1?= =?UTF-8?q?=E7=84=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Header.tsx | 28 ++++++- .../__tests__/FloatingNodeHeader.test.tsx | 73 ++++++++++++++++++- .../__tests__/GenerateImageNode.test.tsx | 2 + src/components/__tests__/Header.test.tsx | 18 ++++- src/components/nodes/FloatingNodeHeader.tsx | 34 ++++++++- src/components/nodes/GenerateImageNode.tsx | 14 +--- src/hooks/useCommitOnOutsidePointerDown.ts | 28 +++++++ src/store/workflowStore.ts | 17 ++++- 8 files changed, 190 insertions(+), 24 deletions(-) create mode 100644 src/hooks/useCommitOnOutsidePointerDown.ts diff --git a/src/components/Header.tsx b/src/components/Header.tsx index a4349f30..a3c11fc1 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useMemo, useCallback, useEffect, type ReactNode } from "react"; +import { useState, useMemo, useCallback, useEffect, useRef, type ReactNode } from "react"; import Link from "next/link"; import { useSearchParams } from "next/navigation"; import { @@ -16,6 +16,7 @@ import { CostIndicator } from "./CostIndicator"; import { useI18n } from "@/i18n"; import { buildSerializedWorkflow } from "@/store/utils/workflowSerialization"; import { HeaderUserMenu } from "@/components/auth/HeaderUserMenu"; +import { useCommitOnOutsidePointerDown } from "@/hooks/useCommitOnOutsidePointerDown"; const SHOW_UNUSED_HEADER_ACTIONS = false; @@ -123,6 +124,9 @@ export function Header() { const [showSettingsModal, setShowSettingsModal] = useState(false); const [workflowNameDraft, setWorkflowNameDraft] = useState(workflowName || ""); + const [isEditingWorkflowName, setIsEditingWorkflowName] = useState(false); + const workflowNameEditorRef = useRef(null); + const lastCommittedWorkflowNameDraftRef = useRef(null); const currentCanvasWorkflowDescription = useCanvasWorkflowStore((state) => state.currentCanvasWorkflowDescription); const setCurrentCanvasWorkflow = useCanvasWorkflowStore((state) => state.setCurrentCanvasWorkflow); @@ -159,12 +163,20 @@ export function Header() { const commitWorkflowName = useCallback(() => { const nextName = workflowNameDraft.trim(); + if (lastCommittedWorkflowNameDraftRef.current === nextName) { + setIsEditingWorkflowName(false); + return; + } + lastCommittedWorkflowNameDraftRef.current = nextName; + if (!nextName || nextName === workflowName) { setWorkflowNameDraft(workflowName || ""); + setIsEditingWorkflowName(false); return; } setWorkflowName(nextName); + setIsEditingWorkflowName(false); if (urlWorkflowId) { setCurrentCanvasWorkflow({ title: nextName, @@ -180,6 +192,12 @@ export function Header() { setCurrentCanvasWorkflow, ]); + useCommitOnOutsidePointerDown({ + active: isEditingWorkflowName, + rootRef: workflowNameEditorRef, + onCommit: commitWorkflowName, + }); + const handleRevertAIChanges = useCallback(() => { const confirmed = window.confirm( t("header.revertConfirm") @@ -205,7 +223,7 @@ export function Header() {
-
+