fix(ui): improve knowledge reading and add isolated formatting examples
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useI18n } from "../i18n";
|
||||
import { useState } from "react";
|
||||
import { Copy } from "lucide-react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { apiFetch, apiErrorMessage } from "../api/client";
|
||||
import { listEvidence, getEvidence, type EvidencePage, type EvidenceUnit } from "../api/evidence";
|
||||
@@ -28,11 +29,11 @@ function CopyText({ text, label, showText = true }: { text: string; label: strin
|
||||
const { t } = useI18n();
|
||||
const [notice, setNotice] = useState("");
|
||||
return <div className="flex min-w-0 flex-wrap items-start gap-2">
|
||||
{showText && <code className="min-w-0 flex-1 break-all text-xs select-text">{text}</code>}
|
||||
<Button size="sm" variant="outline" aria-label={t("Copy {label}", { label: label })} onClick={async () => {
|
||||
{showText && <code className="min-w-0 flex-1 [overflow-wrap:anywhere] text-xs select-text">{text}</code>}
|
||||
<Button size="icon" variant="ghost" title={t("Copy {label}", { label })} aria-label={t("Copy {label}", { label })} onClick={async () => {
|
||||
try { await navigator.clipboard.writeText(text); setNotice("Copied"); }
|
||||
catch { setNotice("Select the text and copy it manually."); }
|
||||
}}>{t("Copy")}</Button><span role="status" className="text-xs text-muted-foreground">{t(notice)}</span>
|
||||
}}><Copy aria-hidden="true" /></Button>{notice && <span role="status" className="basis-full text-xs text-muted-foreground">{t(notice)}</span>}
|
||||
</div>;
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ function Instructions({ data }: { data: EvidencePage }) {
|
||||
<p className="mb-2 text-sm font-medium">{data.pending_revision ? t("Consolidation is incomplete. The previous active content remains available.") : data.active_revision ? t("The core uses the last successfully consolidated version.") : t("Run the first consolidation to convert and activate the local archive.")}</p>
|
||||
<details className="mt-3"><summary className="cursor-pointer text-sm font-medium">{t("Edit files, consolidate and commit")}</summary>
|
||||
{data.location.workspace ? <div className="mt-3"><p className="mb-1 text-xs text-muted-foreground">{t("Workspace on the installation host")}</p><CopyText text={data.location.workspace} label={t("workspace path")} /></div> : <p role="alert" className="mt-3 text-sm">{t("A host file path is unavailable for this installation. Configure a persistent workspace-registry bind mount before editing files from the host.")}</p>}
|
||||
<ol className="mt-3 max-w-[75ch] list-decimal space-y-3 pl-5 text-sm">
|
||||
<ol className="mt-3 list-decimal space-y-3 pl-5 text-sm">
|
||||
<li>{t("Edit the files under")} <code>evidence/curated/<kind>/</code> {t("with your preferred editor. Keep existing IDs. Remove a unit's file to delete it; keep the curated directory.")}</li>
|
||||
<li>{t("Check Git status and the diff. Saving a file does not update recall.")}{data.location.git_commands.slice(0, 2).map(command => <div className="mt-2" key={command}><CopyText text={command} label={t("Git inspection command")} /></div>)}</li>
|
||||
<li>{t("From the installation directory, run this command. It validates and activates Evidence without a full preprocessing run. If needed, add")} <code>--installation /absolute/path/thothii-installation.yaml</code> {t("immediately after")} <code>tht</code>.
|
||||
@@ -130,14 +131,14 @@ function UnitDetail({ item, location }: { item: EvidenceUnit; location: Evidence
|
||||
const { t } = useI18n();
|
||||
const source = item.provenance.kind === "manual" ? item.provenance.original : item.provenance;
|
||||
const file = location.workspace ? `${location.workspace.replace(/\\/g, "/")}/evidence/${item.file}` : null;
|
||||
return <article className="max-w-[75ch] space-y-5 pb-8">
|
||||
return <article className="min-w-0 w-full space-y-5 pb-8 [overflow-wrap:anywhere]">
|
||||
<header><p className="text-xs text-muted-foreground">{t(states[item.status])} · {item.purposes.map(purpose => t(purpose.replaceAll("_", " "))).join(", ")}</p><h2 className="mt-1 font-sans text-xl font-semibold">{item.title}</h2></header>
|
||||
{file && <CopyText text={file} label={t("Evidence file path")} />}
|
||||
{item.status !== "active" && <p className="text-sm text-muted-foreground">{["invalid", "removed"].includes(item.status) ? t("The file is invalid or removed. Its last active content is shown here.") : t("This is the file version awaiting consolidation.")} {t("The core continues to use its last active version.")}</p>}
|
||||
{Object.entries(item.applies_to).some(([, values]) => values.length > 0) && <section><h3 className="font-medium">{t("Scope")}</h3>{Object.entries(item.applies_to).map(([name, values]) => values.length > 0 && <p className="mt-2 break-words text-sm" key={name}><span className="capitalize">{t(name)}</span>: {values.join(", ")}</p>)}</section>}
|
||||
{Object.entries(item.payload).map(([field, value]) => <section key={field}><h3 className="mb-2 text-sm font-semibold capitalize">{t(field.replaceAll("_", " "))}</h3>{typeof value === "string" ? field === "sql" ? <pre className="overflow-auto rounded-md bg-muted p-3 text-sm">{value}</pre> : <MarkdownView source={value} /> : Array.isArray(value) ? <ul className="list-inside list-disc text-sm">{value.map(v => <li key={v}>{v}</li>)}</ul> : <dl className="space-y-2 text-sm">{Object.entries(value).map(([key, text]) => <div key={key}><dt className="font-mono font-medium">{key || t("(empty value)")}</dt><dd>{text}</dd></div>)}</dl>}</section>)}
|
||||
{Object.entries(item.payload).map(([field, value]) => <section key={field}><h3 className="mb-2 text-sm font-semibold capitalize">{t(field.replaceAll("_", " "))}</h3>{typeof value === "string" ? field === "sql" ? <pre className="overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] rounded-md bg-muted p-3 text-sm">{value}</pre> : <MarkdownView source={value} readable /> : Array.isArray(value) ? <ul className="list-inside list-disc space-y-2 text-sm">{value.map(v => <li key={v}>{v}</li>)}</ul> : <dl className="space-y-2 text-sm">{Object.entries(value).map(([key, text]) => <div key={key}><dt className="font-mono font-medium">{key || t("(empty value)")}</dt><dd><MarkdownView source={text} readable /></dd></div>)}</dl>}</section>)}
|
||||
<section className="border-t pt-4"><h3 className="font-medium">{t("Provenance")}</h3><p className="mt-2 text-sm">{item.provenance.kind === "manual" ? t("Manual declaration by {author}.", { author: item.provenance.declared_by ?? "" }) : t("Derived from a source document.")}</p>
|
||||
{source?.source_file && <><p className="mt-2 break-all text-xs">{item.provenance.kind === "manual" ? t("Original document (lineage): ") : t("Source: ")}{source.source_file}</p>{source.supporting_excerpts?.map((text, i) => <p key={i} className="mt-2 whitespace-pre-wrap text-sm text-muted-foreground">“{text}”</p>)}</>}
|
||||
{source?.source_file && <><p className="mt-2 [overflow-wrap:anywhere] text-xs">{item.provenance.kind === "manual" ? t("Original document (lineage): ") : t("Source: ")}{source.source_file}</p>{source.supporting_excerpts?.map((text, i) => <div key={i} className="mt-4"><MarkdownView source={text} readable /></div>)}</>}
|
||||
</section>
|
||||
{item.review_items.length > 0 && <section><h3 className="font-medium">{t("Review required")}</h3>{item.review_items.map((review, i) => <p key={i} className="mt-2 text-sm">{t(review.message)}</p>)}</section>}
|
||||
</article>;
|
||||
|
||||
Reference in New Issue
Block a user