Skip to content

fix(app-shell): Setup walkthrough rows — one name for Setup, confirms before Disable and before switching a packaged action off, read-only reasons, forced-reset wording - #27849

Merged
objectstack-fleet[bot] merged 11 commits into
mainfrom
claude/project-thread-uywna1
Oct 30, 2026
Merged

objectstack-fleet[bot] merged 11 commits into
mainfrom
claude/project-thread-uywna1

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC

Requested by Bill · project thread
Refs #27521
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:Setup 走查建议的界面部分——首页链接与应用切换器统一用 Setup 应用自己的名称;软件包页说明只读原因、禁用前确认、改称「删除软件包」;打包自动化关闭动作前确认、成功后提示、显示对象名称、手机上不再溢出;强制改密页用控制台自己的译文并把字段叫「临时密码」;记录页标签栏可横向滚动并有渐隐提示;info/warning 不再显示成警报橙色;Setup 页眉标签可用键盘打开说明。
  • 为什么改:Setup and Studio: suggestions from the 18.3.0 RC browser walkthrough: Setup naming and machine values, invitation and user onboarding, permission-set authoring, dialog focus, Studio first run, validation and flow builders, and publish-panel wording #27521 是 18.3.0 RC 走查的建议卡,分诊要求每行要么做掉、要么建卡、要么给出不做的理由;这里是 Setup 第 1–23 行中只需改 ui 的部分。
  • 风险与回滚:只动 ui 文案、确认框和布局,不改 spec、服务端或元数据协议;标签栏和严重度颜色是所有应用共用的渲染器,影响面最大;回滚即还原本 PR。
  • 先看:ui/packages/components/src/renderers/layout/containers.tsx(标签栏滚动与渐隐)、ui/packages/app-shell/src/views/setup/PackagedActionsSection.tsx(关闭前确认)、ui/packages/app-shell/src/views/metadata-admin/PackagesPage.tsx(禁用确认与只读原因)。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/setup/ packages/app-shell/src/views/metadata-admin/PackagesPage.readOnlyReasonAndDisableConfirm-27521.test.tsx,预期全部通过。
  • 需要你做的:无,席位落地。

What changes

Setup rows 1–23 of #27521 (row 6 is #27797), worked one by one against main. Taken here (ui only):

  • Row 1 — one name for Setup. Home's apps-strip link and the app switcher's entry now read the Setup app's own served label (appLabel over resolveKeyedI18nLabel), the name the app header shows, instead of the fixed "System Settings" / "Settings" strings; those strings stay only as the fallback when no app object is in hand. The Settings hub keeps its title: it is a page inside Setup ("All Settings" in the sidebar), not the app.
  • Row 4 (ui half) — info is not an alarm. A select value info or warning with no declared colour now reads blue or yellow from SEMANTIC_COLOR_MAP (@object-ui/fields), instead of the hashed palette slot that drew Notifications' info orange. A declared option colour still wins.
  • Row 5 (ui half) — header tags explain themselves from the keyboard. ManagedByBadge already opens its explanation on hover (measured on main); the tag now takes focus (tabIndex=0), which opens the same tooltip.
  • Rows 12 and 22 (ui half) — the forced password change. On PASSWORD_RESET_REQUIRED the overlay draws its own body (auth.remediation.password.resetBody: an administrator set a temporary password) instead of the server's sentence, which repeated the title in English for a French user; the first field is "Temporary password" (auth.remediation.password.temporary). An expired password keeps the server's sentence and "Current password". Both keys in all ten packs.
  • Row 13 (ui half) — record tab strips scroll. A horizontal page:tabs strip wider than its box scrolls sideways (overflow-x-auto, triggers shrink-0) and fades at each edge that hides a tab; useHorizontalOverflow (package-private, not exported) re-reads the edge on scroll and resize into data-overflow. The bottom rule became an inset shadow so the active underline still draws over it once the strip clips at its padding box. Measured on the user record at 1440: scrollWidth 1269 in a 1088 box, cut with no cue before; now it scrolls and reads end / both / start.
  • Row 20 — Packaged automation. Switching a packaged action off asks first (off stops it everywhere it is offered); switching on runs at once. An accepted switch, action or flow, says so in a toast; a refused one keeps its verbatim refusal and no toast. The Object column shows the object's label (useObjectLabel) over the machine name. On a phone the fixed column widths apply from sm up, long machine names break, and cells pad less: measured at 390, both tables went from scrollWidth 523 / 537 in a 342 box to 342 / 342. Not touched: Setup › Packaged automation: a packaged action switched off keeps its button on the record page, and clicking it shows a toast naming sys_metadata_activation and ADR-0126 #27504's question (whether a switched-off action's button stays on the record page).
  • Row 21 — Packages. The sheet says why a read-only package offers no write action: loaded from code (scope: 'project'), read-only here (scope-less read-only), or part of the platform (system / cloud, reworded from "platform kernel package"). Disable asks first; Enable runs at once. "Delete app" becomes "Delete package" (key engine.packages.detail.deletePackage). Installed Apps gets its own subtitle.

Fixed on main, not changed here:

Carded, filed from the paragraphs in the os-dev-report comment on #27521: rows 2 (#27853), 3 (#27854), 4 rest (#27855), 10 Create User half (#27857), 12 Create User result line (#27858), 13 rest (#27859), 14 (#27861, #27862), 15 columns (#27863), 16 field order and stacked messages (#27864, #27865), 17 (#27866, too large for this PR), 19 (#27867), 22 rest (#27869). Each one's text, labels or layout comes from server or spec metadata (service-settings manifests, platform-objects, plugin-auth, packages/spec/src/security/permission.form.ts), or is its own ui card (row 14's registry-label read face, row 16's stacked messages in ResourceEditPage, row 17's grid).

Will not do:

  • Row 5, empty states — Sharing Rules and Webhooks open on their "Active" view, which filters active = true; "No records match this view's filter" is the accurate sentence there, and first-run copy would misstate a view that hides inactive rows.
  • Row 15, hover-only row actions — the reveal on hover, focus-within, selection and coarse pointers is the grid-wide pattern of every list in the product (RowActionMenu, data-table); changing it for Setup alone would split one pattern in two.

Later, separate PR: rows 7, 8, 9, 10 (Invite half), 11 and 23 touch the Invitations surface. #27797 is blocked behind server card #27843, so these rows wait for #27843 to land.

Row Answer Pin or reason
1 taken AppSwitcher.homeMenu-12605 (served label, any label), HomePage.greetingAndApps-12601
2 carded #27853 server copy (service-settings manifests, plugin-webhooks)
3 carded #27854 server nav (setup-nav.contributions.ts)
4 taken (colour) · carded #27855 (rest) badge-severity-27521
5 taken (keyboard) · fixed on main (hover) · will-not-do (empty states) ManagedByBadge.keyboard-27521
6 #27797 —
7, 8, 9, 10 (Invite), 11, 23 waits on #27843, separate PR —
10 (Create User) carded #27857 plugin-auth refusal, sys-user.object.ts params
12 taken (overlay) · carded #27858 (result line) RemediationOverlay.passwordResetRequired-12365 (new describe), forcedResetNewPassword
13 taken (tab strip) · carded #27859 (rest) page-tabs-overflow-cue-27521
14 carded #27861 (ui) · #27862 (server) ui read face + server grant message
15 will-not-do (hover) · carded #27863 (columns) grid-wide pattern
16 fixed on main (derivation) · carded #27864 (order) · #27865 (messages) spec form + ResourceEditPage
17 carded #27866 too large here
18 fixed on main by #27808 —
19 carded #27867 server manifest; "de" still refused, measured
20 taken PackagedActionsSection.test §6; phone layout measured in Chromium (jsdom lays nothing out)
21 taken PackagesPage.readOnlyReasonAndDisableConfirm-27521
22 taken (overlay) · carded #27869 (rest) as row 12

Tests

New: ManagedByBadge.keyboard-27521, badge-severity-27521, page-tabs-overflow-cue-27521, PackagesPage.readOnlyReasonAndDisableConfirm-27521, a describe in RemediationOverlay.passwordResetRequired-12365, §6 of PackagedActionsSection.test, a case in AppSwitcher.homeMenu-12605. Existing pins updated for the new words: "Delete package", "Temporary password", the switch-off confirm (switchOff helper), the Setup link's label.

Acceptance notes

  • @object-ui/i18n's de-quote-pairing-3876 pins an exact count of quoted spans in the de pack; the new de strings follow the pack's own unquoted {{label}} form for the flow switch, so the count stands.
  • The tab-strip fade is a CSS mask on the sticky strip, so the strip's own background fades with the tabs at that edge.
  • @object-ui/i18n: engine.packages.detail.deleteApp is renamed engine.packages.detail.deletePackage; no other reader of the old key exists in the tree.

Verification

All on head 5a54fd98 (after merging origin/main, pnpm install --frozen-lockfile and a full turbo run build, 114/114) unless a line says otherwise.

Targeted tests — 483 files, 9777 passed, 0 failed
pnpm --dir ui exec vitest run --maxWorkers=2 packages/app-shell/src/views/setup/ packages/app-shell/src/views/metadata-admin/PackagesPage packages/app-shell/src/views/metadata-admin/AssignedUsersSection packages/app-shell/src/console/__tests__/RemediationOverlay packages/app-shell/src/console/home/ packages/app-shell/src/layout/__tests__/AppSwitcher packages/app-shell/src/components/ packages/fields/src/__tests__/ packages/components/src/__tests__/page-tabs packages/i18n/ scripts/
 Test Files  483 passed | 3 skipped (486)
      Tests  9777 passed | 22 skipped (9799)
os-verify-lock: VERDICT command-exit 0

Before the merge, on ed05c2ac: packages/components/src/__tests__/ 256 files / 2412 passed; console/home + layout 152 / 974; components/ + fields + the ManagedBy pins 149 / 2940.

Ablation — the Disable confirm

node scripts/ablation-replace.mjs on PackagesPage.tsx, anchor onClick={() => (enabled ? startAction(() => setDisableOpen(true)) : void toggleEnable())} → onClick={() => void toggleEnable()}: anchor x1 → x0, blob 032c769d → 41626a6b; PackagesPage.readOnlyReasonAndDisableConfirm-27521 2 failed / 6 passed (both (b) cases); restored: blob == HEAD 032c769d, git diff HEAD empty.

Gates (local subset, exit codes captured before any pipe)

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 34 families on 2c0f76c9; each run:

node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0
node scripts/check-adr-0087-registration.mjs --self-test :: exit 0
node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-empty-changeset.mjs --base origin/main :: exit 0
node scripts/check-empty-changeset.mjs --self-test :: exit 0
node scripts/check-sdui-manifest.mjs :: exit 0
node scripts/check-sdui-manifest.mjs --self-test :: exit 0
node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0
node scripts/release-pending-publish.mjs --self-test :: exit 0
pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0
pnpm check:changeset-gate-self-tests :: exit 0
pnpm check:closed-ceremony-text :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:dispatcher-error-vocabulary :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:engine-double-contract :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:pm-changeset-deadline-census :: exit 0
pnpm check:published-files :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:skill-identifier-liveness :: exit 0
pnpm check:test-source-alias :: exit 0
pnpm check:tier-file-adoption :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:undeclared-dep-imports :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
pnpm --dir ui exec vitest run scripts/ :: exit 0
pnpm --filter @object-ui/components run type-check :: exit 0
pnpm --filter @object-ui/fields run type-check :: exit 0
pnpm --filter @object-ui/i18n run type-check :: exit 0
pnpm --filter @object-ui/app-shell run type-check :: exit 0
eslint (changed ui files) :: exit 1
pnpm --dir ui check:new-line-citations :: exit 0
eslint (changed ui files, inline config honoured) :: exit 0

pnpm --dir ui exec vitest run scripts/ first ran together with packages/i18n/ and went red on de-quote-pairing-3876 (the new de strings carried „…“); fixed in ed05c2ac, then green in the run above. The full ESLint run with --no-inline-config reports one pre-existing error in containers.tsx (react-hooks/static-components on the record-title read face, already disabled inline on main); with inline config honoured: 0 errors.

Browser (Chromium, stock `examples/app-showcase --seed-admin`, admin)
  • 1440: Home shows "System Settings" and the switcher "Settings" on main; the Setup header shows "Setup".
  • 1440, user record: tab strip scrollWidth 1269 in a 1088 box with overflow: visible on main; on the branch it scrolls, data-overflow reads end → both → start, the active underline sits on the rule.
  • 390, Packaged automation: tables scrollWidth 523 / 537 in a 342 box on main; 342 / 342 on the branch; 1136 / 1136 at 1440.
  • 1440, Company: Country "de" answers "1 setting needs attention: Country", input maxlength=2 (row 19, carded).

Generated by Claude Code

claude added 11 commits October 29, 2026 23:56
…able header tags

Claude-Session: https://claude.ai/code/session_01Utp6CZLnkdSxVfvNuQ6RgB
Co-authored-by: Claude <noreply@anthropic.com>
…-uywna1

# Conflicts:
#	ui/packages/app-shell/src/views/metadata-admin/AssignedUsersSection.pickerColumns-27433.test.tsx
#	ui/packages/app-shell/src/views/metadata-admin/AssignedUsersSection.tsx
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC

席位核对

ACCEPT · head 5a54fd9875ae7fe97a162217f2a60276d29064f3 · 2026-10-30T02:25Z

  1. Shape: draft → main, Refs #27521 (Setup rows only; the card stays open for the Invitations rows behind invite-member answers outcome by mail delivery and sys_invitation gains a server copy_invitation_link action that answers the accept URL (ruling E on #27797) #27843 and for the Studio rows that seat 3 holds), attribution block on top, root changeset (four @object-ui/* patches). 39 files, +789 / −66. No assignee, no reviewer.
  2. Card rule met (seat read the diff): each Setup row is taken here (ui half), carded, or answered "will not do" with a reason, as Setup and Studio: suggestions from the 18.3.0 RC browser walkthrough: Setup naming and machine values, invitation and user onboarding, permission-set authoring, dialog focus, Studio first run, validation and flow builders, and publish-panel wording #27521's acceptance asks.
  3. Gates (check-runs on this head): 44 success, 11 skipped, 0 red.
    • Named runs: Lint & Repo Gates 123850773199, TypeScript Type Check 123850261643, Type Check UI 123848958555, Test UI 123853312898.
    • The dev's readings: 34/34 derived gates with 0 NOT-MEASURED; 483 test files / 9777 tests passed; the Disable-confirm ablation goes red 2/8.
  4. Contract review: not owed. Clause-②: no (the new hook is not exported from @object-ui/components), Metadata-protocol: none.
  5. Accepted deviation: none from the card. Noted for the record page work: the page:tabs strip change in renderers/layout/containers.tsx is shared with every record page. Record page v4: same-shaped related panels with no collapse, a persistent tab row under the header (the enlarged state is the active tab), Activity as the first panel and a tab, one top bar on every face, tiers by container width #27524 (the v4 tab row) will rebuild that strip, so it merges main after this lands.
  6. Landing: not governed (check-governed-merges --pr 27849: 0 of 39 paths hit the register), +789 / −66. The seat lands it: ready + auto-merge now.

Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant