You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
Repository navigation
Commit 8a8bcf3
Browse filesBrowse the repository at this point in the historyBrowse files
fix(app-shell): packaged flow rows keep their height; the platform reason opens from a neutral chip (objectui#12609) (#12647)
Fixes#12609
Clause-②: yes
Setup › Packaged automation: a flow row that carries the runtime's
`reason` sentence no longer grows to several lines. The sentence opens,
verbatim and in full, from a neutral **Details** chip on the flow name's
line. This is the card as triage narrowed it (comment 6210990723):
target 3 only, the half that classifies nothing.
## What changed
- `packages/app-shell/src/views/setup/PackagedAutomationPage.tsx`
- The paragraph element that rendered `row.reason` inside the flow cell
is gone.
- A new local component, `ReasonDetails`, draws a small outline chip (an
Info icon and the word "Details") inline after the flow's label. The
chip opens a popover that shows the sentence whole and muted, with no
alert role.
- The chip renders only when the row carries a non-empty string
`reason`. That rule is the existing one in `joinPackagedFlows`,
unchanged. The chip's label, icon and classes are the same on every row,
and nothing reads, matches or compares the sentence.
- A popover, not a tooltip: the sentence runs to several lines and can
name an operator switch the admin needs to copy. A popover opens on
click, tap and keyboard, and stays open to be read and selected.
- Rows without a reason render the same markup as before.
- `packages/i18n/src/locales/*.ts`: one new key,
`packagedAutomation.reasonDetails`, in all ten packs. Each pack uses the
word it already uses for "Details" elsewhere.
- `.changeset/12609-packaged-flow-reason-chip.md`: a patch for
`@object-ui/app-shell` and `@object-ui/i18n`, with the Clause-②
paragraph (one pack key added; no export or prop changes).
## Governing text
`@objectstack/spec` `FlowRuntimeState.reason`, verbatim: "A free-form
sentence, deliberately — the shape the two surfaces that already carry
this reason use. Consumers RENDER it; ⛔ do not parse it." This PR adds
no regex, `includes` or match on the reason, and the chip's wording
names no cause.
## Tests
`PackagedAutomationPage.test.tsx`, section 6 (the platform reason for an
unbound flow), reworked:
- **A deployment-policy row and a binding-failure row.** The row holds
no paragraph element and none of the sentence. Its "Details" chip opens
a dialog-role disclosure whose text is exactly the sentence: muted, with
no alert.
- **The chip does not classify.** The policy row's chip and the
binding-failure row's chip have the same text ("Details") and the same
classes.
- **Rows without a reason have no chip and the same text as before.**
This covers a bound row, a disabled row, an older backend's bare row and
a non-string reason.
`pnpm exec vitest run --maxWorkers=2
packages/app-shell/src/views/setup/PackagedAutomationPage.test.tsx`: 15
passed (15).
### Ablation (each red proven, then restored)
Each mutation went through objectstack's `scripts/ablation-replace.mjs`
in wrap mode. The anchor must hit, and the tool checks on-disk counts
and blob hashes. Restore is proven by blob == HEAD and an empty `git
diff HEAD`. The test imports the page from `src/`, so no build sits
between the mutation and the run.
| Mutation | Red tests |
|---|---|
| A: the reason paragraph put back in the row, chip kept | policy row,
binding-failure row: 2 failed, 13 passed (the row's paragraph count was
1, not 0) |
| B: the chip removed | policy row, binding-failure row,
does-not-classify: 3 failed, 12 passed |
| C: the chip drawn on every row | no-reason rows, non-string reason: 2
failed, 13 passed |
| D: the chip's label chosen from the sentence's words | policy row,
does-not-classify: 2 failed, 13 passed |
Mutation A's first attempt was refused by the tool before anything ran.
Its replacement contained the anchor, so the anchor count could not
drop. It was re-anchored and re-run, and the counts above come from the
run whose mutation landed.
## Local gates, all on `ad380ce`
objectui is hand-derived from its own `package.json` and
`.github/workflows/ci.yml`. Each exit code was captured before any pipe.
CI runs the full farm.
- `pnpm exec turbo run build --filter='@object-ui/app-shell^...'
--concurrency=2` (upstream closure of app-shell, which contains i18n's):
exit 0, 28 tasks successful (28)
- `pnpm --filter @object-ui/i18n type-check` and `pnpm --filter
@object-ui/app-shell type-check`: exit 0. app-shell's
`tsconfig.test.json` includes `src/**/*.test.tsx`, so the test file is
compiled.
- `pnpm exec vitest run --maxWorkers=2
packages/app-shell/src/views/setup/ packages/i18n/`: exit 0, 88 files
passed, 1387 tests passed, 13 skipped
- `pnpm check:i18n-keys`, `check:i18n-drift` (1 key added, 0 values
changed), `check:i18n-dead-keys` (the new key is not listed): exit 0
- `pnpm check:changeset-claims`, `pnpm changeset:check`, `node
scripts/check-changeset-presence.mjs`: exit 0
- `pnpm check:test-path-roots`, `pnpm check:spec-symbols`, `pnpm
check:new-line-citations` (0 new): exit 0
- `pnpm exec eslint --no-inline-config` on the 12 changed `.ts` and
`.tsx` files: exit 0, no output
## Acceptance notes
- **The switch is unchanged.** It still shows the row's `enabled` field,
so a flow that deployment policy keeps unarmed still reads On. Showing
the effective state needs the structured discriminator that
objectstack-ai/objectstack#23842 adds, and this PR does not touch the
switch.
- **Card targets 1 and 2 are not here.** The chip that names the
deployment policy and the once-banner both need that discriminator. Per
triage, the console half of those is filed once the field is in a
published `@objectstack/spec`.
- **Acceptance 2, the screenshot at 1280 px in light and dark: NOT
MEASURED in this run.** A reader needs four things:
- a backend with packaged time-triggered flows and
`OS_AUTOMATION_SCHEDULED_WORK_ENABLED` unset, so those rows carry the
policy sentence;
- a console started from this branch, on its own port, pointed at that
backend;
- the page `/apps/com.objectstack.setup/component/automation/packaged`;
- a click on a row's Details chip, to read the popover.
- **Row height in pixels: NOT MEASURED.** No browser ran here. What the
tests pin is structural: the row holds no paragraph, and the chip sits
inline in the label's line (`leading-4` text, a one-pixel border, no
vertical padding). Rows without a reason were already two lines tall
(the label above the machine name), in cells with the table primitive's
`p-4` padding. So the claim this PR makes is "a reason row is as tall as
any other row", not a pixel figure; the screenshot reading above should
take the figure.
- **Card acceptance 3, `pnpm --filter @object-ui/app-shell test`:** the
whole-package run is left to CI. Locally, the setup directory and the
whole i18n package ran, as listed above.
- **Docs:** no page under `content/docs/` describes how this page shows
the reason, so no doc changed.
- **Overlap:** objectui#12606 (another seat, in flight) owns the header
row of Setup component pages. This PR touches only this file's flow rows
and its module docblock, and the later lander merges `main`.
---
_Generated by [Claude
Code](https://claude.ai/code/session_011K9g23W67dy2zwnyzaoB6o)_
Co-authored-by: Claude <noreply@anthropic.com>
Setup › Packaged automation keeps a flow row to the table's height when the platform says why the flow is not armed (objectui#12609).
7
+
8
+
The runtime's `reason` sentence for an enabled flow that is not armed used to render as a paragraph under the flow's name, so every such row grew to several lines and the table stopped scanning as a table. The sentence now opens from a small "Details" chip on the name's line, in a popover that shows it whole and unedited, in muted text. A row without a reason shows no chip and renders as before.
9
+
10
+
The chip does not say what the reason is. Its label is the same on every row that carries a reason, whatever the sentence says, because the contract says the field is rendered and never parsed, and a deployment-policy row and a binding failure arrive in the same shape. The activation switch still shows the flow's `enabled` field, as before.
11
+
12
+
**Clause-②: yes (widening)**: `@object-ui/i18n`'s ten locale packs gain one key, `packagedAutomation.reasonDetails`. No export, prop or other key changes on either package.
Copy file name to clipboardExpand all lines: packages/i18n/src/locales/ar.ts
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -4542,6 +4542,7 @@ const ar = {
4542
4542
toggleFailed: "تعذّر تغيير التفعيل.",
4543
4543
cloneFailedHttp: "تعذّر استنساخ هذا التدفق (HTTP {{status}}).",
4544
4544
cloneFailed: "تعذّر استنساخ هذا التدفق.",
4545
+
reasonDetails: "التفاصيل",
4545
4546
actionsSubtitle: "إجراءات تأتي مع الحزم المثبّتة. أوقف أحدها في هذا النشر فيتوقف عن العمل في كل مكان يُعرض فيه. ويبقى بإمكانك إنشاء إجراء خاص بك إلى جانبه في Studio.",
Copy file name to clipboardExpand all lines: packages/i18n/src/locales/de.ts
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -4158,6 +4158,7 @@ const de = {
4158
4158
toggleFailed: "Aktivierung konnte nicht geändert werden.",
4159
4159
cloneFailedHttp: "Dieser Flow konnte nicht geklont werden (HTTP {{status}}).",
4160
4160
cloneFailed: "Dieser Flow konnte nicht geklont werden.",
4161
+
reasonDetails: "Details",
4161
4162
actionsSubtitle: "Aktionen aus installierten Paketen. Schalten Sie eine für diese Installation ab, und sie läuft überall dort nicht mehr, wo sie angeboten wird. Eine eigene Aktion daneben zu erstellen, bleibt Ihnen im Studio offen.",
Copy file name to clipboardExpand all lines: packages/i18n/src/locales/es.ts
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -4251,6 +4251,7 @@ const es = {
4251
4251
toggleFailed: "No se pudo cambiar la activación.",
4252
4252
cloneFailedHttp: "No se pudo clonar este flujo (HTTP {{status}}).",
4253
4253
cloneFailed: "No se pudo clonar este flujo.",
4254
+
reasonDetails: "Detalles",
4254
4255
actionsSubtitle: "Acciones incluidas en los paquetes instalados. Desactiva una en esta implementación y dejará de ejecutarse en todos los lugares donde se ofrece. Crear tu propia acción junto a ella sigue estando disponible en Studio.",
Copy file name to clipboardExpand all lines: packages/i18n/src/locales/fr.ts
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -4248,6 +4248,7 @@ const fr = {
4248
4248
toggleFailed: "Impossible de modifier l'activation.",
4249
4249
cloneFailedHttp: "Impossible de cloner ce flux (HTTP {{status}}).",
4250
4250
cloneFailed: "Impossible de cloner ce flux.",
4251
+
reasonDetails: "Détails",
4251
4252
actionsSubtitle: "Actions fournies par les packages installés. Désactivez-en une pour ce déploiement et elle cesse de s'exécuter partout où elle est proposée. Vous pouvez toujours créer votre propre action à côté, dans Studio.",
0 commit comments