From a3ceefc00ed4600a7026954e873abd9cad4a356f Mon Sep 17 00:00:00 2001 From: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Date: Mon, 2 Dec 2024 19:21:42 +0000 Subject: [PATCH] merge columns (#17938) --- .../components/RoutingFormResponsesTable.tsx | 71 ++++++++++++++++--- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/packages/features/insights/components/RoutingFormResponsesTable.tsx b/packages/features/insights/components/RoutingFormResponsesTable.tsx index b9d9328d2e..ea3b506f75 100644 --- a/packages/features/insights/components/RoutingFormResponsesTable.tsx +++ b/packages/features/insights/components/RoutingFormResponsesTable.tsx @@ -26,10 +26,10 @@ import { HoverCardContent, HoverCardTrigger, Table, + TableHeader, TableBody, TableCell, TableHead, - TableHeader, TableRow, } from "@calcom/ui"; import type { BadgeProps } from "@calcom/ui/components/badge/Badge"; @@ -278,6 +278,40 @@ export function RoutingFormResponsesTable({ const totalDBRowCount = data?.pages?.[0]?.total ?? 0; const totalFetched = flatData.length; + const mergedHeaders = useMemo(() => { + if (!headers) return []; + + // Group headers by label + const headersByLabel = headers.reduce( + (acc, header) => { + if (!acc[header.label]) { + acc[header.label] = { + id: header.id, + label: header.label, + options: [], // Initialize as empty array + }; + } + + // Only merge options if they exist + if (header.options?.length) { + acc[header.label].options = [...acc[header.label].options, ...header.options]; + } + + return acc; + }, + {} as Record< + string, + { + id: string; + label: string; + options: { id: string | null; label: string }[]; + } + > + ); + + return Object.values(headersByLabel); + }, [headers]); + const processedData = useMemo(() => { if (isHeadersLoading) return []; return flatData.map((response) => { @@ -289,27 +323,42 @@ export function RoutingFormResponsesTable({ routedToBooking: response.routedToBooking, }; + // Group responses by header label + // NOTE: this is a HACK to group responses by label and not ID. Some how a client has duplicate headers in a form and we need to merge them + // We will revert this code when we have merged these on a DB level. + // These fields can also have different types, select,multiselect,text etc... so can provide weird results. + const valuesByLabel: Record = {}; + Object.entries(response.response).forEach(([fieldId, field]) => { const header = headers?.find((h) => h.id === fieldId); + if (!header) return; - if (header?.options) { + if (!valuesByLabel[header.label]) { + valuesByLabel[header.label] = []; + } + + if (header.options) { if (Array.isArray(field.value)) { - // Map the IDs to their corresponding labels for array values const labels = field.value.map((id) => { - const option = header.options?.find((opt) => opt.id === id); + const option = header.options?.find((opt) => opt?.id?.toLowerCase() === id.toLowerCase()); return option?.label ?? id; }); - row[fieldId] = labels; + valuesByLabel[header.label].push(...labels); } else { - // Handle single value case const option = header.options?.find((opt) => opt.id === field.value); - row[fieldId] = option?.label ?? field.value; + valuesByLabel[header.label].push(option?.label ?? field.value); } } else { - row[fieldId] = field.value; + valuesByLabel[header.label].push(field.value); } }); + // Add merged values to row + Object.entries(valuesByLabel).forEach(([label, values]) => { + const uniqueValues = Array.from(new Set(values)).filter(Boolean); + row[label] = uniqueValues; + }); + return row; }); }, [flatData, headers, isHeadersLoading]); @@ -328,9 +377,9 @@ export function RoutingFormResponsesTable({ }, }), - ...(headers?.map((header) => { - return columnHelper.accessor(header.id, { - id: header.id, + ...(mergedHeaders?.map((header) => { + return columnHelper.accessor(header.label, { + id: header.label, header: header.label, size: 200, cell: (info) => {