Skip to content

feat: 取り込み補助に Markdown 対応と D&D 導線を追加#300

Merged
yusuke0610 merged 3 commits into
mainfrom
feat/markdown-import-assist
Jun 1, 2026
Merged

feat: 取り込み補助に Markdown 対応と D&D 導線を追加#300
yusuke0610 merged 3 commits into
mainfrom
feat/markdown-import-assist

Conversation

@yusuke0610

@yusuke0610 yusuke0610 commented Jun 1, 2026

Copy link
Copy Markdown
Owner

概要

職務経歴書フォームの取り込み補助(PDF 原本からテキストをドラッグ選択してフォームへ流し込む機能)を Markdown ファイルにも拡張し、ファイル取り込みの導線を右カラムのドロップゾーンに一本化しました。すべてクライアントサイド完結で、ファイルはサーバーに送信しません。

変更内容

機能追加

  • Markdown 取り込み対応: PDF と同じ「原本ビューで文字をドラッグ選択 → フォーム入力欄へ流し込む」UX を Markdown に拡張
  • 取り込み導線の一本化: ヘッダーの「ファイルから取り込み」ボタンを廃止し、右カラムのドロップゾーンに集約(ドラッグ&ドロップ / クリック選択の両対応)

実装

  • utils/markdown.ts: marked + DOMPurify で sanitize 描画する renderMarkdown を抽出(MarkdownTextarea の重複ロジックも統合)
  • MarkdownDocumentView を新設。原本ビューは kind で PDF / Markdown のレンダラーを切り替え。選択→流し込みは既存の window.getSelection() 機構を流用
  • useResumeImportAssist: kind 判定・種別別サイズ上限(PDF 20MB / MD 2MB)・ドロップ受け入れ用 acceptFile を追加
  • 折り畳みトグルをサイドバーと同じシェブロン UI に統一

リファクタ(PDF 限定 → 汎用化)

  • ResumePdfTracePanelResumeSourceTracePanel
  • usePdfPanelLayoutuseImportPanelLayout
  • メッセージ文言・UI_MESSAGES の PDF 限定表現を汎用化

セキュリティ

  • Markdown 描画は renderMarkdown()(DOMPurify sanitize)の出力のみを dangerouslySetInnerHTML に渡す既存パターンを踏襲。<script> / onerror 除去を unit test で固定

テスト

  • make ci 全 pass(backend lint/test + frontend lint/test/build、frontend 205 tests
  • unit 追加: utils/markdown.test.tsuseResumeImportAssist.test.ts(MD 判定 / 未対応形式 / サイズ超過 / acceptFile
  • E2E 追加e2e/career-import-assist.spec.ts、全 27 E2E pass):
    • ファイル選択 / ドラッグ&ドロップでの Markdown 読み込み → 原本描画
    • 原本上で選択した文字 → フォーカス中の入力欄へ流し込み
    • 拡張子が pdf/md 以外(.txt)→ 未対応エラー表示・未描画
    • サイズ上限超過(>2MB)→ サイズ超過エラー表示・未描画

🤖 Generated with Claude Code

職務経歴書フォームの取り込み補助(PDF 原本からの流し込み)を Markdown
ファイルにも拡張し、ファイル取り込み導線を右カラムのドロップゾーンに一本化する。

- Markdown を marked + DOMPurify で sanitize 描画する renderMarkdown を
  utils に抽出(MarkdownTextarea の重複ロジックも統合)
- 原本ビューを kind で PDF / Markdown のレンダラー切替に変更。
  MarkdownDocumentView を新設し、選択→流し込みは既存の getSelection 機構を流用
- useResumeImportAssist に kind 判定・種別別サイズ上限(PDF 20MB / MD 2MB)・
  ドロップ受け入れ用 acceptFile を追加
- 取り込み導線をヘッダーボタンから右カラムのドロップゾーン(D&D / クリック)へ一本化
- 折り畳みトグルをサイドバーと同じシェブロン UI に統一
- PDF 限定の命名を一般化(ResumePdfTracePanel→ResumeSourceTracePanel、
  usePdfPanelLayout→useImportPanelLayout、メッセージ文言・UI_MESSAGES)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 48 minutes and 25 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6ce291e9-26fc-4ba7-b5e4-f9401e7ad8b7

📥 Commits

Reviewing files that changed from the base of the PR and between 4e7cc1c and 78c58d3.

📒 Files selected for processing (3)
  • frontend/e2e/career-import-assist.spec.ts
  • frontend/src/components/forms/MarkdownDocumentView.tsx
  • frontend/src/components/forms/ResumeSourceTracePanel.module.css
📝 Walkthrough

Walkthrough

The PR extends the resume import feature from PDF-only to support both PDF and Markdown files by introducing a shared Markdown utility, refactoring panel/assist hooks to handle multiple file types, replacing the single-format ResumePdfTracePanel with a new multi-format ResumeSourceTracePanel component, and updating UI messages and form integration accordingly.

Changes

Resume Import Expansion

Layer / File(s) Summary
Shared Markdown rendering utility
frontend/src/utils/markdown.ts, frontend/src/utils/markdown.test.ts, frontend/src/components/forms/MarkdownTextarea.tsx
New renderMarkdown() utility converts Markdown to sanitized HTML via marked.parse() and DOMPurify.sanitize(), with comprehensive tests for empty input, basic rendering, and XSS prevention. MarkdownTextarea refactored to use the shared utility instead of inline dependencies.
Hook refactoring: layout and import assist
frontend/src/hooks/career/useImportPanelLayout.ts, frontend/src/hooks/career/useImportPanelLayout.test.ts, frontend/src/hooks/career/useResumeImportAssist.ts, frontend/src/hooks/career/useResumeImportAssist.test.ts
usePdfPanelLayout renamed to useImportPanelLayout with updated documentation. useResumeImportAssist expanded to detect file kind (pdf or markdown), validate size per kind, and expose new acceptFile() API alongside handleFileChange(). Tests cover PDF/Markdown uploads, unsupported types, and oversized files.
ResumeSourceTracePanel: multi-format document viewer
frontend/src/components/forms/ResumeSourceTracePanel.tsx, frontend/src/components/forms/ResumeSourceTracePanel.module.css
New component replaces ResumePdfTracePanel with support for both PDF and Markdown. Implements drag-and-drop file upload, zoom controls, and conditional rendering by kind. Includes new CSS for dropzone/drag-active states and Markdown body styling (headings, code blocks, tables).
MarkdownDocumentView component
frontend/src/components/forms/MarkdownDocumentView.tsx
New component asynchronously renders Markdown files using renderMarkdown(), displays loading/error states, captures text selection via onFill callback, and applies zoom scaling via fontSize in em.
Integration into CareerResumeForm and ProjectModal
frontend/src/components/forms/CareerResumeForm.tsx, frontend/src/components/forms/CareerResumeForm.module.css, frontend/src/components/forms/ProjectModal.tsx, frontend/src/components/forms/ProjectModal.test.tsx, frontend/src/components/forms/PdfDocumentView.tsx, frontend/src/constants/messages.ts, .claude/rules/frontend/architecture.md
CareerResumeForm and ProjectModal updated to use useImportPanelLayout and ResumeSourceTracePanel. Header file-picker removed from CareerResumeForm; import consolidated in right panel. Panel collapse/expand labels updated via UI_MESSAGES.SOURCE_PANEL_COLLAPSE/EXPAND. CSS toggle and collapsed-state styling refined. IMPORT_ASSIST_MESSAGES generalized from PDF-specific to file-import-generic, adding dropzone and unsupported-type labels. Tests updated to mock ResumeSourceTracePanel and new assist return shape with kind and acceptFile.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • yusuke0610/devforge#293: Both PRs modify Markdown rendering in MarkdownTextarea via shared sanitization and XSS prevention.
  • yusuke0610/devforge#277: Retrieved PR adds the PDF panel via usePdfPanelLayout and ResumePdfTracePanel, while this PR replaces both with import-panel and source-trace variants.
  • yusuke0610/devforge#294: Both PRs modify useResumeImportAssist.ts, useResumeImportAssist.test.ts, and messages.ts in the context of file size guards and panel display labels.

Suggested labels

feature

Poem

🐰 A PDF once stood alone and proud,
But now Markdown joins the crowd!
With dropzones, zoom, and graceful drag,
The import panel spreads its flag. ✨
Two formats rendered, side by side—
A rabbit's joy, a feature's pride!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 63.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main changes: adding Markdown support and drag-and-drop functionality to the resume import assistance feature.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/markdown-import-assist

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/components/forms/MarkdownDocumentView.tsx`:
- Around line 32-60: The render-error path leaves html as null so the loading
placeholder remains; update the catch handler inside the useEffect that calls
file.text() to also setHtml to a non-null sentinel (e.g., empty string or an
"error" value) so the component no longer renders the RENDERING placeholder, and
keep calling onError(IMPORT_ASSIST_MESSAGES.RENDER_FAILED); modify the
useEffect's catch block (and the cleanup behavior if needed) to setHtml(...)
alongside onError to reflect failure, referencing the useEffect, file.text(),
onError, setHtml and html symbols to locate the change.

In `@frontend/src/components/forms/ResumeSourceTracePanel.module.css`:
- Around line 158-169: The .markdownBody CSS rule uses the deprecated
declaration "word-break: break-word"; update this rule to remove that deprecated
property and instead add "overflow-wrap: break-word" (keeping existing layout
properties intact) so the .markdownBody selector uses the standard,
non-deprecated wrapping behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7c8d7ff6-6edc-4203-8d53-89382c780421

📥 Commits

Reviewing files that changed from the base of the PR and between 94be2e2 and 4e7cc1c.

📒 Files selected for processing (18)
  • .claude/rules/frontend/architecture.md
  • frontend/src/components/forms/CareerResumeForm.module.css
  • frontend/src/components/forms/CareerResumeForm.tsx
  • frontend/src/components/forms/MarkdownDocumentView.tsx
  • frontend/src/components/forms/MarkdownTextarea.tsx
  • frontend/src/components/forms/PdfDocumentView.tsx
  • frontend/src/components/forms/ProjectModal.test.tsx
  • frontend/src/components/forms/ProjectModal.tsx
  • frontend/src/components/forms/ResumePdfTracePanel.tsx
  • frontend/src/components/forms/ResumeSourceTracePanel.module.css
  • frontend/src/components/forms/ResumeSourceTracePanel.tsx
  • frontend/src/constants/messages.ts
  • frontend/src/hooks/career/useImportPanelLayout.test.ts
  • frontend/src/hooks/career/useImportPanelLayout.ts
  • frontend/src/hooks/career/useResumeImportAssist.test.ts
  • frontend/src/hooks/career/useResumeImportAssist.ts
  • frontend/src/utils/markdown.test.ts
  • frontend/src/utils/markdown.ts
💤 Files with no reviewable changes (1)
  • frontend/src/components/forms/ResumePdfTracePanel.tsx

Comment thread frontend/src/components/forms/MarkdownDocumentView.tsx
Comment thread frontend/src/components/forms/ResumeSourceTracePanel.module.css
yusuke0610 and others added 2 commits June 1, 2026 15:39
- ファイル選択 / ドラッグ&ドロップでの Markdown 読み込み→原本描画
- 原本選択→入力欄への流し込み
- 未対応拡張子(.txt)と上限超過(>2MB)のエラー表示を検証

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 描画失敗時に html を空文字で確定し RENDERING 表示の残存を解消
- .markdownBody の word-break: break-word を標準の overflow-wrap へ置換

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit e8749f4 into main Jun 1, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant