fix(desktop): render workspace documents after login

This commit is contained in:
2026-07-25 20:56:21 +08:00
parent 563e0fe115
commit b2c22901ba
4 changed files with 36 additions and 12 deletions

View File

@@ -26,9 +26,9 @@ const workspace = {
{ id: 'task-2', projectId, title: '检查迷你布局', summary: '验证窄屏下的导航和滚动。', completed: false, owner: '张明', due: null, createdAt: '今天 10:00', completedAt: null, tagId: 'tag-design', tag: '设计' },
],
aiSessions: [{ id: 'old-session', projectId, title: '梳理版本计划', summary: '项目会话', updatedAt: '今天', references: [] }],
notesSources: [
{ id: 'note-1', projectId, kind: 'note', title: '版本规划', updatedAt: '今天', tag: '产品', source: '项目笔记' },
{ id: 'source-1', projectId, kind: 'file', title: '需求说明.pdf', updatedAt: '昨天', tag: '资料', source: '上传文件' },
documents: [
{ id: 'note-1', projectId, kind: 'markdown', name: '版本规划', extension: '.md', mimeType: 'text/markdown', updatedAt: '今天' },
{ id: 'source-1', projectId, kind: 'file', name: '需求说明.pdf', extension: '.pdf', mimeType: 'application/pdf', updatedAt: '昨天' },
],
cronPlans: [{ id: 'cron-1', projectId, title: '每周复盘', schedule: '0 17 * * 5', nextRun: null, enabled: true, lastResult: '', owner: '张明' }],
}

View File

@@ -187,7 +187,7 @@ function HomeView({ workspace, openAction }: ViewProps) {
</div>
<div className="metric-grid">
<Metric value={pending.length} label="待办计划" color="blue" />
<Metric value={workspace.notesSources.length} label="笔记资料" color="green" />
<Metric value={workspace.documents.length} label="笔记资料" color="green" />
<Metric value={workspace.aiSessions.length} label="AI 会话" color="purple" />
<Metric value={workspace.cronPlans.length} label="计划任务" color="orange" />
</div>
@@ -239,8 +239,8 @@ function NotesView({ session, workspace, refresh }: ViewProps) {
<div className="page-title"><div><Title heading={5}></Title><Text type="secondary"></Text></div><Button type="primary" size="small" icon={<IconPlus />} onClick={() => fileInput.current?.click()}></Button></div>
<input className="hidden-file" ref={fileInput} type="file" onChange={async (event) => { const file = event.target.files?.[0]; if (!file) return; await uploadSource(session, workspace.project.id, file); await refresh(); event.target.value = '' }} />
<div className="note-grid">
{workspace.notesSources.map((note, index) => <article className={`source-note tone-${index % 4}`} key={note.id}><IconFile /><strong>{note.title}</strong><p>{note.source || note.kind}</p><span>{note.tag || '资料'} · {note.updatedAt}</span></article>)}
{!workspace.notesSources.length && <Empty description="还没有笔记或资料" />}
{workspace.documents.map((document, index) => <article className={`source-note tone-${index % 4}`} key={document.id}><IconFile /><strong>{document.name}</strong><p>{document.extension || document.mimeType || document.kind}</p><span>{document.kind || '资料'} · {document.updatedAt}</span></article>)}
{!workspace.documents.length && <Empty description="还没有笔记或资料" />}
</div>
</section>
)

View File

@@ -23,14 +23,14 @@ export type WorkspaceTask = {
tag: string
}
export type NoteSource = {
export type WorkspaceDocument = {
id: string
projectId: string
kind: string
title: string
name: string
extension: string
mimeType: string
updatedAt: string
tag: string
source: string
}
export type CronPlan = {
@@ -48,7 +48,7 @@ export type Workspace = {
project: Project & { initials: string; unreadCount: number }
tags: Array<{ id: string; name: string }>
tasks: WorkspaceTask[]
notesSources: NoteSource[]
documents: WorkspaceDocument[]
aiSessions: Array<{ id: string; projectId: string; title: string; summary: string; updatedAt: string; references: string[] }>
cronPlans: CronPlan[]
}

View File

@@ -5,10 +5,34 @@ import '@arco-design/web-react/dist/css/arco.css'
import { App } from './App'
import './styles.css'
type ErrorBoundaryState = { error: Error | null }
class AppErrorBoundary extends React.Component<React.PropsWithChildren, ErrorBoundaryState> {
state: ErrorBoundaryState = { error: null }
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
return { error }
}
render() {
if (this.state.error) {
return (
<main style={{ minHeight: '100vh', padding: 24, color: '#1d2129', background: '#f2f3f5' }}>
<h2></h2>
<p></p>
<p style={{ color: '#86909c', wordBreak: 'break-word' }}>{this.state.error.message}</p>
<button type="button" onClick={() => { localStorage.removeItem('senlin-mini-session'); window.location.reload() }}>退</button>
</main>
)
}
return this.props.children
}
}
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<ConfigProvider>
<App />
<AppErrorBoundary><App /></AppErrorBoundary>
</ConfigProvider>
</React.StrictMode>,
)