fix: routing column filters (#17688)

* remove column filters

* remove column filters

* use a loading state while loading columns

* fix
This commit is contained in:
sean-brydon authored and GitHub committed 2024-11-16 18:05:36 +00:00
1 parent b1a0cdc8e2
commit af9bf14d9e
4 files changed
+83 -40

No files matched your search

@@ -1,12 +1,9 @@
"use client";
import { useState } from "react";
import {
RoutingFormResponsesTable,
RoutingKPICards,
FailedBookingsByField,
type RoutingFormTableType,
} from "@calcom/features/insights/components";
import { FiltersProvider } from "@calcom/features/insights/context/FiltersProvider";
import { Filters } from "@calcom/features/insights/filters";
@@ -16,17 +13,16 @@ import InsightsLayout from "./layout";
export default function InsightsPage() {
const { t } = useLocale();
const [routingTable, setRoutingTable] = useState<RoutingFormTableType | null>(null);
return (
<InsightsLayout>
<FiltersProvider>
<Filters showRoutingFilters routingTable={routingTable} />
<Filters showRoutingFilters />
<div className="mb-4 space-y-4">
<RoutingKPICards />
<RoutingFormResponsesTable onTableReady={setRoutingTable} />
<RoutingFormResponsesTable />
<FailedBookingsByField />
@@ -2783,6 +2783,8 @@
"routing_form_insights_booked_by": "Booked by",
"routing_form_insights_created_at": "Created at",
"routing_form_insights_booking_status": "Booking Status",
"routing_form_insights_booking_at": "Booking At",
"routing_form_insights_submitted_at": "Submitted At",
"access_denied": "Access Denied",
"salesforce_route_to_owner": "Contact owner will be the Round Robin host if available",
"salesforce_do_not_route_to_owner": "Contact owner will not be forced (can still be host if it matches the attributes and Round Robin criteria)",
@@ -9,7 +9,7 @@ import {
createColumnHelper,
} from "@tanstack/react-table";
import Link from "next/link";
import { useRef, useMemo, useId, useEffect } from "react";
import { useRef, useMemo, useId } from "react";
import dayjs from "@calcom/dayjs";
import classNames from "@calcom/lib/classNames";
@@ -26,6 +26,12 @@ import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@calcom/ui";
import type { BadgeProps } from "@calcom/ui/components/badge/Badge";
@@ -210,11 +216,7 @@ function BookingStatusCell({
export type RoutingFormTableType = ReturnType<typeof useReactTable<RoutingFormTableRow>>;
export function RoutingFormResponsesTable({
onTableReady,
}: {
onTableReady?: (table: RoutingFormTableType) => void;
}) {
export function RoutingFormResponsesTable() {
const { t } = useLocale();
const { filter } = useFilterContext();
const tableContainerRef = useRef<HTMLDivElement>(null);
@@ -233,16 +235,17 @@ export function RoutingFormResponsesTable({
const initialConfigIsReady = !!(initialConfig?.teamId || initialConfig?.userId || initialConfig?.isAll);
const [startDate, endDate] = dateRange;
const { data: headers } = trpc.viewer.insights.routingFormResponsesHeaders.useQuery(
{
teamId: selectedTeamId ?? undefined,
isAll: isAll ?? false,
routingFormId: selectedRoutingFormId ?? undefined,
},
{
enabled: initialConfigIsReady,
}
);
const { data: headers, isLoading: isHeadersLoading } =
trpc.viewer.insights.routingFormResponsesHeaders.useQuery(
{
teamId: selectedTeamId ?? undefined,
isAll: isAll ?? false,
routingFormId: selectedRoutingFormId ?? undefined,
},
{
enabled: initialConfigIsReady,
}
);
const { data, fetchNextPage, isFetching, hasNextPage } =
trpc.viewer.insights.routingFormResponses.useInfiniteQuery(
@@ -272,6 +275,7 @@ export function RoutingFormResponsesTable({
const totalFetched = flatData.length;
const processedData = useMemo(() => {
if (isHeadersLoading) return [];
return flatData.map((response) => {
const row: RoutingFormTableRow = {
id: response.id,
@@ -304,7 +308,7 @@ export function RoutingFormResponsesTable({
return row;
});
}, [flatData, headers]);
}, [flatData, headers, isHeadersLoading]);
const columnHelper = createColumnHelper<RoutingFormTableRow>();
@@ -319,6 +323,7 @@ export function RoutingFormResponsesTable({
return <BookedByCell attendees={row.routedToBooking?.attendees || []} rowId={row.id} />;
},
}),
...(headers?.map((header) => {
return columnHelper.accessor(header.id, {
id: header.id,
@@ -335,10 +340,9 @@ export function RoutingFormResponsesTable({
},
});
}) ?? []),
columnHelper.accessor("routedToBooking", {
id: "bookingStatus",
header: t("routing_form_insights_booking_status"),
header: t("routing_form_insights_booking_at"),
size: 250,
cell: (info) => (
<div className="max-w-[250px]">
@@ -351,6 +355,14 @@ export function RoutingFormResponsesTable({
</div>
),
}),
columnHelper.accessor("createdAt", {
id: "submittedAt",
header: t("routing_form_insights_submitted_at"),
size: 250,
cell: (info) => (
<div className="max-w-[250px]">{dayjs(info.getValue()).format("MMM D, YYYY HH:mm")}</div>
),
}),
],
[headers, t, copyToClipboard]
);
@@ -366,10 +378,6 @@ export function RoutingFormResponsesTable({
},
});
useEffect(() => {
onTableReady?.(table);
}, [table, onTableReady]);
const fetchMoreOnBottomReached = useFetchMoreOnBottomReached(
tableContainerRef,
fetchNextPage,
@@ -378,6 +386,52 @@ export function RoutingFormResponsesTable({
totalDBRowCount
);
if (isHeadersLoading || (isFetching && !data)) {
return (
<div
className="grid h-[75dvh]"
style={{ gridTemplateRows: "auto 1fr auto", gridTemplateAreas: "'header' 'body' 'footer'" }}>
<div
className="scrollbar-thin border-subtle relative h-full overflow-auto rounded-md border"
style={{ gridArea: "body" }}>
<Table>
<TableHeader className="bg-subtle sticky top-0 z-10">
<TableRow>
{[...Array(4)].map((_, index) => (
<TableHead key={`skeleton-header-${index}`}>
<div className="bg-subtle h-4 w-[200px] animate-pulse rounded-md" />
</TableHead>
))}
</TableRow>
</TableHeader>
<TableBody>
{[...Array(10)].map((_, rowIndex) => (
<TableRow key={`skeleton-row-${rowIndex}`}>
{[...Array(4)].map((_, colIndex) => (
<TableCell key={`skeleton-cell-${rowIndex}-${colIndex}`}>
<div
className={classNames(
"bg-subtle h-6 animate-pulse rounded-md",
colIndex === 0
? "w-[200px]"
: colIndex === 2
? "w-[250px]"
: colIndex === 3
? "w-[250px]"
: "w-[200px]"
)}
/>
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
);
}
return (
<div className="flex-1">
<DataTable
+2 -11
View File
@@ -1,7 +1,6 @@
import type { RoutingFormTableType } from "@calcom/features/insights/components/RoutingFormResponsesTable";
import { useFilterContext } from "@calcom/features/insights/context/provider";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, Icon, Tooltip, DataTableFilters } from "@calcom/ui";
import { Button, Icon, Tooltip } from "@calcom/ui";
import { BookingStatusFilter } from "./BookingStatusFilter";
import { DateSelect } from "./DateSelect";
@@ -38,13 +37,7 @@ const ClearFilters = () => {
);
};
export const Filters = ({
showRoutingFilters = false,
routingTable = null,
}: {
showRoutingFilters?: boolean;
routingTable?: RoutingFormTableType | null;
}) => {
export const Filters = ({ showRoutingFilters = false }: { showRoutingFilters?: boolean }) => {
const { filter } = useFilterContext();
const { selectedFilter } = filter;
@@ -105,8 +98,6 @@ export const Filters = ({
<div className="flex flex-col-reverse sm:flex-row sm:flex-nowrap sm:justify-between">
{showRoutingFilters ? <RoutingDownload /> : <Download />}
<DateSelect />
{routingTable && <DataTableFilters.ColumnVisibilityButton table={routingTable} />}
</div>
</div>
);