fix(docs): surface work-product open failures with a toast
Clicking a Files & Deliverables row fired openWorkProduct and then discarded the result with \`void\`. When the main process could not resolve the target — archived work product, missing workspace root, path outside the managed root, or \`shell.openPath\` reporting no associated app for the file type — the renderer stayed silent and the row looked like a dead button. The user had no way to know why "clicking" did nothing. Await the result in WorkProductRow and route non-ok responses through addToast with tone="danger". The caller sees the underlying failure (OPEN_PATH_FORBIDDEN / OPEN_PATH_FAILED / WORK_PRODUCT_NOT_FOUND / the shell's own message) and can act on it. No backend change — the handler already returned structured errors; this just stops dropping them. Typecheck and build:verify clean.
This commit is contained in:
1 parent
7301b00cb2
commit
9f43549606
1 file changed
+11
-2
@@ -3,6 +3,7 @@ import { FileText, FloppyDisk, NotePencil, Plus, Trash } from "../ui/icons";
|
||||
import type { AgentRecord, DocumentRecord, GoalRecord, ProjectRecord, WorkProductRecord } from "@shared/types";
|
||||
import { ActionButton, ConfirmDialog, EmptyState, InlineNotice, Input, ListFrame, ListRow, Modal, Select, StatusPill, TextArea } from "../ui";
|
||||
import { useT } from "../../i18n";
|
||||
import { useAppStore } from "../../state/store";
|
||||
import { documentTypeOptions, documentStatusOptions, splitTags, parseTags } from "./helpers";
|
||||
import { SectionHeader } from "./SectionHeader";
|
||||
import { NEW_ENTITY_ID } from "../../lib/constants";
|
||||
@@ -66,6 +67,7 @@ function DocumentEditor({ companyId, agents, projects, goals, document, onSaved
|
||||
}
|
||||
|
||||
function WorkProductRow({ product, companyId }: { product: WorkProductRecord; companyId: string }) {
|
||||
const addToast = useAppStore((s) => s.addToast);
|
||||
const subtitle = [
|
||||
product.type.replaceAll("_", " "),
|
||||
product.provider,
|
||||
@@ -76,9 +78,16 @@ function WorkProductRow({ product, companyId }: { product: WorkProductRecord; co
|
||||
// the main process can join it against the work product's workspace
|
||||
// root before handing off to the OS shell. Direct `openPath(externalId)`
|
||||
// used to flash a failure when the renderer tried to treat the relative
|
||||
// path as absolute.
|
||||
// path as absolute. Surface shell failures (no associated app, path
|
||||
// outside managed root, workspace moved) as a toast so the click
|
||||
// doesn't look like a dead button when the OS can't complete the open.
|
||||
const primaryAction = product.url || (product.provider === "filesystem" && product.externalId)
|
||||
? () => { void window.agentCompany.openWorkProduct({ companyId, id: product.id }); }
|
||||
? async () => {
|
||||
const result = await window.agentCompany.openWorkProduct({ companyId, id: product.id });
|
||||
if (!result.ok) {
|
||||
addToast(`Couldn't open ${product.title}: ${result.error.message}`, "danger");
|
||||
}
|
||||
}
|
||||
: undefined;
|
||||
return (
|
||||
<ListRow onClick={primaryAction}>
|
||||
|
||||
Reference in new issue
Block a user