feat: restore saved documents through facade

This commit is contained in:
2026-08-02 20:40:34 -04:00
parent 498e3f79ba
commit 61360473fe
6 changed files with 28 additions and 4 deletions

View File

@@ -468,7 +468,7 @@ function Viewport({ selectedObject, setSelectedObject, workbench, facade, docume
function PageFrame({ page, onNavigate, onOpenWorkspace, showNotice, facade }: { page: Page; onNavigate: (page: Page) => void; onOpenWorkspace: () => void; showNotice: (message: string) => void; facade: BitBybitWebCadFacade }) {
const pages: Record<Exclude<Page, 'workspace'>, ReactNode> = {
start: <StartPage onNavigate={onNavigate} onOpenWorkspace={onOpenWorkspace} showNotice={showNotice} />,
projects: <ProjectsPage onNavigate={onNavigate} onOpenWorkspace={onOpenWorkspace} showNotice={showNotice} />,
projects: <ProjectsPage onNavigate={onNavigate} onOpenWorkspace={onOpenWorkspace} showNotice={showNotice} facade={facade} />,
import: <FileFlowPage mode="import" onNavigate={onNavigate} showNotice={showNotice} facade={facade} />,
export: <FileFlowPage mode="export" onNavigate={onNavigate} showNotice={showNotice} facade={facade} />,
settings: <SettingsPage onNavigate={onNavigate} showNotice={showNotice} />,
@@ -500,8 +500,14 @@ function ProjectCard({ project, index, onClick }: { project: typeof projects[num
return <button className="project-card" onClick={onClick}><div className={`project-preview preview-${index}`}><div className="preview-shape" /><div className="preview-grid" /></div><div className="project-card-info"><div className="project-card-title"><strong>{project.name}</strong><MoreHorizontal size={15} /></div><span>{project.path}</span><div className="project-card-meta"><span>{project.modified}</span><span>{project.objects} objects</span><Badge tone={project.state === 'Unsaved' ? 'amber' : project.state === 'Read only' ? 'muted' : 'green'}>{project.state}</Badge></div></div></button>
}
function ProjectsPage({ onNavigate, onOpenWorkspace, showNotice }: { onNavigate: (page: Page) => void; onOpenWorkspace: () => void; showNotice: (message: string) => void }) {
return <div className="projects-page"><PageHeader eyebrow="Project manager" title="Your projects." description="Local-first project storage with explicit save and recovery states." actions={<><button className="button button-outline" onClick={() => onNavigate('import')}><Upload size={16} />Import</button><button className="button button-primary" onClick={onOpenWorkspace}><Plus size={16} />New project</button></>} /><div className="manager-toolbar"><div className="large-search"><Search size={16} /><input placeholder="Search projects" /><kbd>/</kbd></div><div className="toolbar-select"><span>Sort by</span><select><option>Last modified</option><option>Name</option><option>Object count</option></select><ChevronDown size={14} /></div><IconButton icon={LayoutGrid} label="Grid view" active /><IconButton icon={ListTree} label="List view" /></div><div className="project-list">{projects.map((project, index) => <div className="project-list-row" key={project.name}><div className={`list-thumbnail preview-${index}`}><div className="preview-shape" /><div className="preview-grid" /></div><div className="list-main"><strong>{project.name}</strong><span>{project.path}</span></div><span className="list-count">{project.objects} objects</span><span className="list-modified">{project.modified}</span><Badge tone={project.state === 'Unsaved' ? 'amber' : project.state === 'Read only' ? 'muted' : 'green'}>{project.state}</Badge><button className="row-action" title="More project actions" onClick={() => showNotice(`Actions for ${project.name}`)}><MoreHorizontal size={16} /></button></div>)}</div><div className="storage-banner"><div className="storage-icon"><HardDrive size={18} /></div><div><strong>Local storage</strong><span>3.4 GB of 10 GB used · Last backup just now</span></div><button className="text-button" onClick={() => onNavigate('settings')}>Manage storage <ArrowRight size={14} /></button></div></div>
function ProjectsPage({ onNavigate, onOpenWorkspace, showNotice, facade }: { onNavigate: (page: Page) => void; onOpenWorkspace: () => void; showNotice: (message: string) => void; facade: BitBybitWebCadFacade }) {
const openSavedProject = async () => {
const loaded = await facade.app.document.load('doc-pump-housing')
if (!loaded) { showNotice('No saved local snapshot found'); return }
showNotice(`Loaded ${loaded.label}`)
onOpenWorkspace()
}
return <div className="projects-page"><PageHeader eyebrow="Project manager" title="Your projects." description="Local-first project storage with explicit save and recovery states." actions={<><button className="button button-outline" onClick={() => onNavigate('import')}><Upload size={16} />Import</button><button className="button button-primary" onClick={onOpenWorkspace}><Plus size={16} />New project</button></>} /><div className="manager-toolbar"><div className="large-search"><Search size={16} /><input placeholder="Search projects" /><kbd>/</kbd></div><div className="toolbar-select"><span>Sort by</span><select><option>Last modified</option><option>Name</option><option>Object count</option></select><ChevronDown size={14} /></div><IconButton icon={LayoutGrid} label="Grid view" active /><IconButton icon={ListTree} label="List view" /></div><div className="project-list">{projects.map((project, index) => <button className="project-list-row" key={project.name} onClick={() => void openSavedProject()}><div className={`list-thumbnail preview-${index}`}><div className="preview-shape" /><div className="preview-grid" /></div><div className="list-main"><strong>{project.name}</strong><span>{project.path}</span></div><span className="list-count">{project.objects} objects</span><span className="list-modified">{project.modified}</span><Badge tone={project.state === 'Unsaved' ? 'amber' : project.state === 'Read only' ? 'muted' : 'green'}>{project.state}</Badge><span className="row-action" title="Open project"><ArrowRight size={16} /></span></button>)}</div><div className="storage-banner"><div className="storage-icon"><HardDrive size={18} /></div><div><strong>Local storage</strong><span>3.4 GB of 10 GB used · Last backup just now</span></div><button className="text-button" onClick={() => onNavigate('settings')}>Manage storage <ArrowRight size={14} /></button></div></div>
}
function FileFlowPage({ mode, onNavigate, showNotice, facade }: { mode: 'import' | 'export'; onNavigate: (page: Page) => void; showNotice: (message: string) => void; facade: BitBybitWebCadFacade }) {