Skip to content

UI: Add-tenant panel can't be cancelled — no close (×) control, no Esc, no click-outside #545

Description

@smunini

Summary

On the Tenants page, opening Add tenant and typing something leaves you with no way to back out. The panel has a submit button and nothing else — no ×, no Cancel, no Esc, and clicking elsewhere on the page does nothing. Add a close control.

Repro

  1. Go to /ui/tenants.
  2. Click Add tenant.
  3. Type something into Tenant ID.
  4. Try to cancel. The only thing that works is clicking the Add tenant button again — a control labeled as the open action, so nobody looks there.

What's actually there

crates/ui/templates/pages/tenants.html:51-78 — the panel is a native <details class="addbox"> disclosure (chosen so it works without JavaScript). Its .addbox__actions block holds a single submit button. .addbox in crates/ui/assets/app.css:860-930 is position: absolute with no backdrop, so clicks outside the panel land on the page and do nothing.

<details> has no Esc behavior of its own, and no script adds one here.

The same panel pattern is used in two other places, with a different failure:
bulk-import.html:12 and bulk-import-detail.html:14 use <details class="addbox addbox--modal">. The --modal variant (app.css:931-960) stretches the <summary> across the viewport as a backdrop while open, so click-outside does close those. But there is still no × and no Esc, and an invisible backdrop is not a discoverable affordance. Whatever we do here should cover all three.

The pattern to copy

The app already solves this correctly one page over. The Resources edit modal has an explicit × — crates/ui/templates/pages/resources.html:133:

<button type="button" class="modal__x" data-modal-close aria-label="{{ i18n.t("action-cancel") }}">×</button>

— with Esc handled in crates/ui/assets/resources.js:53-54. The action-cancel Fluent key already exists (locales/en/main.ftl:66), so no new string is needed for the label.

Constraint worth knowing before starting

The whole reason these are <details> and not <dialog> is that they open without JavaScript (tenants.html:45-48 says so explicitly). A <details> cannot be closed from inside its own panel without script, so:

  • Suggested: add the × as a progressive enhancement — present in the markup, hidden by default, revealed by a small pinned asset that also wires Esc and sets details.open = false. With JS off, behavior is exactly what it is today, so nothing regresses.
  • Also give the plain .addbox a click-outside backdrop like --modal already has, so dismissal doesn't depend on JS at all.
  • Alternative: move to a native <dialog>, which gets Esc and <form method="dialog"> close buttons for free — but showModal() is JS-only, so no-JS opening would regress. Flagging the trade-off rather than picking it.

Also decide

Should the form reset when the panel closes? Today the typed values survive a close/reopen. Either behavior is defensible; pick one deliberately — "cancel" implying the input is discarded is the more common expectation.

Acceptance criteria

  • The Add-tenant panel has a visible close control that discards the panel.
  • Esc closes it.
  • Clicking outside closes it, on the plain .addbox as well as --modal.
  • Same treatment applied to the two bulk-import dialogs.
  • Nothing regresses with JavaScript disabled — cover it in crates/ui/e2e/tests/nojs/.
  • Close control is labeled for screen readers (reuse action-cancel) and reachable by keyboard; a11y.spec.ts passes with the panel open.
  • A recorded decision on whether closing resets the form.
  • e2e coverage for open → type → cancel on /ui/tenants (crates/ui/e2e/tests/tenants.spec.ts has no test for this today).

Pointers

  • crates/ui/templates/pages/tenants.html:51-78 — the reported panel
  • crates/ui/templates/pages/bulk-import.html:12, bulk-import-detail.html:14 — same pattern, --modal variant
  • crates/ui/assets/app.css:860-930 (.addbox), :931-960 (.addbox--modal backdrop trick), :927 (.addbox__actions)
  • crates/ui/templates/pages/resources.html:120-135 + crates/ui/assets/resources.js:53-54 — the × and Esc pattern to reuse
  • locales/en/main.ftl:66action-cancel

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingui

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions