From 57bf6a012df13a8062545bcd324cbeb0ee9667d9 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Thu, 4 Jun 2026 04:31:23 +0000 Subject: [PATCH 1/6] refactor: update UI terminology to Naruon guidelines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Map 'AI Summary' to '맥락 종합' - Map 'Insight' to '판단 포인트' - Map 'Todo' to '실행 항목' - Map 'Calendar Sync' to '일정 반영' - Map 'Dashboard' to '홈' - Map 'Email' to '메일' - Update related test cases and e2e specs to reflect new text - Fix grammatical postpositions for Korean strings --- frontend/src/app/ai-hub/page.test.tsx | 8 +-- frontend/src/app/layout.test.tsx | 2 +- frontend/src/app/layout.tsx | 2 +- frontend/src/app/page.test.tsx | 16 +++--- frontend/src/app/prompt-studio/page.tsx | 2 +- frontend/src/app/tasks/page.test.tsx | 4 +- .../src/components/DashboardLayout.test.tsx | 10 ++-- frontend/src/components/DashboardLayout.tsx | 12 ++--- frontend/src/components/EmailDetail.test.tsx | 8 +-- frontend/src/components/EmailDetail.tsx | 14 ++--- frontend/src/components/EmailList.tsx | 4 +- frontend/src/components/NetworkGraph.tsx | 2 +- frontend/src/components/ProjectsLayout.tsx | 4 +- .../src/components/SettingsLayout.test.tsx | 2 +- frontend/src/components/SettingsLayout.tsx | 10 ++-- frontend/src/components/TasksLayout.tsx | 4 +- frontend/src/components/WorkspaceHome.tsx | 12 ++--- .../components/mobile-workspace-panels.tsx | 2 +- .../src/components/ui/control-sizing.test.tsx | 2 +- frontend/tests/e2e/dashboard-branding.spec.ts | 52 +++++++++---------- frontend/tests/e2e/dashboard-flows.spec.ts | 8 +-- frontend/tests/e2e/scrolling.spec.ts | 2 +- 22 files changed, 91 insertions(+), 91 deletions(-) diff --git a/frontend/src/app/ai-hub/page.test.tsx b/frontend/src/app/ai-hub/page.test.tsx index 9efde82a5..9b03a3676 100644 --- a/frontend/src/app/ai-hub/page.test.tsx +++ b/frontend/src/app/ai-hub/page.test.tsx @@ -45,7 +45,7 @@ const aiHubSurface = { prompt_cards: [ { prompt_key: 'prompt_safe', - prompt_title: '의사결정 로그 요약', + prompt_title: '의사결정 로그 맥락 종합', description_text: '메일에서 판단 포인트를 추출합니다.', shared_scope: false, owner_label: 'alice', @@ -55,7 +55,7 @@ const aiHubSurface = { workflow_cards: [ { workflow_key: 'workflow_prompt_safe', - workflow_title: '의사결정 로그 요약 실행 흐름', + workflow_title: '의사결정 로그 맥락 종합 실행 흐름', trigger_source: 'prompt_template', state_code: 'ready', evidence_text: 'active organization provider is available', @@ -164,10 +164,10 @@ describe('AIHubPage', () => { expect(lowerHeaderNames.has(headerName)).toBe(false); } expect(container.textContent).toContain('AI 허브'); - expect(container.textContent).toContain('의사결정 로그 요약'); + expect(container.textContent).toContain('의사결정 로그 맥락 종합'); clickButton(container, '워크플로우'); - expect(container.textContent).toContain('의사결정 로그 요약 실행 흐름'); + expect(container.textContent).toContain('의사결정 로그 맥락 종합 실행 흐름'); clickButton(container, 'AI 에이전트'); expect(container.textContent).toContain('Primary OpenAI'); diff --git a/frontend/src/app/layout.test.tsx b/frontend/src/app/layout.test.tsx index c920e84b7..26f2bd76d 100644 --- a/frontend/src/app/layout.test.tsx +++ b/frontend/src/app/layout.test.tsx @@ -5,7 +5,7 @@ import { metadata } from "./layout"; describe("root layout metadata", () => { it("describes the Korean-first Naruon workspace and local icons", () => { expect(metadata.title).toBe("Naruon | AI Email Workspace"); - expect(metadata.description).toContain("이메일"); + expect(metadata.description).toContain("메일"); expect(metadata.icons).toMatchObject({ icon: "/brand/naruon-app-icon.svg", }); diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index e45474076..422b07eab 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -4,7 +4,7 @@ import "./globals.css"; export const metadata: Metadata = { title: "Naruon | AI Email Workspace", - description: "이메일, 일정, 관계, 판단 포인트를 하나의 맥락으로 연결하는 AI 이메일 워크스페이스", + description: "메일, 일정, 관계, 판단 포인트를 하나의 맥락으로 연결하는 AI 메일 워크스페이스", icons: { icon: "/brand/naruon-app-icon.svg", }, diff --git a/frontend/src/app/page.test.tsx b/frontend/src/app/page.test.tsx index aaa4e3fbf..4d915753b 100644 --- a/frontend/src/app/page.test.tsx +++ b/frontend/src/app/page.test.tsx @@ -363,7 +363,7 @@ describe("Home workspace action bridge", () => { await flushAsyncWork(); expect(container.querySelector('#mobile-calendar')?.className).toContain("flex"); - expect(container.textContent).toContain("캘린더 반영 대기"); + expect(container.textContent).toContain("일정 반영 대기"); expect(window.location.hash).toBe(""); }); @@ -401,7 +401,7 @@ describe("Home workspace action bridge", () => { ok: true, json: async () => ({ emails: [ - { id: 102, subject: "출시 리뷰 일정 조율", sender: "pm@example.com", date: "2026-05-17T10:00:00Z", snippet: "캘린더 반영 후보" }, + { id: 102, subject: "출시 리뷰 일정 조율", sender: "pm@example.com", date: "2026-05-17T10:00:00Z", snippet: "일정 반영 후보" }, ], }), }); @@ -547,8 +547,8 @@ describe("Home workspace action bridge", () => { await flushAsyncWork(); expect(container.querySelector('#mobile-calendar')?.className).toContain("flex"); - expect(container.textContent).toContain("캘린더 반영 대기"); - expect(container.textContent).not.toContain("오늘의 실행 대시보드"); + expect(container.textContent).toContain("일정 반영 대기"); + expect(container.textContent).not.toContain("오늘의 실행 홈"); }); it("lets hashless mobile workspace events override a saved dashboard startup view", async () => { @@ -577,8 +577,8 @@ describe("Home workspace action bridge", () => { expect(window.location.hash).toBe(""); expect(container.querySelector('#mobile-calendar')?.className).toContain("flex"); - expect(container.textContent).toContain("캘린더 반영 대기"); - expect(container.textContent).not.toContain("오늘의 실행 대시보드"); + expect(container.textContent).toContain("일정 반영 대기"); + expect(container.textContent).not.toContain("오늘의 실행 홈"); }); it("ignores malformed hashless mobile workspace events for dashboard overrides", async () => { @@ -682,7 +682,7 @@ describe("Home workspace action bridge", () => { root?.render(); }); await flushAsyncWork(); - expect(container.textContent).toContain("캘린더 반영 대기"); + expect(container.textContent).toContain("일정 반영 대기"); await act(async () => { window.history.replaceState(null, "", "/"); @@ -691,7 +691,7 @@ describe("Home workspace action bridge", () => { await flushAsyncWork(); expect(container.textContent).toContain("김나루님"); - expect(container.textContent).not.toContain("캘린더 반영 대기"); + expect(container.textContent).not.toContain("일정 반영 대기"); }); it("renders an API-backed loading state for the mobile search panel instead of placeholders", async () => { diff --git a/frontend/src/app/prompt-studio/page.tsx b/frontend/src/app/prompt-studio/page.tsx index be0e19db4..c00467978 100644 --- a/frontend/src/app/prompt-studio/page.tsx +++ b/frontend/src/app/prompt-studio/page.tsx @@ -16,7 +16,7 @@ export default function PromptStudioPage() { is_shared: false }); - const [testVariable, setTestVariable] = useState('이메일 내용 예시입니다.'); + const [testVariable, setTestVariable] = useState('메일 내용 예시입니다.'); const [testResult, setTestResult] = useState(''); const [testing, setTesting] = useState(false); const [saving, setSaving] = useState(false); diff --git a/frontend/src/app/tasks/page.test.tsx b/frontend/src/app/tasks/page.test.tsx index 8ba50eab3..b86350291 100644 --- a/frontend/src/app/tasks/page.test.tsx +++ b/frontend/src/app/tasks/page.test.tsx @@ -64,8 +64,8 @@ describe("TasksPage", () => { }); await flushAsyncWork(); - expect(container.querySelector("h1")?.textContent).toContain("할 일 추적"); - expect(container.textContent).toContain("할 일 추적"); + expect(container.querySelector("h1")?.textContent).toContain("실행 항목 추적"); + expect(container.textContent).toContain("실행 항목 추적"); expect(container.textContent).toContain("위임한 작업"); expect(container.textContent).toContain("실제 티켓 큐"); expect(container.textContent).toContain("연결된 티켓 없음"); diff --git a/frontend/src/components/DashboardLayout.test.tsx b/frontend/src/components/DashboardLayout.test.tsx index 7e863a509..a1cdbd856 100644 --- a/frontend/src/components/DashboardLayout.test.tsx +++ b/frontend/src/components/DashboardLayout.test.tsx @@ -82,7 +82,7 @@ describe("DashboardLayout", () => { expect(main).not.toBeNull(); expect(skipLink).not.toBeNull(); expect(logo?.getAttribute("src")).toBe("/brand/naruon-symbol.svg"); - expect(headerActionButtons).toEqual(["캘린더 반영", "답장 초안", "할 일 만들기"]); + expect(headerActionButtons).toEqual(["일정 반영", "답장 초안", "실행 항목 생성"]); expect(headerActionGroup?.className).toContain("lg:flex"); expect(headerActionGroup?.className).not.toContain("xl:flex"); expect(skipLink?.textContent).toBe("Skip to main content"); @@ -103,8 +103,8 @@ describe("DashboardLayout", () => { const desktopStartupPreference = container.querySelector('section[aria-label="Desktop startup preference"]'); expect(desktopStartupPreference).not.toBeNull(); expect(desktopStartupPreference?.textContent ?? "").toContain("시작 화면"); - expect(desktopStartupPreference?.querySelector('button[data-desktop-startup-view="dashboard"]')?.textContent).toContain("대시보드"); - expect(desktopStartupPreference?.querySelector('button[data-desktop-startup-view="email"]')?.textContent).toContain("이메일"); + expect(desktopStartupPreference?.querySelector('button[data-desktop-startup-view="dashboard"]')?.textContent).toContain("홈"); + expect(desktopStartupPreference?.querySelector('button[data-desktop-startup-view="email"]')?.textContent).toContain("메일"); expect(desktopStartupPreference?.querySelector('button[data-desktop-startup-view="calendar"]')?.textContent).toContain("일정"); act(() => { @@ -124,8 +124,8 @@ describe("DashboardLayout", () => { expect(mobileMenu?.className).toContain("inset-y-0"); expect(mobileMenu?.querySelector('button[aria-label="모바일 워크스페이스 메뉴 닫기"]')).not.toBeNull(); expect(mobileMenu?.textContent ?? "").toContain("시작 화면"); - expect(mobileMenu?.textContent ?? "").toContain("대시보드"); - expect(mobileMenu?.textContent ?? "").toContain("이메일"); + expect(mobileMenu?.textContent ?? "").toContain("홈"); + expect(mobileMenu?.textContent ?? "").toContain("메일"); expect(mobileMenu?.textContent ?? "").toContain("일정"); expect(mobileMenu?.textContent ?? "").toContain("메일"); expect(mobileMenu?.textContent ?? "").toContain("워크스페이스"); diff --git a/frontend/src/components/DashboardLayout.tsx b/frontend/src/components/DashboardLayout.tsx index de9f0a092..8db1a361a 100644 --- a/frontend/src/components/DashboardLayout.tsx +++ b/frontend/src/components/DashboardLayout.tsx @@ -58,22 +58,22 @@ const primaryNavItems = [ ]; const startupViewItems = [ - { label: '대시보드', view: 'dashboard' as const, description: '오늘의 실행 요약' }, - { label: '이메일', view: 'email' as const, description: '받은편지함 작업공간' }, + { label: '홈', view: 'dashboard' as const, description: '오늘의 실행 맥락 종합' }, + { label: '메일', view: 'email' as const, description: '받은편지함 작업공간' }, { label: '일정', view: 'calendar' as const, description: '캘린더 연결 먼저 보기' }, ]; const mobileWorkspaceMenuItems = [ { label: '받은편지함', description: '메일 스레드', icon: Inbox, href: '#mobile-inbox', view: 'inbox' as const }, { label: '맥락 검색', description: '메일, 첨부, 일정, 사람 검색', icon: Search, href: '#mobile-search', view: 'search' as const }, - { label: '일정 연결', description: '캘린더 반영 후보', icon: CalendarDays, href: '#mobile-calendar', view: 'calendar' as const }, + { label: '일정 연결', description: '일정 반영 후보', icon: CalendarDays, href: '#mobile-calendar', view: 'calendar' as const }, { label: 'AI 실행', description: '관계 맥락과 실행 항목', icon: Sparkles, href: '#mobile-actions', view: 'actions' as const }, ]; const headerActions = [ - { label: '캘린더 반영', action: 'calendar-sync', message: '메일 상세 패널에서 실행 항목을 캘린더에 반영합니다.', icon: CalendarDays }, + { label: '일정 반영', action: 'calendar-sync', message: '메일 상세 패널에서 실행 항목을 캘린더에 반영합니다.', icon: CalendarDays }, { label: '답장 초안', action: 'reply-draft', message: '메일 상세 패널에서 답장 초안을 생성합니다.', icon: PenLine }, - { label: '할 일 만들기', action: 'create-task', message: '메일 상세 패널에서 실행 항목을 할 일로 정리합니다.', icon: CheckCircle2 }, + { label: '실행 항목 생성', action: 'create-task', message: '메일 상세 패널에서 실행 항목을 실행 항목으로 정리합니다.', icon: CheckCircle2 }, ]; @@ -449,7 +449,7 @@ export function DashboardLayout({

워크스페이스 메뉴

-

메일, 일정, 할 일, 데이터와 보안 메뉴로 이동합니다.

+

메일, 일정, 실행 항목, 데이터와 보안 메뉴로 이동합니다.

); @@ -367,7 +367,7 @@ export function EmailDetail({ emailId, actionCommand = null }: { emailId: number className="h-9 rounded-xl bg-emerald-600 px-4 text-white hover:bg-emerald-700" > {isSyncing &&