Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

console: the floating assistant button covers the inline-edit 保存 and the attachment 删除附件 buttons, and attachment delete has no confirmation (objectui#12211 item 2) #12248

Closed

Description

@objectstack-fleet

Filing gate ①: a reproduced product defect, split from list card #12211 (item 2) as triage 6121957396 directs ("The dispatching seat splits it per item into sub-issues"). This card carries item 2 only. The parent closes when every item is split and closed.

Parent: #12211. Domain and priority are inherited from the parent (domain:ui, priority:p3); area:files per triage.
Reader: the domain:ui lane (either seat), from pm:queue.
Dedupe: the parent's table, item 2: floating assistant button covers (2 hits; nearest objectui#10899, closed: the FAB over the chat send button) and attachment delete confirm (15 hits; nearest objectui#12047, closed: the grant-gated attachments panel).

Triage's note for this item (6121957396), verbatim: "Item 2: the confirmation on attachment delete is the console's ordinary destructive-action confirm. ⛔ No new setting."

What happens (from the parent, item 2)

Source: the 2026-10-12 hosted-shape browser pass of HotCRM 4.0.1 on a cloud rig at production v1.36.0's pins (objectui d758f2f20d), zh-CN.

  • Reach: case and task records, viewport 1440×900 and 1440×1400.
    • document.elementFromPoint at the centre of 保存 (1365,849) and of 删除附件 (1383,847) returns the assistant button 打开HotCRM助手. A click opens the assistant instead.
    • One tester lost an inline save this way.
    • The delete button is only reachable by keyboard (Tab from 下载, then Enter), and it deletes at once: DELETE /api/v1/data/sys_attachment/… → 200, with no confirm.

Acceptance

  • Neither button sits under the FAB at common viewports. For example, the FAB yields while an inline-edit bar or a row action is in its corner.
  • Attachment delete asks for confirmation, through the console's ordinary destructive-action confirm.

Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:filesFiles — upload, download, signed URLs, access derived from the parent record
    on Oct 12, 2026
  2. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 (item 2 of objectui#12211, as triage 6121957396 directs on the parent: the console's assistant button no longer covers the inline-edit save and the attachment delete controls at common viewports, and attachment delete asks through the console's ordinary destructive-action confirm; ⛔ no new setting)
    Session: session_01G5TSaEwbEQsKMjhzTB4rEd
    Account: os-warren
    Branch: claude/issue-12248-fab-yields-attachment-confirm
    Worktree: objectui-issue-12248
    Domain: domain:ui
    Seat: domain:ui#2
    File surface, on objectui main 7578323a:

    • The button: packages/app-shell/src/layout/ConsoleChatbotFab.tsx (fixed bottom-20 right-6, sm:bottom-6). It yields while an inline-edit save bar or a bottom-right row action occupies its corner; the mechanism (a shell-level signal, an inset, or hiding) is the dev's, measured.
    • The save bar, only where it must signal or clear the corner: packages/plugin-detail/src/InlineEditSaveBar.tsx.
    • The attachment delete: packages/app-shell/src/views/RecordAttachmentsPanel.tsx. The row's delete goes through ActionConfirmDialog (views/ActionConfirmDialog.tsx, read and reused, ⛔ not changed), the confirm the record page's own delete uses (objectui#11001).
    • Strings: packages/i18n/src/locales/*.ts, all ten packs, only if no existing key says "delete this attachment" truly. An existing key that names a different noun is ⛔ not reused.
    • Co-located tests, and .changeset/12248-fab-yields-attachment-confirm.md (@object-ui/app-shell; @object-ui/plugin-detail and @object-ui/i18n if touched; ⛔ never major).
    • ⛔ No new setting, prop on a published component, or spec key.
    • (Stop on breach; explain in the report.)
      Container & model: M, mode:subagent, model: default tier — dispatch-gates --tier --repo objectstack-ai/objectui: "no path-derived mandate"
      Clause-②: yes
      Responsibility: objectui's console shell (@object-ui/app-shell ConsoleChatbotFab), whose fixed bottom-right button sits over the record page's inline-edit save bar and the attachments panel's delete; and RecordAttachmentsPanel, whose delete calls dataSource.delete at once | the record page's own delete already asks through ActionConfirmDialog (objectui#11001) | every user editing a record inline or deleting an attachment at 1440-wide viewports (measured in the parent's 2026-10-12 hosted pass on HotCRM 4.0.1: elementFromPoint at the centre of 保存 and 删除附件 returned the assistant button; one tester lost an inline save; DELETE sys_attachment answered 200 with no confirm)
      Thread-read: none
      Serial constraints cleared: read at 2026-10-12T14:01Z on objectui main 7578323a:
    • The files: their last changes on main (023f00d4, 9b6c19ef) have landed. No open PR touches ConsoleChatbotFab.tsx, RecordAttachmentsPanel.tsx, ActionConfirmDialog.tsx or InlineEditSaveBar.tsx (8 open PRs read).
    • Neighbours: this seat's open PRs objectui#12259 (plugin-detail feed files) and objectui#12260 (console/home, layout/InboxPopover.tsx, new layout/ActivityObjectLabel.tsx) share no file. Clause-②: yes is declared up front for the likely pack key; if the dev measures an existing key that fits, the report narrows it to no and says why.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 12248,
    "status": "done",
    "branch": "claude/issue-12248-fab-yields-attachment-confirm",
    "pr": "#12264",
    "session": "session_01G5TSaEwbEQsKMjhzTB4rEd (mode:subagent, the dispatching seat's id; container CLAUDE_CODE_REMOTE_SESSION_ID cse_01G5TSaEwbEQsKMjhzTB4rEd)",
    "premise_still_valid": true,
    "summary": "Both defects reproduced on objectui main 7578323 in a Playwright harness that mounts the real RecordDetailView, AppShell and ConsoleChatbotFab. At 1440x900 zh, Save's centre was (1365.2, 849) and the last attachment row's Delete centre was (1383, 847), and elementFromPoint answered 打开HotCRM助手 at both, matching the card. ConsoleChatbotFab now goes invisible while an element marked data-fab-yield overlaps its own box. It re-measures once per frame on captured scroll, on resize and on childList mutations. InlineEditSaveBar marks its bar, and RecordAttachmentsPanel marks its Download and Delete row actions. The attachment delete now asks through ActionConfirmDialog (unchanged, destructive), mounted the way RecordDetailView mounts it. The dialog uses the existing title key detail.deleteAttachment, the existing confirm label objectActions.deleteConfirmButton, and one new key, detail.deleteAttachmentConfirm, which interpolates the file name and is in all ten packs. After the fix, at 1440x900, 1440x1400, 1280x720 and 1920x1080 in en and zh, the FAB is hidden and elementFromPoint returns Save or Delete. A click on Save opens the assistant 0 times. At 390x844 the FAB stays visible during an inline edit, because the bar sits below it. Cancel deletes nothing and confirm deletes exactly once. PM assumption 1 held: no existing shell signal could carry it, so the signal is a DOM attribute, with no setting, prop, export or spec key. Assumption 2: a yield for the save bar alone does not clear the row action; that needed its own marker, which was measured. Assumption 3 held. Assumption 4: no existing key fits, so one key was added and Clause-② yes stands. Assumption 5: pins written and ablated.",
    "tests": "At HEAD 50d6a6f: vitest over the 7 directly affected files: 'Test Files 7 passed (7) / Tests 64 passed (64)'. vitest packages/i18n/: '83 passed (83) / Tests 1321 passed | 13 skipped'. Script tests placeholder-spelling-parity and one-authority-per-exported-name-6273: '2 passed / 15 passed'. At f8ad8a0, a narrowed run (declared) over packages/app-shell/src/layout/, the 4 attachments-panel test files, RecordDetailView.deleteConfirmDialog-11001, AiChatPage.planApprovalReachesLaunchers-11666, packages/plugin-detail/src/tests/ and packages/i18n/: 'Test Files 1 failed | 316 passed | 1 skipped'. The one failure was de-quote-pairing-3876 (pinned counts 84 to 85 for the new matched German pair), updated in 50d6a6f and green above. Type-check (app-shell, plugin-detail, i18n, script names echoed) exited 0 at f8ad8a0 after building the closure (turbo build --filter='@object-ui/app-shell^...' --concurrency=2, 28/28 tasks). tsc -p tsconfig.test.json --listFiles at 50d6a6f lists both new test files, RecordAttachmentsPanel.test.tsx and de-quote-pairing-3876.test.ts, with 0 errors. eslint . in the 3 packages exited 0 with 0 errors; no warning on an added line. Ablation at 50d6a6f used objectstack scripts/ablation-replace.mjs: the anchor hit as declared, the blob changed on disk, and each restore was proven by blob == HEAD and an empty git diff HEAD. Leg 1, save-bar marker removed: yieldsCorner 2 failed / 1 passed. Leg 2, both row-action markers removed (2 hits): 1 failed / 2 passed. Leg 3, setOccupied(hit) replaced by setOccupied(false): 2 failed / 1 passed (the positional control stays green by design). Leg 4, confirm bypassed (true || await confirmDelete): 7 failed / 28 passed. The browser before-state for the attachments corner was measured with leg 2 applied in wrap mode (restore proven): elementFromPoint at (1383, 847) returned 打开HotCRM助手. No dist ablation was needed, because the vitest src aliases resolve @object-ui/plugin-detail to src.",
    "mcp_calls": "0 (no MCP GitHub tool was called)",
    "api_writes": "2, both through the fleet-write relay (each is POST /repos/objectstack-ai/objectstack/dispatches, answered 204, executed as objectstack-fleet[bot]). (1) pr_create, run 38267289307: POST /repos/objectstack-ai/objectui/pulls (draft) and POST /repos//issues/12264/assignees [os-warren]; the read-back was 10799 bytes sent and 10799 stored, identical. (2) comment: POST /repos//issues/12248/comments (this report). Not REST: git push x3 (the empty-branch probe and 2 commits). No label write.",
    "gates": [
    "pnpm check:i18n-keys: exit 0 at 50d6a6f. Every in-scope call-site key resolves against the en pack, and every literal inline defaultValue matches the value the pack serves.",
    "pnpm check:i18n-drift: exit 0. No en value changed in this range.",
    "pnpm check:i18n-dead-keys: exit 0 (a report, not a gate).",
    "pnpm check:control-bytes: exit 0. check-control-bytes: OK.",
    "pnpm check:new-line-citations: exit 0. VERDICT new-cross-file-line-citations: 0 new citation(s).",
    "pnpm check:vi-mock-inherit: exit 0. OK.",
    "pnpm check:vi-mock-specifiers: exit 0. OK.",
    "pnpm check:vi-mock-override-shape: exit 0. OK.",
    "pnpm check:test-path-roots: exit 0. OK.",
    "pnpm check:changeset-claims: exit 0.",
    "pnpm check:pending-changeset-literals: exit 0. No test source names a pending changeset.",
    "node scripts/check-changeset-no-major.mjs: exit 0. No changeset declares a major bump.",
    "node scripts/check-changeset-presence.mjs: exit 0. 17 source file(s) of 3 released package(s) changed, and this change declares 1 changeset.",
    "pnpm --filter app-shell/plugin-detail/i18n run type-check: exit 0. os-verify-lock VERDICT command-exit 0 (at f8ad8a0).",
    "pnpm --filter app-shell/plugin-detail/i18n run lint: exit 0, 0 errors.",
    "NOT MEASURED: pnpm check:eager-locale-catalogues. Reason: it reads a built console bundle (apps/console/dist/eager-closure.json), so locally it exits 2 with PREREQUISITE NOT MET. Declared to CI.",
    "CI on PR 12264, read once at 50d6a6f: in_progress (32 check runs: 25 in progress, 4 success, 3 skipped). Not awaited."
    ],
    "line_budget": "n/a",
    "deviations": [
    "packages/i18n/src/tests/de-quote-pairing-3876.test.ts was edited. It is an i18n co-located test whose pinned German-pair counts move with any new „…“ value. It is covered by the claim's 'Co-located tests' line, though the claim named only locales/.ts under i18n.",
    "The browser measurement used a temporary untracked Vite entry (apps/console/fab-probe-12248.
    ) and Playwright drivers under node_modules. All were deleted before and after the final probe, and none was ever staged. The private vite server on :5248 was stopped by PID.",
    "Narrowed local test scope, declared: the full vitest farm is CI's.",
    "Build and type-check ran at f8ad8a0. The only later commit (50d6a6f) touches one i18n test file, which the tsc listFiles run at 50d6a6f covers.",
    "Conflict, stated rather than chosen silently: the harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. Commits carry objectui AGENTS.md's model-free trailer pair, and the PR body ends with os-dev.md's session-URL footer."
    ],
    "files_changed": [
    ".changeset/12248-fab-yields-attachment-confirm.md (app-shell patch, plugin-detail patch, i18n minor)",
    "packages/app-shell/src/layout/ConsoleChatbotFab.tsx",
    "packages/app-shell/src/layout/tests/ConsoleChatbotFab.yieldsCorner-12248.test.tsx (new)",
    "packages/app-shell/src/views/RecordAttachmentsPanel.tsx",
    "packages/app-shell/src/views/tests/RecordAttachmentsPanel.deleteConfirm-12248.test.tsx (new)",
    "packages/app-shell/src/views/tests/RecordAttachmentsPanel.test.tsx",
    "packages/plugin-detail/src/InlineEditSaveBar.tsx",
    "packages/i18n/src/locales/{en,zh,ja,ko,de,fr,es,pt,ru,ar}.ts (one key each: detail.deleteAttachmentConfirm)",
    "packages/i18n/src/tests/de-quote-pairing-3876.test.ts"
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none (承接者:无), noted in PR 12264 Acceptance notes, not filed. The console stylesheet's unlayered button:not([disabled]) rule sets transition: transform/filter, so it overrides every Tailwind transition-* utility on a button. Measured: the FAB's computed transition-property is 'transform, filter' whatever its class says. This is polish, outside classes a/b/c. Dedupe words: button transition override, index.css transition, transition utility inert.",
    "carrier: none (承接者:无), noted, not filed. The FAB yield is opt-in, and no other bottom-right control (a page ending in right-aligned buttons) was measured under the FAB. This is an inference, outside classes a/b/c."
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT: PR objectui#12264 (head 50d6a6f) · domain:ui seat 2 · session_01G5TSaEwbEQsKMjhzTB4rEd · 2026-10-12T15:32Z

    Reviewed against GitHub and the diff, not the report. Inputs: claim 6125835635 and report 6126936166.

    • Shape:
      • Draft on main. The first line is Fixes #12248, and the parent objectui#12211 is named bare.
      • Clause-②: yes, as the claim declared up front for the pack key.
      • The files are inside the claimed surface. One more is a co-located i18n pin: de-quote-pairing-3876's pinned count moves with the new German pair.
      • check-governed-merges --pr reads NOT governed.
    • The fix: read against the diff.
      • ConsoleChatbotFab goes invisible while an element marked data-fab-yield overlaps its own box. It re-measures once per frame on scroll, resize and node changes.
      • InlineEditSaveBar and the attachments panel's row actions carry the marker.
      • The attachment delete asks through the unchanged ActionConfirmDialog (destructive), the record page's own confirm. Cancel deletes nothing.
      • One pack key, detail.deleteAttachmentConfirm, is added to all ten packs. ⛔ No setting, prop, export or spec key.
    • Contract review: PASS 6127380179 on this head. Two non-blocking notes, both taken as Acceptance notes below.
    • Evidence:
      • A browser before/after at 1440×900, 1440×1400, 1280×720 and 1920×1080, in en and zh: elementFromPoint returns Save and Delete, not the assistant button. At 390×844 the button stays visible, because the bar sits below it.
      • 4 ablation legs, each red as pre-registered, restore proven.
      • CI on 50d6a6f reads 30 success and 3 skipped.
    • Acceptance notes:
      • @object-ui/app-shell and @object-ui/plugin-detail are scored patch for an additive change. The truthful word is minor, but the published version does not move, because all objectui packages are one fixed group (contract review ②). Left as is.
      • data-fab-yield is a thin published contract, read across two packages. It is stated in the changeset and the source comments; a README line would make it durable. Not filed: under the filing gate a missing doc line is not a card. carrier: the next card that touches InlineEditSaveBar's docs.
      • The console stylesheet's unlayered button:not([disabled]) transition rule overrides Tailwind transition-* utilities on buttons. Polish, outside the three classes. Acceptance notes, carrier: none.
      • The yield is opt-in. No other bottom-right control was measured under the button. An inference, not a finding.
    • Landing: ready first, then auto-merge once mergeable_state settles, through the merge queue.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 2 · session_01G5TSaEwbEQsKMjhzTB4rEd · 2026-10-12T15:47Z

    PR objectui#12264 merged through the merge queue as 51c661e on main. Verified by content on origin/main, not by sha:

    • ConsoleChatbotFab.tsx declares FAB_YIELD_SELECTOR and useCornerOccupied.
    • InlineEditSaveBar.tsx and RecordAttachmentsPanel.tsx carry data-fab-yield.
    • detail.deleteAttachmentConfirm is in all ten packs.
    • Control: objectui#12261's arrangeByDeclaredOptions is still on main.

    The card was closed by the PR's Fixes line, and pm:dispatched is removed in this same act. This completes item 2 of the parent objectui#12211.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:filesFiles — upload, download, signed URLs, access derived from the parent recordbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions