feat: add markdown import/export (closes #77, #78)

- Add POST /api/knowledge/import endpoint for .md and .zip files
- Add GET /api/knowledge/export endpoint with markdown/json formats
- Import parses frontmatter (title, tags, status, visibility)
- Export includes frontmatter in markdown format
- Add ImportExportActions component with drag-and-drop UI
- Add import progress dialog with success/error summary
- Add export dropdown with format selection
- Include comprehensive test suite
- Support bulk import with detailed error reporting
This commit is contained in:
Jason Woltje
2026-01-30 00:05:15 -06:00
parent 806a518467
commit c4c15ee87e
12 changed files with 1224 additions and 15 deletions

View File

@@ -4,6 +4,7 @@ import { useState, useMemo } from "react";
import { EntryStatus } from "@mosaic/shared";
import { EntryList } from "@/components/knowledge/EntryList";
import { EntryFilters } from "@/components/knowledge/EntryFilters";
import { ImportExportActions } from "@/components/knowledge";
import { mockEntries, mockTags } from "@/lib/api/knowledge";
import Link from "next/link";
import { Plus } from "lucide-react";
@@ -99,22 +100,35 @@ export default function KnowledgePage() {
return (
<main className="container mx-auto px-4 py-8 max-w-5xl">
{/* Header */}
<div className="mb-8 flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold text-gray-900">Knowledge Base</h1>
<p className="text-gray-600 mt-2">
Documentation, guides, and knowledge entries
</p>
<div className="mb-8">
<div className="flex items-center justify-between mb-4">
<div>
<h1 className="text-3xl font-bold text-gray-900">Knowledge Base</h1>
<p className="text-gray-600 mt-2">
Documentation, guides, and knowledge entries
</p>
</div>
{/* Create button */}
<Link
href="/knowledge/new"
className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors shadow-sm"
>
<Plus className="w-5 h-5" />
<span>Create Entry</span>
</Link>
</div>
{/* Create button */}
<Link
href="/knowledge/new"
className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors shadow-sm"
>
<Plus className="w-5 h-5" />
<span>Create Entry</span>
</Link>
{/* Import/Export Actions */}
<div className="flex justify-end">
<ImportExportActions
onImportComplete={() => {
// TODO: Refresh the entry list when real API is connected
// For now, this would trigger a refetch of the entries
window.location.reload();
}}
/>
</div>
</div>
{/* Filters */}