From 4cd8dbbab413b2213b604f61df056fbaec0a1a2c Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Wed, 2 Apr 2025 10:36:42 +0200 Subject: [PATCH] feat: support Filter Segment in other pages (#20461) * feat: support Filter Segment in other pages * minor changes to the behaviors * remove comment * fix type error * fix e2e test --- .../(use-page-wrapper)/insights/layout.tsx | 7 ++++- .../bookings/views/bookings-listing-view.tsx | 11 +++++--- apps/web/playwright/out-of-office.e2e.ts | 2 -- .../features/data-table/DataTableProvider.tsx | 6 +++-- .../components/filters/AddFilterButton.tsx | 20 ++++++++++---- .../components/filters/FilterBar.tsx | 18 +++++++++++++ .../data-table/components/filters/index.ts | 2 ++ .../features/data-table/components/index.ts | 3 +-- .../data-table/components/segment/index.ts | 7 +++++ .../components/RoutingFormResponsesTable.tsx | 27 ++++++++++++------- .../outOfOffice/OutOfOfficeEntriesList.tsx | 12 ++++++--- .../UserTable/PlatformManagedUsersTable.tsx | 24 +++++++++-------- .../components/UserTable/UserListTable.tsx | 16 +++++------ 13 files changed, 107 insertions(+), 48 deletions(-) create mode 100644 packages/features/data-table/components/filters/FilterBar.tsx create mode 100644 packages/features/data-table/components/segment/index.ts diff --git a/apps/web/app/(use-page-wrapper)/insights/layout.tsx b/apps/web/app/(use-page-wrapper)/insights/layout.tsx index c20180c2ff..ccf32c60fe 100644 --- a/apps/web/app/(use-page-wrapper)/insights/layout.tsx +++ b/apps/web/app/(use-page-wrapper)/insights/layout.tsx @@ -1,5 +1,6 @@ import { getTranslate } from "app/_utils"; +import { CTA_CONTAINER_CLASS_NAME } from "@calcom/features/data-table/lib/utils"; import Shell from "@calcom/features/shell/Shell"; import UpgradeTipWrapper from "./UpgradeTipWrapper"; @@ -8,7 +9,11 @@ export default async function InsightsLayout({ children }: { children: React.Rea const t = await getTranslate(); return (
- + }> {children}
diff --git a/apps/web/modules/bookings/views/bookings-listing-view.tsx b/apps/web/modules/bookings/views/bookings-listing-view.tsx index f5992b5cb4..08e521660d 100644 --- a/apps/web/modules/bookings/views/bookings-listing-view.tsx +++ b/apps/web/modules/bookings/views/bookings-listing-view.tsx @@ -10,6 +10,7 @@ import { DataTableProvider, DataTableWrapper, DataTableFilters, + DataTableSegment, ColumnFilterType, useFilterValue, ZMultiSelectFilterValue, @@ -374,10 +375,14 @@ function BookingsContent({ status }: BookingsProps) { paginationMode="standard" ToolbarLeft={ <> - - - + + + } + ToolbarRight={ + <> + + } LoaderView={} diff --git a/apps/web/playwright/out-of-office.e2e.ts b/apps/web/playwright/out-of-office.e2e.ts index 1e6cc250d3..e984c968ac 100644 --- a/apps/web/playwright/out-of-office.e2e.ts +++ b/apps/web/playwright/out-of-office.e2e.ts @@ -676,7 +676,6 @@ test.describe("Out of office", () => { ); await page.locator('[data-testid="add-filter-button"]').click(); await page.locator('[data-testid="add-filter-item-dateRange"]').click(); - await page.locator('[data-testid="add-filter-button"]').click(); await page.locator('[data-testid="filter-popover-trigger-dateRange"]').click(); await expect(page.locator('[data-testid="date-range-options-tdy"]')).toBeVisible(); //Today @@ -777,7 +776,6 @@ test.describe("Out of office", () => { ); await page.locator('[data-testid="add-filter-item-dateRange"]').click(); await entriesListRespPromise; - await page.locator('[data-testid="add-filter-button"]').click(); //close popover //1 OOO record should be visible for member3, end=currentDate-4days expect(await page.locator('[data-testid^="table-redirect-"]').count()).toBe(1); diff --git a/packages/features/data-table/DataTableProvider.tsx b/packages/features/data-table/DataTableProvider.tsx index df6bcd7fc6..3eb5cdba7f 100644 --- a/packages/features/data-table/DataTableProvider.tsx +++ b/packages/features/data-table/DataTableProvider.tsx @@ -15,10 +15,11 @@ import { type FilterSegmentOutput, type ActiveFilters, } from "./lib/types"; +import { CTA_CONTAINER_CLASS_NAME } from "./lib/utils"; export type DataTableContextType = { tableIdentifier: string; - ctaContainerRef?: React.RefObject; + ctaContainerRef: React.RefObject; activeFilters: ActiveFilters; clearAll: (exclude?: string[]) => void; @@ -69,7 +70,7 @@ export function DataTableProvider({ tableIdentifier: _tableIdentifier, children, defaultPageSize = DEFAULT_PAGE_SIZE, - ctaContainerClassName, + ctaContainerClassName = CTA_CONTAINER_CLASS_NAME, }: DataTableProviderProps) { const [activeFilters, setActiveFilters] = useQueryState( "activeFilters", @@ -110,6 +111,7 @@ export function DataTableProvider({ const clearAll = useCallback( (exclude?: string[]) => { + setSegmentIdAndSaveToLocalStorage(null); setPageIndex(null); setActiveFilters((prev) => { const remainingFilters = prev.filter((filter) => exclude?.includes(filter.f)); diff --git a/packages/features/data-table/components/filters/AddFilterButton.tsx b/packages/features/data-table/components/filters/AddFilterButton.tsx index d45c34c2fb..e39fcccbba 100644 --- a/packages/features/data-table/components/filters/AddFilterButton.tsx +++ b/packages/features/data-table/components/filters/AddFilterButton.tsx @@ -3,7 +3,7 @@ import { type Table } from "@tanstack/react-table"; // eslint-disable-next-line no-restricted-imports import startCase from "lodash/startCase"; -import { forwardRef } from "react"; +import { forwardRef, useState } from "react"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { Button } from "@calcom/ui/components/button"; @@ -32,8 +32,12 @@ function AddFilterButtonComponent( ) { const { t } = useLocale(); const { activeFilters, addFilter } = useDataTable(); + const [open, setOpen] = useState(false); const filterableColumns = useFilterableColumns(table); + const availableColumns = filterableColumns.filter( + (column) => !activeFilters?.some((filter) => filter.f === column.id) + ); if (hideWhenFilterApplied && activeFilters?.length > 0) { return null; @@ -43,9 +47,13 @@ function AddFilterButtonComponent( return null; } + if (variant === "sm" && availableColumns.length === 0) { + return null; + } + return (
- + {variant === "base" && (
+ + {ctaContainerRef.current && + createPortal( + <> + + + , + ctaContainerRef.current + )} ); } diff --git a/packages/features/settings/outOfOffice/OutOfOfficeEntriesList.tsx b/packages/features/settings/outOfOffice/OutOfOfficeEntriesList.tsx index 261becf825..215f8a08e1 100644 --- a/packages/features/settings/outOfOffice/OutOfOfficeEntriesList.tsx +++ b/packages/features/settings/outOfOffice/OutOfOfficeEntriesList.tsx @@ -19,6 +19,7 @@ import { useFilterValue, ZDateRangeFilterValue, DataTableFilters, + DataTableSegment, } from "@calcom/features/data-table"; import ServerTrans from "@calcom/lib/components/ServerTrans"; import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; @@ -345,12 +346,17 @@ function OutOfOfficeEntriesListContent() { totalRowCount={totalRowCount} tableContainerRef={tableContainerRef} paginationMode="infinite" - ToolbarLeft={ setSearchTerm(value)} />} + ToolbarLeft={ + <> + setSearchTerm(value)} /> + + + } ToolbarRight={ <> - - + + } EmptyView={ diff --git a/packages/features/users/components/UserTable/PlatformManagedUsersTable.tsx b/packages/features/users/components/UserTable/PlatformManagedUsersTable.tsx index 149d3c2ae3..4dbda93382 100644 --- a/packages/features/users/components/UserTable/PlatformManagedUsersTable.tsx +++ b/packages/features/users/components/UserTable/PlatformManagedUsersTable.tsx @@ -10,6 +10,7 @@ import { DataTableToolbar, DataTableSelectionBar, DataTableFilters, + DataTableSegment, useColumnFilters, useDataTable, } from "@calcom/features/data-table"; @@ -287,22 +288,23 @@ function UserListTableContent({ oAuthClientId }: PlatformManagedUsersTableProps) totalRowCount={data?.meta?.totalRowCount} paginationMode="standard" ToolbarLeft={ - setDebouncedSearchTerm(value)} - className="sm:max-w-64 max-w-full" - /> + <> + setDebouncedSearchTerm(value)} + className="sm:max-w-64 max-w-full" + /> + + + } ToolbarRight={ <> - - + + + }> -
- -
- {numberOfSelectedRows > 0 && (

diff --git a/packages/features/users/components/UserTable/UserListTable.tsx b/packages/features/users/components/UserTable/UserListTable.tsx index f88f4e6954..8225f47591 100644 --- a/packages/features/users/components/UserTable/UserListTable.tsx +++ b/packages/features/users/components/UserTable/UserListTable.tsx @@ -13,13 +13,11 @@ import { DataTableToolbar, DataTableSelectionBar, DataTableFilters, + DataTableSegment, useColumnFilters, ColumnFilterType, convertFacetedValuesToMap, - SaveFilterSegmentButton, - FilterSegmentSelect, useDataTable, - CTA_CONTAINER_CLASS_NAME, } from "@calcom/features/data-table"; import { useOrgBranding } from "@calcom/features/ee/organizations/context/provider"; import { WEBAPP_URL } from "@calcom/lib/constants"; @@ -105,7 +103,7 @@ function reducer(state: UserTableState, action: UserTableAction): UserTableState export function UserListTable() { return ( - + ); @@ -535,16 +533,14 @@ function UserListTableContent() { <> setDebouncedSearchTerm(value)} /> - - - + } ToolbarRight={ <> - - + + }> {numberOfSelectedRows >= 2 && dynamicLinkVisible && ( @@ -586,7 +582,7 @@ function UserListTableContent() { {state.changeMemberRole.showModal && } {state.editSheet.showModal && } - {ctaContainerRef?.current && + {ctaContainerRef.current && createPortal(