diff --git a/tests/ui-testing/pages/oncallPages/oncallPagesListPage.js b/tests/ui-testing/pages/oncallPages/oncallPagesListPage.js index b53d14bd50..a3905ebd96 100644 --- a/tests/ui-testing/pages/oncallPages/oncallPagesListPage.js +++ b/tests/ui-testing/pages/oncallPages/oncallPagesListPage.js @@ -70,7 +70,6 @@ export class OnCallPagesListPage { error: '[data-test="oncall-responses-error"]', unavailable: '[data-test="oncall-responses-unavailable"]', truncated: '[data-test="oncall-responses-truncated"]', - escalationCapped: '[data-test="oncall-escalation-capped"]', responderNobody: '[data-test="oncall-responder-nobody"]', onCallNowGap: '[data-test="oncall-oncallnow-gap"]', diff --git a/web/src/components/oncall/OnCallAboutPage.vue b/web/src/components/oncall/OnCallAboutPage.vue index 26e26cd02f..d6b7eaf053 100644 --- a/web/src/components/oncall/OnCallAboutPage.vue +++ b/web/src/components/oncall/OnCallAboutPage.vue @@ -30,15 +30,15 @@ along with this program. If not, see . - + - - + + . {{ raw(note) }} diff --git a/web/src/components/oncall/OnCallMyDeliveries.spec.ts b/web/src/components/oncall/OnCallMyDeliveries.spec.ts index 80f2420724..fda73f9b86 100644 --- a/web/src/components/oncall/OnCallMyDeliveries.spec.ts +++ b/web/src/components/oncall/OnCallMyDeliveries.spec.ts @@ -117,6 +117,7 @@ describe("OnCallMyDeliveries", () => { vi.clearAllMocks(); queryClient.clear(); resetListViewState(); + window.localStorage.clear(); answer([]); service.markDeliveriesRead.mockResolvedValue({ data: { updated: 1, unread: 0 } } as any); service.acknowledgeResponse.mockResolvedValue({ data: {} } as any); @@ -275,6 +276,57 @@ describe("OnCallMyDeliveries", () => { await flushPromises(); expect(wrapper.find('[data-test="oncall-my-needs-you"]').exists()).toBe(false); }); + + const NEEDS_YOU_KEY = "oncall-my-needs-you:default:example@gmail.com"; + + /// The card holds its place through the first read when the last visit had open pages. + it("reserves its card while loading when the last visit had open pages", async () => { + window.localStorage.setItem(NEEDS_YOU_KEY, "flat"); + service.myDeliveries.mockReturnValue(new Promise(() => {})); + const wrapper = render(); + await flushPromises(); + + expect(wrapper.find('[data-test="oncall-my-needs-you"]').exists()).toBe(true); + expect( + wrapper.findAll('[data-test="oncall-my-needs-you-table"] [data-test="row"]'), + ).toHaveLength(0); + }); + + it("drops the reservation once a load has nothing open", async () => { + window.localStorage.setItem(NEEDS_YOU_KEY, "paged"); + answer([delivery({ response_state: "resolved" })]); + const wrapper = render(); + await flushPromises(); + + expect(wrapper.find('[data-test="oncall-my-needs-you"]').exists()).toBe(false); + expect(window.localStorage.getItem(NEEDS_YOU_KEY)).toBe(null); + }); + + it("remembers open pages for the next visit's skeleton", async () => { + answer([delivery({ response_state: "triggered" })]); + render(); + await flushPromises(); + expect(window.localStorage.getItem(NEEDS_YOU_KEY)).toBe("flat"); + }); + + /// A pinned column draws a divider; a table with nothing to scroll past keeps its actions unpinned. + it("does not pin the actions column", async () => { + answer([delivery({ response_state: "triggered" })]); + const { OTable: _table, ...realTable } = stubs; + const wrapper = mount(OnCallMyDeliveries, { + global: { plugins: [i18n, store], stubs: realTable }, + }); + await flushPromises(); + await new Promise((resolve) => setTimeout(resolve, 60)); + await flushPromises(); + + const card = wrapper.find('[data-test="oncall-my-needs-you"]'); + expect(card.find('[data-test="oncall-my-needs-you-ack-resp_1"]').exists()).toBe(true); + const sticky = card + .findAll("td, th") + .filter((cell) => (cell.attributes("style") ?? "").includes("sticky")); + expect(sticky).toHaveLength(0); + }); }); describe("the unread badge", () => { diff --git a/web/src/components/oncall/OnCallMyDeliveries.vue b/web/src/components/oncall/OnCallMyDeliveries.vue index 9e54907730..205f7a3008 100644 --- a/web/src/components/oncall/OnCallMyDeliveries.vue +++ b/web/src/components/oncall/OnCallMyDeliveries.vue @@ -29,8 +29,9 @@ along with this program. If not, see . /> -