From 3036b8d7889fb953dd578abc9d58151c5e8b741d Mon Sep 17 00:00:00 2001 From: DongHyeonka Date: Tue, 25 Aug 2026 17:05:14 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20Ctrl+S=20=EB=A1=9C=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 브라우저의 Ctrl+S 는 "페이지를 파일로 저장"이다. 글을 쓰다가 그 손버릇이 나오면 저장 대화상자가 뜨고 편집한 내용은 그대로 남는다 — 저장한 줄 알고 창을 닫으면 잃는다. 문서·프로젝트·릴리즈 세 편집기에서 기본 동작을 막고 그 화면의 저장으로 돌린다. 저장할 것이 없을 때도 기본 동작은 막는다. 막지 않으면 "저장할 것이 없다"는 화면 상태와 브라우저의 저장 대화상자가 동시에 나와, 무엇이 일어났는지 알 수 없다. Ctrl+Shift+S 와 Alt 조합은 가로채지 않는다 — 다른 뜻으로 쓰는 곳이 있다. 버튼에 단축키를 적어 둔다. 단축키는 알려 주지 않으면 없는 것과 같다. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01XEHXspz4rv5pB5wiiSsVDu --- .../components/document-editor-screen.tsx | 7 ++ .../components/document-status-rail.tsx | 4 +- .../studio/components/project-editor.tsx | 9 +- .../studio/components/release-editor.tsx | 4 + .../studio/components/use-save-shortcut.ts | 29 ++++++ .../features/tech-log/save-shortcut.test.tsx | 91 +++++++++++++++++++ 6 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 src/features/tech-log/presentation/studio/components/use-save-shortcut.ts create mode 100644 tests/features/tech-log/save-shortcut.test.tsx diff --git a/src/features/tech-log/presentation/studio/components/document-editor-screen.tsx b/src/features/tech-log/presentation/studio/components/document-editor-screen.tsx index 84227e5..d383042 100644 --- a/src/features/tech-log/presentation/studio/components/document-editor-screen.tsx +++ b/src/features/tech-log/presentation/studio/components/document-editor-screen.tsx @@ -15,6 +15,7 @@ import { DocumentEditor } from "./document-editor.tsx"; import { GuardedStudioLink } from "./guarded-studio-link.tsx"; import { deriveValidationState } from "../../../domain/studio/document-state.ts"; import { slugFromName } from "./slug-from-name.ts"; +import { useSaveShortcut } from "./use-save-shortcut.ts"; import { useStudio, useStudioEditorSession } from "../use-studio.ts"; type CatalogEntry = components["schemas"]["CatalogEntry"]; @@ -176,6 +177,12 @@ export function DocumentEditorScreen({ documentId }: { documentId: string }) { } }, [begin, editor, setStatus, studio]); + /* + `save` 가 스스로 CLEAN·SAVING·CONFLICT 를 걸러 내므로 단축키는 늘 열어 둔다 — 저장할 것이 + 없을 때 눌러도 아무 일도 일어나지 않는다. + */ + useSaveShortcut(save); + /** * 저장 → 검증 → 미리보기 → 게시를 한 번에 수행한다. * diff --git a/src/features/tech-log/presentation/studio/components/document-status-rail.tsx b/src/features/tech-log/presentation/studio/components/document-status-rail.tsx index b08e2a1..69bd81b 100644 --- a/src/features/tech-log/presentation/studio/components/document-status-rail.tsx +++ b/src/features/tech-log/presentation/studio/components/document-status-rail.tsx @@ -33,7 +33,7 @@ export function DocumentStatusRail({

작업 상태

{labels[controller.status]}

저장 버전
{controller.saved.version}
종류
{kindLabels[controller.draft.kind]}
- + {/* 버튼은 저장과 게시 둘뿐이다. 예전에는 게시까지 검증 → 미리보기 → 게시 세 화면을 차례로 밟아야 했다 — 백엔드가 게시 요청에 신선한 검증 id 와 미리보기 id, 그리고 현재 경고를 모두 @@ -63,7 +63,7 @@ export function DocumentStatusRail({ ) : controller.publishError ? (

{controller.publishError}

) : ( -

불완전한 초안도 저장할 수 있습니다. 게시를 누르면 채워야 할 칸을 그 자리에 표시합니다.

+

불완전한 초안도 저장할 수 있습니다. Ctrl+S 로도 저장합니다. 게시를 누르면 채워야 할 칸을 그 자리에 표시합니다.

)} {unplacedIssues.length ? (