Stop rendering the DocumentCenter as a blank page
Both the prose-documents and work-products sections rendered as
`{x.length > 0 ? ... : null}` with no else branch, and the whole
DocumentCenter was only mounted when a company was selected. The
combined result: a company with no files gave the operator a page
containing only a title and a "New" button, and an operator who had
not yet picked a company saw nothing at all — the exact "page is blank
even though docs were generated" complaint.
Add an explicit empty state inside DocumentCenter (surfaced only when
both collections are empty) and a separate "select a company" empty
state at the section router level. Strings live in the i18n bundle so
the Chinese locale is not left behind.
This commit is contained in:
1 parent
905473d985
commit
2222a67428
4 files changed
+38
-13
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import { useMemo, useState } from "react";
|
||||
import { FileText, FloppyDisk, NotePencil, Trash } from "../ui/icons";
|
||||
import { FileText, FloppyDisk, NotePencil, Plus, Trash } from "../ui/icons";
|
||||
import type { AgentRecord, DocumentRecord, GoalRecord, ProjectRecord, WorkProductRecord } from "@shared/types";
|
||||
import { ActionButton, ConfirmDialog, InlineNotice, Input, ListFrame, ListRow, Modal, Select, StatusPill, TextArea } from "../ui";
|
||||
import { ActionButton, ConfirmDialog, EmptyState, InlineNotice, Input, ListFrame, ListRow, Modal, Select, StatusPill, TextArea } from "../ui";
|
||||
import { useT } from "../../i18n";
|
||||
import { documentTypeOptions, documentStatusOptions, splitTags, parseTags } from "./helpers";
|
||||
import { SectionHeader } from "./SectionHeader";
|
||||
@@ -120,10 +120,18 @@ export function DocumentCenter({ companyId, documents, workProducts, agents, pro
|
||||
const activeDocument = useMemo(() => documents.find((document) => document.id === editingId) ?? null, [documents, editingId]);
|
||||
|
||||
const totalCount = documents.length + workProducts.length;
|
||||
const isEmpty = totalCount === 0;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SectionHeader title={t("ops.documentCenter")} count={totalCount} action={() => setEditingId(NEW_ENTITY_ID)} />
|
||||
{isEmpty ? (
|
||||
<EmptyState
|
||||
title={t("ops.documentsEmptyTitle")}
|
||||
detail={t("ops.documentsEmptyDetail")}
|
||||
action={<ActionButton label={t("ops.documentsEmptyAction")} icon={Plus} tone="accent" onClick={() => setEditingId(NEW_ENTITY_ID)} />}
|
||||
/>
|
||||
) : null}
|
||||
{documents.length > 0 ? (
|
||||
<div>
|
||||
<div className="px-4 pt-3 pb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
|
||||
|
||||
@@ -873,6 +873,10 @@ export const en: Record<string, string> = {
|
||||
"ops.documentCenter": "Document Center",
|
||||
"ops.documentsProse": "Prose documents",
|
||||
"ops.documentsWorkProducts": "Files & deliverables",
|
||||
"ops.documentsEmptyTitle": "No documents yet",
|
||||
"ops.documentsEmptyDetail": "Agents register files here automatically when they write to the workspace, and can publish prose documents (PRDs, specs, post-mortems) via POST /api/companies/{id}/documents.",
|
||||
"ops.documentsEmptyAction": "Create the first document",
|
||||
"ops.documentsSelectCompany": "Select a company from the workspace switcher to see its documents.",
|
||||
"ops.knowledgeBase": "Knowledge Base",
|
||||
"ops.meetings": "Meetings",
|
||||
"ops.sprintBoard": "Sprint Board",
|
||||
|
||||
@@ -873,6 +873,10 @@ export const zh: Record<string, string> = {
|
||||
"ops.documentCenter": "文档中心",
|
||||
"ops.documentsProse": "文稿",
|
||||
"ops.documentsWorkProducts": "文件与交付物",
|
||||
"ops.documentsEmptyTitle": "还没有文档",
|
||||
"ops.documentsEmptyDetail": "Agent 在 workspace 里写文件时会被自动登记为交付物;结构化文稿(PRD、技术规格、复盘)需要调用 POST /api/companies/{id}/documents 发布。",
|
||||
"ops.documentsEmptyAction": "创建第一份文档",
|
||||
"ops.documentsSelectCompany": "请先在工作区切换器中选择一家公司,才能查看它的文档。",
|
||||
"ops.knowledgeBase": "知识库",
|
||||
"ops.meetings": "会议",
|
||||
"ops.sprintBoard": "迭代看板",
|
||||
|
||||
@@ -18,7 +18,8 @@ import { DocumentCenter } from "../../components/company-operations/DocumentCent
|
||||
import { KnowledgeBaseManager } from "../../components/company-operations/KnowledgeBaseManager";
|
||||
import { MeetingsManager } from "../../components/company-operations/MeetingsManager";
|
||||
import { SprintManager } from "../../components/company-operations/SprintManager";
|
||||
import { Panel } from "../../components/ui";
|
||||
import { EmptyState, Panel } from "../../components/ui";
|
||||
import { useT } from "../../i18n";
|
||||
import { unwrap } from "../../lib/desktop";
|
||||
import { useAppStore } from "../../state/store";
|
||||
import { useSectionContext } from "../../hooks/useSectionContext";
|
||||
@@ -29,6 +30,7 @@ interface OperationsSectionsProps {
|
||||
}
|
||||
|
||||
export function OperationsSections({ section }: OperationsSectionsProps) {
|
||||
const t = useT();
|
||||
const {
|
||||
snapshot,
|
||||
currentCompany,
|
||||
@@ -212,16 +214,23 @@ export function OperationsSections({ section }: OperationsSectionsProps) {
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{section === "documents" && currentCompany ? (
|
||||
<DocumentCenter
|
||||
companyId={currentCompany.id}
|
||||
documents={companyDocuments}
|
||||
workProducts={companyWorkProducts}
|
||||
agents={companyAgents}
|
||||
projects={companyProjects}
|
||||
goals={companyGoals}
|
||||
onRefresh={refresh}
|
||||
/>
|
||||
{section === "documents" ? (
|
||||
currentCompany ? (
|
||||
<DocumentCenter
|
||||
companyId={currentCompany.id}
|
||||
documents={companyDocuments}
|
||||
workProducts={companyWorkProducts}
|
||||
agents={companyAgents}
|
||||
projects={companyProjects}
|
||||
goals={companyGoals}
|
||||
onRefresh={refresh}
|
||||
/>
|
||||
) : (
|
||||
<EmptyState
|
||||
title={t("ops.documentsEmptyTitle")}
|
||||
detail={t("ops.documentsSelectCompany")}
|
||||
/>
|
||||
)
|
||||
) : null}
|
||||
|
||||
{section === "knowledge" && currentCompany ? (
|
||||
|
||||
Reference in new issue
Block a user