Task #491: center quick-actions surface + frame the selected row

The user reported that the small quick-actions popover (which holds
the Postpone trigger) was hard to find — it floated next to the
clicked row and they sometimes lost track of which meeting they
were about to act on. They asked for the surface to appear in the
center of the screen, and for the row they clicked to be clearly
framed in a color while the surface is open.

Changes:
- Replaced the row's row-anchored Popover (PopoverAnchor +
  PopoverContent) with a centered Dialog (DialogContent) that
  Radix renders into a portal. The Dialog uses the existing
  `executiveMeetings.quickActions.label` translation key for its
  title (already present in both Arabic and English) and reuses
  #490's polished Postpone Button unchanged. Test ID stays
  `em-row-quick-${id}` so existing e2e specs continue to target
  the same surface.
- Added a third inset-shadow ring (`inset 0 0 0 3px
  ${highlightColor}`) to the row's composed boxShadow stack while
  the row's quickOpen state is true. Listed first in the stack so
  it becomes the outermost frame and wins visually over the
  existing current-meeting / bulk-select rings. Uses the
  page-level highlightPrefs.color so the frame matches the user's
  chosen accent. Also exposes `data-quick-open="true"` on the
  <tr> for tests.
- Updated the row-quick-actions e2e: the postpone-end-to-end test
  now asserts `role="dialog"` on the surface and the row carries
  `data-quick-open` while open and loses it after Postpone is
  clicked. Added a separate test for Escape closing the surface
  and clearing the row frame.

Verified: 5/5 quick-actions tests pass, plus both drag specs
(row-drag + iPad touch-reorder) still pass.
This commit is contained in:
riyadhafraa
2026-05-11 13:25:21 +00:00
parent f1c9ef71b7
commit c7942a221f
@@ -193,6 +193,24 @@ test("Escape closes the centered surface AND clears the selected-row frame", asy
await page.keyboard.press("Escape");
await expect(surface).toBeHidden();
await expect(row).not.toHaveAttribute("data-quick-open", "true");
// Re-open and verify outside-click (on the modal overlay) also
// dismisses the surface and clears the row frame — the second
// expected close path for a centered Dialog.
await row.click();
await expect(surface).toBeVisible();
await expect(row).toHaveAttribute("data-quick-open", "true");
// Radix renders an overlay above the page that intercepts pointer
// events for outside-dismiss. Click near a corner so we don't land
// on the centered DialogContent.
const overlay = page.locator('[data-radix-dialog-overlay], [data-state="open"][class*="fixed inset-0"]').first();
if (await overlay.count()) {
await overlay.click({ position: { x: 5, y: 5 }, force: true });
} else {
await page.mouse.click(5, 5);
}
await expect(surface).toBeHidden();
await expect(row).not.toHaveAttribute("data-quick-open", "true");
});
test("popover only exposes Postpone — Move up/down buttons retired in #489", async ({