fix: reset page on filter change and remove client-side filtering (#20043)

* fix: reset page on filter change

* remove unused filterFn
This commit is contained in:
Eunjae Lee
2025-03-13 15:25:10 +00:00
committed by GitHub
parent ef2c34c55f
commit 6c01f5eace
9 changed files with 22 additions and 136 deletions
@@ -1,12 +1,6 @@
"use client";
import {
useReactTable,
getCoreRowModel,
getFilteredRowModel,
getSortedRowModel,
createColumnHelper,
} from "@tanstack/react-table";
import { useReactTable, getCoreRowModel, getSortedRowModel, createColumnHelper } from "@tanstack/react-table";
import { useMemo, useRef } from "react";
import { WipeMyCalActionButton } from "@calcom/app-store/wipemycalother/components";
@@ -146,7 +140,6 @@ function BookingsContent({ status }: BookingsProps) {
enableColumnFilter: true,
enableSorting: false,
cell: () => null,
filterFn: () => true,
meta: {
filter: {
type: ColumnFilterType.MULTI_SELECT,
@@ -159,7 +152,6 @@ function BookingsContent({ status }: BookingsProps) {
enableColumnFilter: true,
enableSorting: false,
cell: () => null,
filterFn: () => true,
meta: {
filter: {
type: ColumnFilterType.MULTI_SELECT,
@@ -172,7 +164,6 @@ function BookingsContent({ status }: BookingsProps) {
enableColumnFilter: true,
enableSorting: false,
cell: () => null,
filterFn: () => true,
meta: {
filter: {
type: ColumnFilterType.MULTI_SELECT,
@@ -185,7 +176,6 @@ function BookingsContent({ status }: BookingsProps) {
enableColumnFilter: true,
enableSorting: false,
cell: () => null,
filterFn: () => true,
meta: {
filter: {
type: ColumnFilterType.TEXT,
@@ -198,7 +188,6 @@ function BookingsContent({ status }: BookingsProps) {
enableColumnFilter: true,
enableSorting: false,
cell: () => null,
filterFn: () => true,
meta: {
filter: {
type: ColumnFilterType.TEXT,
@@ -211,7 +200,6 @@ function BookingsContent({ status }: BookingsProps) {
enableColumnFilter: true,
enableSorting: false,
cell: () => null,
filterFn: () => true,
meta: {
filter: {
type: ColumnFilterType.DATE_RANGE,
@@ -346,7 +334,6 @@ function BookingsContent({ status }: BookingsProps) {
},
},
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getSortedRowModel: getSortedRowModel(),
getFacetedUniqueValues,
});
@@ -20,7 +20,7 @@ export function DataTablePagination<TData>({
const { pageIndex, pageSize, setPageIndex, setPageSize } = useDataTable();
if (paginationMode === "infinite") {
const loadedCount = table.getFilteredRowModel().rows.length;
const loadedCount = table.getRowModel().rows.length;
return (
<p className="text-subtle text-sm tabular-nums">
Loaded <span className="text-default font-medium">{loadedCount}</span> of{" "}
@@ -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, useCallback } from "react";
import { forwardRef } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import {
@@ -39,19 +39,10 @@ function AddFilterButtonComponent<TData>(
ref: React.Ref<HTMLButtonElement>
) {
const { t } = useLocale();
const { activeFilters, setActiveFilters } = useDataTable();
const { activeFilters, addFilter } = useDataTable();
const filterableColumns = useFilterableColumns(table);
const handleAddFilter = useCallback(
(columnId: string) => {
if (!activeFilters?.some((filter) => filter.f === columnId)) {
setActiveFilters([...activeFilters, { f: columnId, v: undefined }]);
}
},
[activeFilters, setActiveFilters]
);
if (hideWhenFilterApplied && activeFilters?.length > 0) {
return null;
}
@@ -99,7 +90,7 @@ function AddFilterButtonComponent<TData>(
return (
<CommandItem
key={column.id}
onSelect={() => handleAddFilter(column.id)}
onSelect={() => addFilter(column.id)}
className="flex items-center justify-between px-4 py-2"
data-testid={`add-filter-item-${column.id}`}>
<span>{startCase(column.title)}</span>
+14 -2
View File
@@ -16,8 +16,8 @@ type ActiveFilter = z.infer<typeof ZActiveFilter>;
export type DataTableContextType = {
activeFilters: ActiveFilter[];
setActiveFilters: (filters: ActiveFilter[]) => void;
clearAll: (exclude?: string[]) => void;
addFilter: (columnId: string) => void;
updateFilter: (columnId: string, value: FilterValue) => void;
removeFilter: (columnId: string) => void;
@@ -65,8 +65,18 @@ export function DataTableProvider({ children, defaultPageSize = DEFAULT_PAGE_SIZ
const [pageIndex, setPageIndex] = useQueryState("page", parseAsInteger.withDefault(0));
const [pageSize, setPageSize] = useQueryState("size", parseAsInteger.withDefault(defaultPageSize));
const addFilter = useCallback(
(columnId: string) => {
if (!activeFilters?.some((filter) => filter.f === columnId)) {
setActiveFilters([...activeFilters, { f: columnId, v: undefined }]);
}
},
[activeFilters, setActiveFilters]
);
const clearAll = useCallback(
(exclude?: string[]) => {
setPageIndex(0);
setActiveFilters((prev) => prev.filter((filter) => exclude?.includes(filter.f)));
},
[setActiveFilters]
@@ -74,6 +84,7 @@ export function DataTableProvider({ children, defaultPageSize = DEFAULT_PAGE_SIZ
const updateFilter = useCallback(
(columnId: string, value: FilterValue) => {
setPageIndex(0);
setActiveFilters((prev) => {
let added = false;
const newFilters = prev.map((item) => {
@@ -94,6 +105,7 @@ export function DataTableProvider({ children, defaultPageSize = DEFAULT_PAGE_SIZ
const removeFilter = useCallback(
(columnId: string) => {
setPageIndex(0);
setActiveFilters((prev) => prev.filter((filter) => filter.f !== columnId));
},
[setActiveFilters]
@@ -111,7 +123,7 @@ export function DataTableProvider({ children, defaultPageSize = DEFAULT_PAGE_SIZ
<DataTableContext.Provider
value={{
activeFilters,
setActiveFilters,
addFilter,
clearAll,
updateFilter,
removeFilter,
@@ -1,11 +1,6 @@
"use client";
import {
useReactTable,
getCoreRowModel,
getFilteredRowModel,
getSortedRowModel,
} from "@tanstack/react-table";
import { useReactTable, getCoreRowModel, getSortedRowModel } from "@tanstack/react-table";
// eslint-disable-next-line no-restricted-imports
import { useMemo, useEffect } from "react";
@@ -81,7 +76,6 @@ export function RoutingFormResponsesTable() {
data: processedData,
columns,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getSortedRowModel: getSortedRowModel(),
defaultColumn: {
size: 150,
@@ -1,10 +1,4 @@
import {
createColumnHelper,
useReactTable,
getCoreRowModel,
getFilteredRowModel,
getSortedRowModel,
} from "@tanstack/react-table";
import { createColumnHelper, useReactTable, getCoreRowModel, getSortedRowModel } from "@tanstack/react-table";
import { useMemo } from "react";
import { ColumnFilterType } from "@calcom/features/data-table";
@@ -68,7 +62,6 @@ export const useInsightsBookings = () => {
data: emptyData,
columns,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getSortedRowModel: getSortedRowModel(),
getFacetedUniqueValues: getInsightsFacetedUniqueValues,
});
@@ -5,7 +5,7 @@ import { useMemo } from "react";
import { z } from "zod";
import dayjs from "@calcom/dayjs";
import { dataTableFilter, ColumnFilterType } from "@calcom/features/data-table";
import { ColumnFilterType } from "@calcom/features/data-table";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { useCopy } from "@calcom/lib/hooks/useCopy";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -49,10 +49,6 @@ export const useInsightsColumns = ({
filter: { type: ColumnFilterType.SINGLE_SELECT },
},
cell: () => null,
filterFn: (row, id, filterValue) => {
const cellValue = row.original.formId;
return dataTableFilter(cellValue, filterValue);
},
}),
columnHelper.accessor("bookingUserId", {
id: "bookingUserId",
@@ -65,10 +61,6 @@ export const useInsightsColumns = ({
},
},
cell: () => null,
filterFn: (row, id, filterValue) => {
const cellValue = row.original.bookingUserId;
return dataTableFilter(cellValue, filterValue);
},
}),
columnHelper.accessor("bookingUid", {
id: "bookingUid",
@@ -169,10 +161,6 @@ export const useInsightsColumns = ({
meta: {
filter: { type: filterType },
},
filterFn: (row, id, filterValue) => {
const cellValue = row.original.response[id]?.value;
return dataTableFilter(cellValue, filterValue);
},
});
}) ?? []),
columnHelper.accessor("bookingStatusOrder", {
@@ -187,15 +175,6 @@ export const useInsightsColumns = ({
meta: {
filter: { type: ColumnFilterType.MULTI_SELECT, icon: "circle" },
},
filterFn: (row, id, filterValue) => {
const cellValue = row.original.bookingStatusOrder;
return dataTableFilter(cellValue, filterValue);
},
sortingFn: (rowA, rowB) => {
const statusA = rowA.original.bookingStatusOrder ?? 6; // put it at the end if bookingStatusOrder is null
const statusB = rowB.original.bookingStatusOrder ?? 6;
return statusA - statusB;
},
}),
columnHelper.accessor("bookingCreatedAt", {
id: "bookingCreatedAt",
@@ -206,16 +185,6 @@ export const useInsightsColumns = ({
<BookingAtCell row={info.row.original} rowId={info.row.original.id} />
</div>
),
sortingFn: (rowA, rowB) => {
const dateA = rowA.original.bookingCreatedAt;
const dateB = rowB.original.bookingCreatedAt;
if (!dateA && !dateB) return 0;
if (!dateA) return -1;
if (!dateB) return 1;
if (!(dateA instanceof Date) || !(dateB instanceof Date)) return 0;
return dateA.getTime() - dateB.getTime();
},
}),
columnHelper.accessor("bookingAssignmentReason", {
id: "bookingAssignmentReason",
@@ -229,10 +198,6 @@ export const useInsightsColumns = ({
const assignmentReason = info.getValue();
return <div className="max-w-[250px]">{assignmentReason}</div>;
},
filterFn: (row, id, filterValue) => {
const reason = row.original.bookingAssignmentReason;
return dataTableFilter(reason, filterValue);
},
}),
columnHelper.accessor("createdAt", {
id: "createdAt",
@@ -245,10 +210,6 @@ export const useInsightsColumns = ({
<Badge variant="gray">{dayjs(info.getValue()).format("MMM D, YYYY HH:mm")}</Badge>
</div>
),
filterFn: (row, id, filterValue) => {
const createdAt = row.original.createdAt;
return dataTableFilter(createdAt, filterValue);
},
}),
];
}, [isHeadersSuccess, headers]);
@@ -155,10 +155,6 @@ function UserListTableContent({ oAuthClientId }: PlatformManagedUsersTableProps)
</div>
);
},
filterFn: (rows, id, filterValue) => {
const userEmail = rows.original.email;
return filterValue.includes(userEmail);
},
},
{
id: "role",
@@ -181,15 +177,6 @@ function UserListTableContent({ oAuthClientId }: PlatformManagedUsersTableProps)
</Badge>
);
},
filterFn: (rows, id, filterValue) => {
if (filterValue.includes("PENDING")) {
if (filterValue.length === 1) return !rows.original.accepted;
else return !rows.original.accepted || filterValue.includes(rows.getValue(id));
}
// Show only the selected roles
return filterValue.includes(rows.getValue(id));
},
},
{
id: "teams",
@@ -230,10 +217,6 @@ function UserListTableContent({ oAuthClientId }: PlatformManagedUsersTableProps)
</div>
);
},
filterFn: (rows, _, filterValue: string[]) => {
const teamNames = rows.original.teams.map((team) => team.name);
return filterValue.some((value: string) => teamNames.includes(value));
},
},
];
return cols;
@@ -13,12 +13,6 @@ import {
DataTableSelectionBar,
DataTableFilters,
useColumnFilters,
textFilter,
isTextFilterValue,
isSingleSelectFilterValue,
isMultiSelectFilterValue,
singleSelectFilter,
multiSelectFilter,
ColumnFilterType,
convertFacetedValuesToMap,
useDataTable,
@@ -237,18 +231,6 @@ function UserListTableContent() {
</div>
);
},
filterFn: (row, id, filterValue) => {
const attributeValues = row.original.attributes?.filter((attr) => attr.attributeId === id);
if (isTextFilterValue(filterValue)) {
return attributeValues?.some((attr) => textFilter(attr.value, filterValue)) ?? false;
} else if (isSingleSelectFilterValue(filterValue)) {
return singleSelectFilter(attributeValues?.map((attr) => attr.value) ?? [], filterValue);
} else if (isMultiSelectFilterValue(filterValue)) {
return multiSelectFilter(attributeValues?.map((attr) => attr.value) ?? [], filterValue);
}
return false;
},
};
}) ?? [];
return attributeColumns;
@@ -312,10 +294,6 @@ function UserListTableContent() {
</div>
);
},
filterFn: (rows, id, filterValue) => {
const userEmail = rows.original.email;
return filterValue.includes(userEmail);
},
},
{
id: "role",
@@ -335,15 +313,6 @@ function UserListTableContent() {
</Badge>
);
},
filterFn: (rows, id, filterValue) => {
if (filterValue.includes("PENDING")) {
if (filterValue.length === 1) return !rows.original.accepted;
else return !rows.original.accepted || filterValue.includes(rows.getValue(id));
}
// Show only the selected roles
return filterValue.includes(rows.getValue(id));
},
},
{
id: "teams",
@@ -381,10 +350,6 @@ function UserListTableContent() {
</div>
);
},
filterFn: (rows, _, filterValue: string[]) => {
const teamNames = rows.original.teams.map((team) => team.name);
return filterValue.some((value: string) => teamNames.includes(value));
},
},
...generateAttributeColumns(),
{