From af9bf14d9e26d1062ae12bb5f3fd38185d3f1de8 Mon Sep 17 00:00:00 2001 From: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Date: Sat, 16 Nov 2024 18:05:36 +0000 Subject: [PATCH] fix: routing column filters (#17688) * remove column filters * remove column filters * use a loading state while loading columns * fix --- .../insights/insights-routing-view.tsx | 8 +- apps/web/public/static/locales/en/common.json | 2 + .../components/RoutingFormResponsesTable.tsx | 100 ++++++++++++++---- packages/features/insights/filters/index.tsx | 13 +-- 4 files changed, 83 insertions(+), 40 deletions(-) diff --git a/apps/web/modules/insights/insights-routing-view.tsx b/apps/web/modules/insights/insights-routing-view.tsx index 13aa5b35aa..24cd91896b 100644 --- a/apps/web/modules/insights/insights-routing-view.tsx +++ b/apps/web/modules/insights/insights-routing-view.tsx @@ -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(null); return ( - +
- + diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index 501e748e1c..26367507cb 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -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)", diff --git a/packages/features/insights/components/RoutingFormResponsesTable.tsx b/packages/features/insights/components/RoutingFormResponsesTable.tsx index 1a9e14727a..15430c42d9 100644 --- a/packages/features/insights/components/RoutingFormResponsesTable.tsx +++ b/packages/features/insights/components/RoutingFormResponsesTable.tsx @@ -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>; -export function RoutingFormResponsesTable({ - onTableReady, -}: { - onTableReady?: (table: RoutingFormTableType) => void; -}) { +export function RoutingFormResponsesTable() { const { t } = useLocale(); const { filter } = useFilterContext(); const tableContainerRef = useRef(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(); @@ -319,6 +323,7 @@ export function RoutingFormResponsesTable({ return ; }, }), + ...(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) => (
@@ -351,6 +355,14 @@ export function RoutingFormResponsesTable({
), }), + columnHelper.accessor("createdAt", { + id: "submittedAt", + header: t("routing_form_insights_submitted_at"), + size: 250, + cell: (info) => ( +
{dayjs(info.getValue()).format("MMM D, YYYY HH:mm")}
+ ), + }), ], [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 ( +
+
+ + + + {[...Array(4)].map((_, index) => ( + +
+ + ))} + + + + {[...Array(10)].map((_, rowIndex) => ( + + {[...Array(4)].map((_, colIndex) => ( + +
+ + ))} + + ))} + +
+
+
+ ); + } + return (
{ ); }; -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 = ({
{showRoutingFilters ? : } - - {routingTable && }
);