+
[]>(() => [
header: t("oncall.actions"),
sortable: false,
size: 96,
- meta: { align: "right" },
+ meta: { align: "center" },
},
]);
diff --git a/web/src/views/OnCall/OnCallResponses.spec.ts b/web/src/views/OnCall/OnCallResponses.spec.ts
index b23fc8ae5b..672306b546 100644
--- a/web/src/views/OnCall/OnCallResponses.spec.ts
+++ b/web/src/views/OnCall/OnCallResponses.spec.ts
@@ -833,6 +833,18 @@ describe("OnCallResponses", () => {
expect(cell.querySelectorAll('[aria-hidden="true"]').length).toBeGreaterThan(0);
});
+ /// A ⋯-only row reserves no empty slots, so its menu centres under the Actions header.
+ it("centres a resolved row's lone ⋯ with no empty slots beside it", async () => {
+ const resolved = await withPages([
+ page({ state: "resolved", closed_at: Date.now() * 1000, acked_by: "ana@o2.ai" }),
+ ]);
+ const cell = resolved
+ .find('[data-test="oncall-row-more-alert:al_ckt"]')
+ .element.closest(".justify-center")!;
+ expect(cell).not.toBeNull();
+ expect(cell.querySelectorAll(":scope > span.size-8[aria-hidden='true']").length).toBe(0);
+ });
+
/// Snoozing only makes sense while the ladder is still climbing, so a
/// handled row's menu must not offer it.
it("offers no snooze once nothing is escalating", async () => {
diff --git a/web/src/views/OnCall/OnCallResponses.vue b/web/src/views/OnCall/OnCallResponses.vue
index 92effa9fac..ff77bf073f 100644
--- a/web/src/views/OnCall/OnCallResponses.vue
+++ b/web/src/views/OnCall/OnCallResponses.vue
@@ -607,9 +607,9 @@ along with this program. If not, see .
-
+
-
+
@@ -654,7 +654,11 @@ along with this program. If not, see .
-
+
.
-
+