fix(desktop): render workspace documents after login
This commit is contained in:
@@ -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: '张明' }],
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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[]
|
||||
}
|
||||
|
||||
@@ -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>,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user