From c7e66a3aa9c5a52b5e906fb60b945364f6931465 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Thu, 12 Feb 2026 06:09:08 +0100 Subject: [PATCH] fix: maintain uid parameter in BookingDetailsSheet URL (#27872) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: maintain uid parameter in BookingDetailsSheet URL Move the isSyncedFromUrlToStoreRef guard from the effect level to inside the Zustand subscription callback. This ensures the Store→URL subscription is always created while still preventing premature URL overwrites during URL→Store sync. Also adds an E2E test verifying the uid parameter appears in the URL after clicking a booking item in the v3 bookings view. Co-Authored-By: eunjae@cal.com * Update apps/web/playwright/bookings-list.e2e.ts Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> * fix: clean up bookings-v3 feature flag after E2E test Co-Authored-By: eunjae@cal.com --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --- .../store/bookingDetailsSheetStore.tsx | 5 +- apps/web/playwright/bookings-list.e2e.ts | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/apps/web/modules/bookings/store/bookingDetailsSheetStore.tsx b/apps/web/modules/bookings/store/bookingDetailsSheetStore.tsx index 7f4e45f6e8..3bc88f27d3 100644 --- a/apps/web/modules/bookings/store/bookingDetailsSheetStore.tsx +++ b/apps/web/modules/bookings/store/bookingDetailsSheetStore.tsx @@ -185,11 +185,8 @@ function useBiDirectionalSyncBetweenStoreAndUrl({ store }: { store: BookingDetai // Sync Store → URL useEffect(() => { - // We can't sync from Store to URL if URL hasn't first been synced to Store - // This is to prevent override of any user configuration provided by URL query params. Think about page being refreshed - if (!isSyncedFromUrlToStoreRef.current) return; - const unsubscribe = store.subscribe((state) => { + if (!isSyncedFromUrlToStoreRef.current) return; if (state.selectedBookingUid !== selectedBookingUidFromUrl) { setSelectedBookingUidToUrl(state.selectedBookingUid); } diff --git a/apps/web/playwright/bookings-list.e2e.ts b/apps/web/playwright/bookings-list.e2e.ts index 94690f731c..a3b37cb7c5 100644 --- a/apps/web/playwright/bookings-list.e2e.ts +++ b/apps/web/playwright/bookings-list.e2e.ts @@ -763,6 +763,56 @@ test.describe("Bookings", () => { .toBe(1); }); }); + + test("clicking a booking item adds uid param to URL when bookings-v3 is enabled", async ({ + page, + users, + bookings, + prisma, + }) => { + const existingFlag = await prisma.feature.findUnique({ where: { slug: "bookings-v3" } }); + await prisma.feature.upsert({ + where: { slug: "bookings-v3" }, + update: { enabled: true }, + create: { slug: "bookings-v3", enabled: true, type: "OPERATIONAL" }, + }); + + try { + const user = await users.create(); + + const bookingFixture = await createBooking({ + title: "Test booking for uid param", + bookingsFixture: bookings, + relativeDate: 3, + organizer: user, + organizerEventType: user.eventTypes[0], + attendees: [{ name: "Attendee", email: "attendee@example.com", timeZone: "Europe/Berlin" }], + }); + + await user.apiLogin(); + const bookingsGetResponse = page.waitForResponse((response) => + /\/api\/trpc\/bookings\/get.*/.test(response.url()) + ); + await page.goto("/bookings/upcoming", { waitUntil: "domcontentloaded" }); + await bookingsGetResponse; + + const bookingItem = page.locator(`[data-booking-uid="${bookingFixture.uid}"]`); + await expect(bookingItem).toBeVisible(); + + await bookingItem.locator('[role="button"]').first().click(); + + await expect(page).toHaveURL(new RegExp(`[?&]uid=${bookingFixture.uid}(&|$)`)); + } finally { + if (existingFlag) { + await prisma.feature.update({ + where: { slug: "bookings-v3" }, + data: { enabled: existingFlag.enabled }, + }); + } else { + await prisma.feature.deleteMany({ where: { slug: "bookings-v3" } }); + } + } + }); }); async function createBooking({