From 1ab4b9dfab81a5ea05278951ea5ed19b3fe92d55 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 26 Nov 2025 18:05:55 +0100 Subject: [PATCH] chore: Fix circular dependency in tanstack-table.d.ts (#25411) * chore: Fix circular dependency in tanstack-table.d.ts * fix: Re-export TextFilterOperator * Unable to export non-type values from @calcom/types * Refactor data-table types in a way that ensures type-safety as before * Add FilterPopover and further fixups * Fix further type errors missed earlier * More hidden type errors * Type error in useFilterValue --- apps/web/modules/insights/insights-view.tsx | 5 +- .../filters/BaseSelectFilterOptions.tsx | 12 +-- .../components/filters/DateRangeFilter.tsx | 3 +- .../components/filters/FilterPopover.tsx | 9 +- .../filters/MultiSelectFilterOptions.tsx | 5 +- .../filters/NumberFilterOptions.tsx | 3 +- .../filters/SingleSelectFilterOptions.tsx | 6 +- .../components/filters/TextFilterOptions.tsx | 3 +- .../data-table/hooks/useFilterValue.ts | 5 +- packages/features/data-table/lib/types.ts | 99 ++++++------------- .../routing/RoutingFormResponsesTable.tsx | 3 +- .../features/insights/lib/bookingUtils.ts | 3 +- .../services/InsightsRoutingBaseService.ts | 6 +- .../organizations/listMembers.handler.test.ts | 14 +-- .../organizations/listMembers.handler.ts | 13 ++- packages/types/data-table.d.ts | 57 +++++++++++ packages/types/tanstack-table.d.ts | 4 +- 17 files changed, 140 insertions(+), 110 deletions(-) create mode 100644 packages/types/data-table.d.ts diff --git a/apps/web/modules/insights/insights-view.tsx b/apps/web/modules/insights/insights-view.tsx index cab0603825..250b9c929c 100644 --- a/apps/web/modules/insights/insights-view.tsx +++ b/apps/web/modules/insights/insights-view.tsx @@ -10,6 +10,7 @@ import { ColumnFilterType, type FilterableColumn, } from "@calcom/features/data-table"; +import type { FilterType } from "@calcom/types/data-table"; import { useDataTable } from "@calcom/features/data-table/hooks/useDataTable"; import { useSegments } from "@calcom/features/data-table/hooks/useSegments"; import { @@ -53,13 +54,13 @@ export default function InsightsPage({ timeZone }: { timeZone: string }) { ); } -const createdAtColumn: Extract = { +const createdAtColumn: Extract }> = { id: "createdAt", title: "createdAt", type: ColumnFilterType.DATE_RANGE, }; -const startTimeColumn: Extract = { +const startTimeColumn: Extract }> = { id: "startTime", title: "startTime", type: ColumnFilterType.DATE_RANGE, diff --git a/packages/features/data-table/components/filters/BaseSelectFilterOptions.tsx b/packages/features/data-table/components/filters/BaseSelectFilterOptions.tsx index 776350f748..6383cdd33a 100644 --- a/packages/features/data-table/components/filters/BaseSelectFilterOptions.tsx +++ b/packages/features/data-table/components/filters/BaseSelectFilterOptions.tsx @@ -18,26 +18,26 @@ import { Icon } from "@calcom/ui/components/icon"; import { useDataTable, useFilterValue } from "../../hooks"; import type { - ColumnFilterType, FacetedValue, FilterableColumn as _FilterableColumn, FilterValueSchema, } from "../../lib/types"; +import type { FilterType } from "@calcom/types/data-table"; type FilterableColumn = Extract< _FilterableColumn, - { type: ColumnFilterType.MULTI_SELECT | ColumnFilterType.SINGLE_SELECT } + { type: Extract } >; -type FilterableSelectColumn = +type FilterableSelectColumn> = Extract; -type FilterValue = ReturnType< +type FilterValue> = ReturnType< typeof useFilterValue> >; export type BaseSelectFilterOptionsProps< - T extends ColumnFilterType.MULTI_SELECT | ColumnFilterType.SINGLE_SELECT + T extends Extract > = { column: FilterableSelectColumn; filterValueSchema: FilterValueSchema; @@ -88,7 +88,7 @@ function getSectionedOptions(options: FacetedValue[]) { } export function BaseSelectFilterOptions< - T extends ColumnFilterType.MULTI_SELECT | ColumnFilterType.SINGLE_SELECT + T extends Extract >({ column, filterValueSchema, diff --git a/packages/features/data-table/components/filters/DateRangeFilter.tsx b/packages/features/data-table/components/filters/DateRangeFilter.tsx index aa0c6b8d29..b4378e7246 100644 --- a/packages/features/data-table/components/filters/DateRangeFilter.tsx +++ b/packages/features/data-table/components/filters/DateRangeFilter.tsx @@ -33,10 +33,11 @@ import { import { preserveLocalTime } from "../../lib/preserveLocalTime"; import type { FilterableColumn, DateRangeFilterOptions } from "../../lib/types"; import { ZDateRangeFilterValue, ColumnFilterType } from "../../lib/types"; +import type { FilterType } from "@calcom/types/data-table"; import { useFilterPopoverOpen } from "./useFilterPopoverOpen"; type DateRangeFilterProps = { - column: Extract; + column: Extract }>; options?: DateRangeFilterOptions; showColumnName?: boolean; showClearButton?: boolean; diff --git a/packages/features/data-table/components/filters/FilterPopover.tsx b/packages/features/data-table/components/filters/FilterPopover.tsx index 3c02bb3f41..7e420111c2 100644 --- a/packages/features/data-table/components/filters/FilterPopover.tsx +++ b/packages/features/data-table/components/filters/FilterPopover.tsx @@ -1,6 +1,7 @@ -// eslint-disable-next-line no-restricted-imports + import startCase from "lodash/startCase"; +import type { FilterType } from "@calcom/types/data-table"; import { Badge } from "@calcom/ui/components/badge"; import { Button } from "@calcom/ui/components/button"; import type { IconName } from "@calcom/ui/components/icon"; @@ -18,7 +19,7 @@ import { FilterOptions } from "./FilterOptions"; import { useFilterPopoverOpen } from "./useFilterPopoverOpen"; import { numberFilterOperatorOptions, useTextFilterOperatorOptions } from "./utils"; -const FILTER_ICONS: Record = { +const FILTER_ICONS: Record = { [ColumnFilterType.TEXT]: "file-text", [ColumnFilterType.NUMBER]: "binary", [ColumnFilterType.MULTI_SELECT]: "layers", @@ -84,11 +85,11 @@ function AppliedSelectFilterValue({ column, filterValue }: SelectedLabelsProps) let moreCount = 0; if (isSingleSelectFilterValue(filterValue)) { - const options = (column as Extract).options; + const options = (column as FilterableColumn & { type: "ss" }).options; text = options.find((opt) => opt.value === filterValue.data)?.label; moreCount = 0; } else if (isMultiSelectFilterValue(filterValue)) { - const options = (column as Extract).options; + const options = (column as FilterableColumn & { type: "ms" }).options; text = options.find((opt) => opt.value === filterValue.data[0])?.label; moreCount = filterValue.data.length - 1; } diff --git a/packages/features/data-table/components/filters/MultiSelectFilterOptions.tsx b/packages/features/data-table/components/filters/MultiSelectFilterOptions.tsx index 72445dfff5..ef1462dad7 100644 --- a/packages/features/data-table/components/filters/MultiSelectFilterOptions.tsx +++ b/packages/features/data-table/components/filters/MultiSelectFilterOptions.tsx @@ -3,17 +3,18 @@ import { useDataTable } from "../../hooks"; import type { FilterableColumn } from "../../lib/types"; import { ZMultiSelectFilterValue, ColumnFilterType } from "../../lib/types"; +import type { FilterType } from "@calcom/types/data-table"; import { BaseSelectFilterOptions } from "./BaseSelectFilterOptions"; export type MultiSelectFilterOptionsProps = { - column: Extract; + column: Extract }>; }; export function MultiSelectFilterOptions({ column }: MultiSelectFilterOptionsProps) { const { updateFilter } = useDataTable(); return ( - + > column={column} filterValueSchema={ZMultiSelectFilterValue} testIdPrefix="select-filter-options" diff --git a/packages/features/data-table/components/filters/NumberFilterOptions.tsx b/packages/features/data-table/components/filters/NumberFilterOptions.tsx index fd651bbfb0..f0d5db9f54 100644 --- a/packages/features/data-table/components/filters/NumberFilterOptions.tsx +++ b/packages/features/data-table/components/filters/NumberFilterOptions.tsx @@ -9,10 +9,11 @@ import { Form, Select, NumberInput } from "@calcom/ui/components/form"; import { useFilterValue, useDataTable } from "../../hooks"; import type { FilterableColumn } from "../../lib/types"; import { ZNumberFilterValue, ColumnFilterType } from "../../lib/types"; +import type { FilterType } from "@calcom/types/data-table"; import { numberFilterOperatorOptions } from "./utils"; export type NumberFilterOptionsProps = { - column: Extract; + column: Extract }>; }; export function NumberFilterOptions({ column }: NumberFilterOptionsProps) { diff --git a/packages/features/data-table/components/filters/SingleSelectFilterOptions.tsx b/packages/features/data-table/components/filters/SingleSelectFilterOptions.tsx index 756cad64cc..cf6b74f385 100644 --- a/packages/features/data-table/components/filters/SingleSelectFilterOptions.tsx +++ b/packages/features/data-table/components/filters/SingleSelectFilterOptions.tsx @@ -1,19 +1,21 @@ "use client"; +import type { FilterType } from "@calcom/types/data-table"; + import { useDataTable } from "../../hooks"; import type { FilterableColumn } from "../../lib/types"; import { ZSingleSelectFilterValue, ColumnFilterType } from "../../lib/types"; import { BaseSelectFilterOptions } from "./BaseSelectFilterOptions"; export type SingleSelectFilterOptionsProps = { - column: Extract; + column: Extract }>; }; export function SingleSelectFilterOptions({ column }: SingleSelectFilterOptionsProps) { const { updateFilter } = useDataTable(); return ( - + > column={column} filterValueSchema={ZSingleSelectFilterValue} testIdPrefix="select-filter-options" diff --git a/packages/features/data-table/components/filters/TextFilterOptions.tsx b/packages/features/data-table/components/filters/TextFilterOptions.tsx index 649b10179d..40abefa356 100644 --- a/packages/features/data-table/components/filters/TextFilterOptions.tsx +++ b/packages/features/data-table/components/filters/TextFilterOptions.tsx @@ -9,10 +9,11 @@ import { Form, Select, Input } from "@calcom/ui/components/form"; import { useFilterValue, useDataTable } from "../../hooks"; import type { FilterableColumn } from "../../lib/types"; import { ZTextFilterValue, ColumnFilterType } from "../../lib/types"; +import type { FilterType } from "@calcom/types/data-table"; import { useTextFilterOperatorOptions } from "./utils"; export type TextFilterOptionsProps = { - column: Extract; + column: Extract }>; }; export function TextFilterOptions({ column }: TextFilterOptionsProps) { diff --git a/packages/features/data-table/hooks/useFilterValue.ts b/packages/features/data-table/hooks/useFilterValue.ts index 3ac8ff52a7..1db4ddf8cc 100644 --- a/packages/features/data-table/hooks/useFilterValue.ts +++ b/packages/features/data-table/hooks/useFilterValue.ts @@ -1,11 +1,12 @@ import { useMemo } from "react"; import type { z } from "zod"; -import type { FilterValueSchema, ColumnFilterType, ZFilterValue } from "../lib/types"; +import type { FilterValueSchema, ZFilterValue } from "../lib/types"; +import type { FilterType } from "@calcom/types/data-table"; import { useDataTable } from "./useDataTable"; export function useFilterValue< - T extends ColumnFilterType, + T extends FilterType, TSchema extends FilterValueSchema | typeof ZFilterValue >(columnId: string, schema: TSchema) { const { activeFilters } = useDataTable(); diff --git a/packages/features/data-table/lib/types.ts b/packages/features/data-table/lib/types.ts index 033d58179d..781c813934 100644 --- a/packages/features/data-table/lib/types.ts +++ b/packages/features/data-table/lib/types.ts @@ -1,19 +1,24 @@ import type { SortingState, ColumnSort } from "@tanstack/react-table"; import { z } from "zod"; -import type { IconName } from "@calcom/ui/components/icon"; +import type { TextFilterOperator, FilterType } from "@calcom/types/data-table"; +export type { ColumnFilterMeta, FilterableColumn } from "@calcom/types/data-table"; + +const ColumnFilterType = { + SINGLE_SELECT: "ss", + MULTI_SELECT: "ms", + TEXT: "t", + NUMBER: "n", + DATE_RANGE: "dr", +} as const satisfies Record; + +type ColumnFilterTypeValues = typeof ColumnFilterType; export type { SortingState } from "@tanstack/react-table"; export const SYSTEM_SEGMENT_PREFIX = "system_"; -export enum ColumnFilterType { - SINGLE_SELECT = "ss", - MULTI_SELECT = "ms", - TEXT = "t", - NUMBER = "n", - DATE_RANGE = "dr", -} +export { ColumnFilterType, TextFilterOperator }; export const textFilterOperators = [ "equals", @@ -26,12 +31,10 @@ export const textFilterOperators = [ "isNotEmpty", ] as const; -export type TextFilterOperator = (typeof textFilterOperators)[number]; - export const ZTextFilterOperator = z.enum(textFilterOperators); export type SingleSelectFilterValue = { - type: ColumnFilterType.SINGLE_SELECT; + type: ColumnFilterTypeValues["SINGLE_SELECT"]; data: string | number; }; @@ -41,7 +44,7 @@ export const ZSingleSelectFilterValue = z.object({ }) satisfies z.ZodType; export type MultiSelectFilterValue = { - type: ColumnFilterType.MULTI_SELECT; + type: ColumnFilterTypeValues["MULTI_SELECT"]; data: Array; }; @@ -51,7 +54,7 @@ export const ZMultiSelectFilterValue = z.object({ }) satisfies z.ZodType; export type TextFilterValue = { - type: ColumnFilterType.TEXT; + type: ColumnFilterTypeValues["TEXT"]; data: { operator: TextFilterOperator; operand: string; @@ -73,7 +76,7 @@ export type NumberFilterOperator = (typeof numberFilterOperators)[number]; export const ZNumberFilterOperator = z.enum(numberFilterOperators); export type NumberFilterValue = { - type: ColumnFilterType.NUMBER; + type: ColumnFilterTypeValues["NUMBER"]; data: { operator: NumberFilterOperator; operand: number; @@ -89,7 +92,7 @@ export const ZNumberFilterValue = z.object({ }) satisfies z.ZodType; export type DateRangeFilterValue = { - type: ColumnFilterType.DATE_RANGE; + type: ColumnFilterTypeValues["DATE_RANGE"]; data: { startDate: string | null; endDate: string | null; @@ -124,48 +127,6 @@ export type TextFilterOptions = { placeholder?: string; }; -export type ColumnFilterMeta = - | { - type: ColumnFilterType.DATE_RANGE; - icon?: IconName; - dateRangeOptions?: DateRangeFilterOptions; - } - | { - type: ColumnFilterType.TEXT; - icon?: IconName; - textOptions?: TextFilterOptions; - } - | { - type?: Exclude; - icon?: IconName; - }; - -export type FilterableColumn = { - id: string; - title: string; - icon?: IconName; -} & ( - | { - type: ColumnFilterType.SINGLE_SELECT; - options: FacetedValue[]; - } - | { - type: ColumnFilterType.MULTI_SELECT; - options: FacetedValue[]; - } - | { - type: ColumnFilterType.TEXT; - textOptions?: TextFilterOptions; - } - | { - type: ColumnFilterType.NUMBER; - } - | { - type: ColumnFilterType.DATE_RANGE; - dateRangeOptions?: DateRangeFilterOptions; - } -); - export type ColumnFilter = { id: string; value: FilterValue; @@ -176,32 +137,32 @@ export const ZColumnFilter = z.object({ value: ZFilterValue, }) satisfies z.ZodType; -export type FilterValueSchema = T extends ColumnFilterType.SINGLE_SELECT +export type FilterValueSchema = T extends ColumnFilterTypeValues["SINGLE_SELECT"] ? typeof ZSingleSelectFilterValue - : T extends ColumnFilterType.MULTI_SELECT + : T extends ColumnFilterTypeValues["MULTI_SELECT"] ? typeof ZMultiSelectFilterValue - : T extends ColumnFilterType.TEXT + : T extends ColumnFilterTypeValues["TEXT"] ? typeof ZTextFilterValue - : T extends ColumnFilterType.NUMBER + : T extends ColumnFilterTypeValues["NUMBER"] ? typeof ZNumberFilterValue - : T extends ColumnFilterType.DATE_RANGE + : T extends ColumnFilterTypeValues["DATE_RANGE"] ? typeof ZDateRangeFilterValue : never; -export type FilterValue = - T extends ColumnFilterType.SINGLE_SELECT +export type FilterValue = + T extends ColumnFilterTypeValues["SINGLE_SELECT"] ? SingleSelectFilterValue - : T extends ColumnFilterType.MULTI_SELECT + : T extends ColumnFilterTypeValues["MULTI_SELECT"] ? MultiSelectFilterValue - : T extends ColumnFilterType.TEXT + : T extends ColumnFilterTypeValues["TEXT"] ? TextFilterValue - : T extends ColumnFilterType.NUMBER + : T extends ColumnFilterTypeValues["NUMBER"] ? NumberFilterValue - : T extends ColumnFilterType.DATE_RANGE + : T extends ColumnFilterTypeValues["DATE_RANGE"] ? DateRangeFilterValue : never; -export type TypedColumnFilter = { +export type TypedColumnFilter = { id: string; value: FilterValue; }; diff --git a/packages/features/insights/components/routing/RoutingFormResponsesTable.tsx b/packages/features/insights/components/routing/RoutingFormResponsesTable.tsx index d8354fd2be..ea52485374 100644 --- a/packages/features/insights/components/routing/RoutingFormResponsesTable.tsx +++ b/packages/features/insights/components/routing/RoutingFormResponsesTable.tsx @@ -19,6 +19,7 @@ import { ZSingleSelectFilterValue, type FilterableColumn, } from "@calcom/features/data-table"; +import type { FilterType } from "@calcom/types/data-table"; import { useInsightsRoutingParameters } from "@calcom/features/insights/hooks/useInsightsRoutingParameters"; import { trpc } from "@calcom/trpc"; @@ -34,7 +35,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale"; export type RoutingFormTableType = ReturnType>; -const createdAtColumn: Extract = { +const createdAtColumn: Extract }> = { id: "createdAt", title: "createdAt", type: ColumnFilterType.DATE_RANGE, diff --git a/packages/features/insights/lib/bookingUtils.ts b/packages/features/insights/lib/bookingUtils.ts index 6ddf794af1..e017be07ba 100644 --- a/packages/features/insights/lib/bookingUtils.ts +++ b/packages/features/insights/lib/bookingUtils.ts @@ -1,6 +1,7 @@ import { ColumnFilterType } from "@calcom/features/data-table/lib/types"; import { type ColumnFilter } from "@calcom/features/data-table/lib/types"; import { isDateRangeFilterValue } from "@calcom/features/data-table/lib/utils"; +import type { FilterType } from "@calcom/types/data-table"; export function extractDateRangeFromColumnFilters(columnFilters?: ColumnFilter[]) { if (!columnFilters) throw new Error("No date range filter found"); @@ -9,7 +10,7 @@ export function extractDateRangeFromColumnFilters(columnFilters?: ColumnFilter[] if ((filter.id === "startTime" || filter.id === "createdAt") && isDateRangeFilterValue(filter.value)) { const dateFilter = filter.value as Extract< ColumnFilter["value"], - { type: ColumnFilterType.DATE_RANGE } + { type: Extract } >; if (dateFilter.data.startDate && dateFilter.data.endDate) { return { diff --git a/packages/features/insights/services/InsightsRoutingBaseService.ts b/packages/features/insights/services/InsightsRoutingBaseService.ts index b5a109945d..f25ef2be6d 100644 --- a/packages/features/insights/services/InsightsRoutingBaseService.ts +++ b/packages/features/insights/services/InsightsRoutingBaseService.ts @@ -3,7 +3,7 @@ import { z } from "zod"; import dayjs from "@calcom/dayjs"; import { makeSqlCondition } from "@calcom/features/data-table/lib/server"; import type { FilterValue, TextFilterValue, TypedColumnFilter } from "@calcom/features/data-table/lib/types"; -import type { ColumnFilterType } from "@calcom/features/data-table/lib/types"; +import type { FilterType } from "@calcom/types/data-table"; import { isMultiSelectFilterValue, isTextFilterValue, @@ -49,7 +49,7 @@ export type InsightsRoutingServiceOptions = z.infer[]; + columnFilters?: TypedColumnFilter[]; }; export type InsightsRoutingTableItem = { @@ -705,7 +705,7 @@ export class InsightsRoutingBaseService { columnFilters.reduce((acc, filter) => { acc[filter.id] = filter; return acc; - }, {} as Record>) || {}; + }, {} as Record>) || {}; // Extract booking status order filter const bookingStatusOrder = filtersMap["bookingStatusOrder"]; diff --git a/packages/trpc/server/routers/viewer/organizations/listMembers.handler.test.ts b/packages/trpc/server/routers/viewer/organizations/listMembers.handler.test.ts index 75604a1cba..11259ba4f4 100644 --- a/packages/trpc/server/routers/viewer/organizations/listMembers.handler.test.ts +++ b/packages/trpc/server/routers/viewer/organizations/listMembers.handler.test.ts @@ -3,6 +3,7 @@ import { prisma } from "@calcom/prisma/__mocks__/prisma"; import { describe, expect, it, vi, beforeEach } from "vitest"; import { type TypedColumnFilter, ColumnFilterType } from "@calcom/features/data-table/lib/types"; +import type { FilterType } from "@calcom/types/data-table"; import { listMembersHandler } from "./listMembers.handler"; @@ -76,6 +77,7 @@ describe("listMembersHandler", () => { prisma.membership.count.mockResolvedValue(0); prisma.membership.findFirst.mockResolvedValue({ role: "ADMIN" }); // Mock team.findUnique to return only isPrivate field since that's what the handler selects + // eslint-disable-next-line @typescript-eslint/no-explicit-any prisma.team.findUnique.mockResolvedValue({ isPrivate: false } as any); }); @@ -83,7 +85,7 @@ describe("listMembersHandler", () => { // Mock PBAC enabled mockCheckIfTeamHasFeature.mockResolvedValue(true); - const roleFilter: TypedColumnFilter = { + const roleFilter: TypedColumnFilter> = { id: "role", value: { type: ColumnFilterType.MULTI_SELECT, @@ -122,7 +124,7 @@ describe("listMembersHandler", () => { // Mock PBAC disabled mockCheckIfTeamHasFeature.mockResolvedValue(false); - const roleFilter: TypedColumnFilter = { + const roleFilter: TypedColumnFilter> = { id: "role", value: { type: ColumnFilterType.MULTI_SELECT, @@ -157,7 +159,7 @@ describe("listMembersHandler", () => { // Mock PBAC disabled for this test mockCheckIfTeamHasFeature.mockResolvedValue(false); - const roleFilter: TypedColumnFilter = { + const roleFilter: TypedColumnFilter> = { id: "role", value: { type: ColumnFilterType.MULTI_SELECT, @@ -165,7 +167,7 @@ describe("listMembersHandler", () => { }, }; - const teamFilter: TypedColumnFilter = { + const teamFilter: TypedColumnFilter> = { id: "teams", value: { type: ColumnFilterType.MULTI_SELECT, @@ -173,7 +175,7 @@ describe("listMembersHandler", () => { }, }; - const attributeFilter1: TypedColumnFilter = { + const attributeFilter1: TypedColumnFilter> = { id: "1", value: { type: ColumnFilterType.MULTI_SELECT, @@ -181,7 +183,7 @@ describe("listMembersHandler", () => { }, }; - const attributeFilter2: TypedColumnFilter = { + const attributeFilter2: TypedColumnFilter> = { id: "2", value: { type: ColumnFilterType.MULTI_SELECT, diff --git a/packages/trpc/server/routers/viewer/organizations/listMembers.handler.ts b/packages/trpc/server/routers/viewer/organizations/listMembers.handler.ts index a172b86774..d8087488f9 100644 --- a/packages/trpc/server/routers/viewer/organizations/listMembers.handler.ts +++ b/packages/trpc/server/routers/viewer/organizations/listMembers.handler.ts @@ -1,8 +1,7 @@ import { makeWhereClause } from "@calcom/features/data-table/lib/server"; import { type TypedColumnFilter, ColumnFilterType } from "@calcom/features/data-table/lib/types"; +import type { FilterType } from "@calcom/types/data-table"; import { FeaturesRepository } from "@calcom/features/flags/features.repository"; -import { Resource, CustomAction } from "@calcom/features/pbac/domain/types/permission-registry"; -import { getSpecificPermissions } from "@calcom/features/pbac/lib/resource-permissions"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { prisma } from "@calcom/prisma"; @@ -113,19 +112,19 @@ export const listMembersHandler = async ({ ctx, input }: GetOptions) => { const { limit, offset } = input; const roleFilter = filters.find((filter) => filter.id === "role") as - | TypedColumnFilter + | TypedColumnFilter> | undefined; const teamFilter = filters.find((filter) => filter.id === "teams") as - | TypedColumnFilter + | TypedColumnFilter> | undefined; const lastActiveAtFilter = filters.find((filter) => filter.id === "lastActiveAt") as - | TypedColumnFilter + | TypedColumnFilter> | undefined; const createdAtFilter = filters.find((filter) => filter.id === "createdAt") as - | TypedColumnFilter + | TypedColumnFilter> | undefined; const updatedAtFilter = filters.find((filter) => filter.id === "updatedAt") as - | TypedColumnFilter + | TypedColumnFilter> | undefined; const roleWhereClause = roleFilter diff --git a/packages/types/data-table.d.ts b/packages/types/data-table.d.ts new file mode 100644 index 0000000000..2e364eed82 --- /dev/null +++ b/packages/types/data-table.d.ts @@ -0,0 +1,57 @@ +import type { IconName } from "@calcom/ui/components/icon/icon-names"; + +export type FilterType = "ss" | "ms" | "t" | "n" | "dr"; + +export type TextFilterOperator = "equals" | "notEquals" | "contains" | "notContains" | "startsWith" | "endsWith" | "isEmpty" | "isNotEmpty"; + +export type TextFilterOptions = { + allowedOperators?: TextFilterOperator[]; + placeholder?: string; +}; + +export type DateRangeFilterOptions = { + range?: "past" | "custom"; + convertToTimeZone?: boolean; +}; + +export type ColumnFilterMeta = + | { + type: Extract; + icon?: IconName; + dateRangeOptions?: DateRangeFilterOptions; + } + | { + type: Extract; + icon?: IconName; + textOptions?: TextFilterOptions; + } + | { + type?: Extract; + icon?: IconName; + }; + +export type FilterableColumn = { + id: string; + title: string; + icon?: IconName; +} & ( + | { + type: Extract; + options: FacetedValue[]; + } + | { + type: Extract; + options: FacetedValue[]; + } + | { + type: Extract; + textOptions?: TextFilterOptions; + } + | { + type: Extract; + } + | { + type: Extract; + dateRangeOptions?: DateRangeFilterOptions; + } +); \ No newline at end of file diff --git a/packages/types/tanstack-table.d.ts b/packages/types/tanstack-table.d.ts index ed04a037f3..716c838fb1 100644 --- a/packages/types/tanstack-table.d.ts +++ b/packages/types/tanstack-table.d.ts @@ -1,9 +1,9 @@ import "@tanstack/react-table"; -import type { ColumnFilterMeta } from "@calcom/features/data-table/lib/types"; +import type { ColumnFilterMeta } from "./data-table"; declare module "@tanstack/table-core" { - interface ColumnMeta { + interface ColumnMeta { filter?: ColumnFilterMeta; // `autoWidth` can make the column size dynamic,