Repository navigation
fix(plugin-approvals): the approval request page's highlights strip names the flow by its label - #24279
Conversation
…ames the flow by its label The served sys_approval_request_detail page's highlights strip listed process_name (the machine source, flow:NAME) where the flow's label, process_label, is declared and served. The strip and the object's highlightFields now both lead with process_label; record_id stays on the object's list and off the strip. The object's list moves with the strip because the page's Details tab is a bare record:details node, which draws the object's highlightFields minus the strip: a strip-only change would have moved process_name into that tab. Claude-Session: https://claude.ai/code/session_01Nk17Z26X5DB59iQztDBADH Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 21 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 8 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 6 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin be111dc14f0b40234eb8a685df7c7d70c23e6513 && git checkout be111dc14f0b40234eb8a685df7c7d70c23e6513
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 93b4acb57ec23c4e94a7047133ce612f89a13838 046ca5b6672da75d3562ba9b1741370da96ce39a && git checkout -B drift-repro 93b4acb57ec23c4e94a7047133ce612f89a13838 && git merge --no-ff 046ca5b6672da75d3562ba9b1741370da96ce39a
node scripts/docs-audit/affected-docs.mjs --json 93b4acb57ec23c4e94a7047133ce612f89a13838
|
席位核对ACCEPT ·
Generated by Claude Code |
Fixes #24264
Clause-②: no
The served
sys_approval_request_detailrecord page's highlights strip now names the flow by its label,process_label(the "Flow" field). Before, it listed the machine sourceprocess_name, so its first chip read likeflow:deal_desk. The object'shighlightFieldsmakes the same swap:process_labeltakes the place ofprocess_name, andrecord_idstays on the object's list and off the strip.Responsibility:
plugin-approvals' own declarations (the page's highlightsfieldsand the object'shighlightFields) | the platform path already serves the flow label:process_labelis declared on the object, served by the approvals get, and read by the record title's formula and every request list | reached by every user who opens a served approval request record page.The choice: object-level, not page-only
Readings are against objectstack
53ef75243and objectui at the console pin.objectui-sha=5e15928b4, bygit showandgit grep. The page was not driven in a browser.The page's own Details tab reads the object's list, so a page-only edit is not page-only. The Details tab is a
record:detailsnode with neithersectionsnorfields. The spec declares what such a node draws (RecordDetailsProps,packages/spec/src/ui/component.zod.ts): the object'shighlightFields. At the pin, objectui'srecord-details.tsx(objectui#12433) draws that list minus every field the mounted strip registers and minus the H1 field. Its pinrecord-details.highlightFieldsFallback-12433.test.tsxnames this page as the case it was built for. So the Details tab is the object's list minus the strip:maintodayprocess_name,object_name,status,current_step,submitter_id,updated_atrecord_id(the target record card)process_label, …process_name,record_id: a "Source: flow:NAME" row appears in the tabprocess_label, …record_id, unchangedThe page's header slot falls through to the synthesizer. Since the page authors
highlights, the synthesizer's derived strip andrecord:pathare not emitted (buildDefaultPageSchema's highlights branch), so the header reads nothing from this list.Other readers of the object's
highlightFields, and whether a request surface reaches them today:ObjectView/ObjectGriddefault columns: used only by a list view that declares nocolumns. All foursys_approval_requestlist views declare columns, and every one already listsprocess_label. Not reached.InterfaceListPagedefault columns,ObjectKanbandefault card fields, andRelatedListdefault columns and picker: no interface page, kanban view or related list of requests is declared in this repository. Not reached.LookupFielddropdown preview columns (deriveLookupColumns): the two lookups to a request,sys_approval_action.request_idandsys_approval_approver.request_id, sit on objects whoseenable.apiMethodsis['get', 'list'], so no create or edit form opens that picker. Not reached. The Action History list's request cell draws the request's title, not this list.RecordPreviewCard, the pointer card areferenceViapair draws: reached only where a pointer pair names a request row, for example an audit or activity row about a request. Whether such rows exist is NOT MEASURED. Where they do, the card shows the Flow label where it showed the Source.process_label.@objectstack/lint(field references and semantic roles),metadata-core's field-security fold of the served schema, andmetadata-protocol's build probes. None of these changes behaviour for a list of existing fields. The page test's build-rule leg stays green.objectui's console served-page pin copies (
apps/console/src/services/approvalRequestsDataSource.servedPage*.test.tsxat the pin) copy both lists withprocess_name. objectstack-ai/objectui#12484 rewrites them, and they are not touched here.The null case, within declared fields
The console reads a request through the approvals get (
routeApprovalRecordReads,apps/console/src/AppContent.tsxat the pin). There,rowFromRequestservesprocess_labelby the one chain indisplay-labels.ts(requestDisplayLabels): the stored label, else the node-config snapshot's__flowLabel, elseprocess_namehumanized (flow:deal_deskbecomesDeal Desk).approval-service.test.tspins that fallback ("rows fall back to prettified machine names when labels are absent"). What a user sees:flow:NAME.process_namethat humanizes to nothing (flow:followed by nothing), andopenNodeRequestnever writes one (it writesflow:plus the flow name or the node id). The field then has no value, and the console's strip draws no chip for a field with no value in read mode, so there is no Flow chip. The record title still namesprocess_name: on the approvals get throughtitleFormat, since that get serves nodisplay_title, and on the data API throughdisplay_title's fallback.process_labelis the stored column, null on a row the boot fill has not labelled. The chip is then absent, anddisplay_titlereadsprocess_name · record_id.No other field fills the chip. No field, formula or column is added, and there is no spec row:
record:highlightsfieldsalready admits the field.Tests (at
046ca5b66)pnpm --filter '@objectstack/plugin-approvals^...' build: VERDICT command-exit 0.pnpm --filter @objectstack/plugin-approvals build: exit 0.pnpm --filter @objectstack/plugin-approvals exec vitest run --maxWorkers=2 src/sys-approval-request-page.test.ts src/sys-approval-request.object.test.ts src/sys-approval-display-title.test.ts: 3 files, 36 tests passed.pnpm --filter @objectstack/plugin-approvals test:Test Files 81 passed (81),Tests 1108 passed (1108). The package has 81 test files.pnpm --filter @objectstack/plugin-approvals typecheck: exit 0, withcheck:test-typecheck: OK.sys-approval-request-page.test.tsmoves. Its existing case still holds the strip to the object's list minusrecord_id. A new case asserts three things: both lists lead withprocess_label, neither listsprocess_name, and the object's list minus the strip is exactlyrecord_id(the Details tab).Ablation (one run, then restored).
node scripts/ablation-replace.mjsputprocess_nameback at the head of the page's strip. Its on-disk evidence: anchor x1 → x0, replacement x0 → x1, blobaea7e3212b97→822555700a37. The pin went red:Tests 2 failed | 15 passed (17). The new case failed withexpected 'process_name' to be 'process_label', and the existing case failed on the strip no longer equalling the object's list minusrecord_id. The restore leg: blob after restore == HEAD (aea7e3212b97),git diff HEADempty,git statusclean. No test file is left behind by the ablation.Gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackat046ca5b66derived 67 commands for this diff. All 67 ran locally at046ca5b66, each exit code captured before any pipe:pnpm check:i18n(the CLI was not built) andpnpm check:dual-build-cjs-loads(packages withoutdist/). After the prerequisite builds (the i18n gate's own one-command closure, thenturbo run build --filter=!@objectstack/docs), both exited 0.check-i18n-bundles: OK (10 package(s) — all bundles in sync, no undeclared authoring keys);✓ check:dual-build-cjs-loads — 111 published require entry point(s) across 69 package(s) load.node scripts/pm/dispatch-gates.mjs --ranreconciliation:67 derived, 67 run, 0 NOT-MEASURED, 0 UNRUN.The repo-wide scans (
pnpm lintand the rest of the CI battery) are CI's. Their PR check-runs are the reading.Acceptance notes
current_step, the Approval node's machine id (openNodeRequestwritescurrent_step: input.nodeId, androwFromRequestserves it as written). It is the same machine-name shape. Swapping incurrent_step_labelthe same way would draw nothing on the served page, because the approvals get serves the step label asstep_label, not under the column's name.flow:NAME · IDon the approvals get, which serves nodisplay_title. approvals B1 closing card (ruling C on objectui#12438): the inbox opens a request on the served sys_approval_request page where the side sheet is, deletes the sheet, and lists each retired pin against its user report objectui#12484 carries the H1 (the face 5 fit-check reading6246163097on approvals face 5 of 5 (ruling C on objectui#12438): the served sys_approval_request page shows the request's flow origin and its vertical multi-step progress line, as the inbox side sheet does objectui#12491). This PR does not touch it.highlightFieldsminus the strip, which isrecord_idonly. The same header edit corrects it.Generated by Claude Code