From bc67dea2c87e020bb0fbd72254b357d6deec0936 Mon Sep 17 00:00:00 2001 From: altair823 Date: Sat, 9 May 2026 16:25:17 +0900 Subject: [PATCH] =?UTF-8?q?feat(v029):=20NoteCard=20ai=5Fstatus=3D'disable?= =?UTF-8?q?d'=20fallback=20(raw=5Ftext=20=EC=B2=AB=20=EC=A4=84=20+=20summa?= =?UTF-8?q?ry/tags=20hide)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/inbox/components/NoteCard.tsx | 10 +++++++ tests/unit/NoteCard.test.tsx | 33 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/renderer/inbox/components/NoteCard.tsx b/src/renderer/inbox/components/NoteCard.tsx index 66994a2..008016d 100644 --- a/src/renderer/inbox/components/NoteCard.tsx +++ b/src/renderer/inbox/components/NoteCard.tsx @@ -110,8 +110,11 @@ function DueDateBadge({ export function NoteCard({ note, onDeleted, onUpdated, mode = 'inbox', onRestore, onPermanentDelete }: Props): React.ReactElement { const isTrash = mode === 'trash'; + // v0.2.9 Cut B Task 13 — ai_status='disabled' 노트는 raw_text 가 1차 정보. 원문 펼침 default 켬. const [rawOpen, setRawOpen] = useState(note.aiStatus !== 'done'); const [local, setLocal] = useState(note); + const isAiDisabled = local.aiStatus === 'disabled'; + const fallbackTitle = local.rawText.split('\n')[0]?.slice(0, 60) || '(빈 메모)'; // v0.2.9 Cut B Task 6 — 이동 메뉴 dropdown + MoveStatusModal target. const [moveTarget, setMoveTarget] = useState(null); const [menuOpen, setMenuOpen] = useState(false); @@ -211,6 +214,13 @@ export function NoteCard({ note, onDeleted, onUpdated, mode = 'inbox', onRestore 정리 보류 — 원문은 안전합니다 )} + {/* v0.2.9 Cut B Task 13 — ai_status='disabled': raw_text 첫 줄 fallback title. + summary/tags 는 hide. 원문은 아래 "원문 보기" 영역에서 항상 표시. */} + {isAiDisabled && ( +
+

{fallbackTitle}

+
+ )} {local.aiStatus === 'done' && ( <> {isTrash ? ( diff --git a/tests/unit/NoteCard.test.tsx b/tests/unit/NoteCard.test.tsx index ba7c9e0..edd864e 100644 --- a/tests/unit/NoteCard.test.tsx +++ b/tests/unit/NoteCard.test.tsx @@ -90,6 +90,39 @@ describe('NoteCard — image rendering', () => { }); }); +describe('NoteCard — ai_status=disabled fallback (v0.2.9 Cut B Task 13)', () => { + beforeEach(() => { + vi.clearAllMocks(); + cleanup(); + }); + + it('ai_status=disabled: title fallback to raw_text first line, hide summary/tags', () => { + const disabledNote: Note = { + ...baseNote, + aiStatus: 'disabled', + aiTitle: null, + aiSummary: 'should-not-show', + tags: [{ name: 't1', source: 'user' }], + rawText: '첫 줄 본문\n둘째 줄 본문' + }; + render(); + expect(screen.getByText('첫 줄 본문')).toBeInTheDocument(); + expect(screen.queryByText('should-not-show')).toBeNull(); + expect(screen.queryByText('t1')).toBeNull(); + }); + + it('ai_status=disabled: empty raw → "(빈 메모)" fallback', () => { + const disabledNote: Note = { + ...baseNote, + aiStatus: 'disabled', + aiTitle: null, + rawText: '' + }; + render(); + expect(screen.getByText('(빈 메모)')).toBeInTheDocument(); + }); +}); + describe('NoteCard — 이동 메뉴 (v0.2.9 Cut B Task 6)', () => { beforeEach(() => { vi.clearAllMocks();