From 6274ebf4c17c85a0e859c941236182b26b720cc7 Mon Sep 17 00:00:00 2001 From: mrkarimoff Date: Mon, 29 Jan 2024 20:57:19 +0500 Subject: [PATCH] fix table filter issue and put it on the table header --- .../analytics/EventsTable/Columns.tsx | 129 ++++++++++-------- .../analytics/EventsTable/EventsTable.tsx | 11 +- .../analytics/EventsTable/TableFilter.tsx | 59 +++----- apps/analytics/app/options/page.tsx | 64 +++++++++ .../components/DataTable/column-header.tsx | 12 +- 5 files changed, 170 insertions(+), 105 deletions(-) create mode 100644 apps/analytics/app/options/page.tsx diff --git a/apps/analytics/app/_components/analytics/EventsTable/Columns.tsx b/apps/analytics/app/_components/analytics/EventsTable/Columns.tsx index 91bc7274..ab56e635 100644 --- a/apps/analytics/app/_components/analytics/EventsTable/Columns.tsx +++ b/apps/analytics/app/_components/analytics/EventsTable/Columns.tsx @@ -1,69 +1,84 @@ "use client"; import { ColumnDef } from "@tanstack/react-table"; +import { type Dispatch, type SetStateAction } from "react"; import { DataTableColumnHeader } from "~/components/DataTable/column-header"; import { MetadataDialog } from "~/components/MetadataDialog"; import type { Event } from "~/db/getEvents"; +import { type EventType } from "./EventsTable"; import { StackTraceDialog } from "./StackTraceDialog"; +import TableFilter from "./TableFilter"; -export const columns: ColumnDef[] = [ - { - accessorKey: "type", - header: ({ column }) => ( - - ), - }, - { - accessorKey: "timestamp", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - return ( -
{row.original.timestamp.toUTCString()}
- ); +export const getColumns = ( + eventTypes: EventType[], + setEventTypes: Dispatch> +) => { + const columns: ColumnDef[] = [ + { + accessorKey: "type", + header: ({ column }) => ( +
+ + +
+ ), }, - }, - { - accessorKey: "installationId", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - return
{row.original.installationId}
; + { + accessorKey: "timestamp", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + return ( +
+ {row.original.timestamp.toUTCString()} +
+ ); + }, }, - }, - { - accessorKey: "name", - header: ({ column }) => ( - - ), - }, - { - accessorKey: "message", - header: ({ column }) => ( - - ), - }, - { - accessorKey: "stack", - header: "", - cell: ({ row }) => - row.original.stack && ( -
- -
+ { + accessorKey: "installationId", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + return
{row.original.installationId}
; + }, + }, + { + accessorKey: "name", + header: ({ column }) => ( + + ), + }, + { + accessorKey: "message", + header: ({ column }) => ( + ), - }, - { - accessorKey: "metadata", - header: "", - cell: ({ row }) => { - return ( -
- -
- ); }, - }, -]; + { + accessorKey: "stack", + header: "", + cell: ({ row }) => + row.original.stack && ( +
+ +
+ ), + }, + { + accessorKey: "metadata", + header: "", + cell: ({ row }) => { + return ( +
+ +
+ ); + }, + }, + ]; + + return columns; +}; diff --git a/apps/analytics/app/_components/analytics/EventsTable/EventsTable.tsx b/apps/analytics/app/_components/analytics/EventsTable/EventsTable.tsx index 9b7a57a3..1b650e46 100644 --- a/apps/analytics/app/_components/analytics/EventsTable/EventsTable.tsx +++ b/apps/analytics/app/_components/analytics/EventsTable/EventsTable.tsx @@ -4,8 +4,7 @@ import { useEffect, useMemo, useState } from "react"; import { DataTable } from "~/components/DataTable/data-table"; import ExportButton from "~/components/ExportButton"; import { Event } from "~/db/getEvents"; -import { columns } from "./Columns"; -import TableFilter from "./TableFilter"; +import { getColumns } from "./Columns"; export type EventType = { text: string; @@ -34,15 +33,17 @@ export default function EventsTable({ events }: { events: Event[] }) { return (
- -

Events

- +
); diff --git a/apps/analytics/app/_components/analytics/EventsTable/TableFilter.tsx b/apps/analytics/app/_components/analytics/EventsTable/TableFilter.tsx index f4c60858..73ca6c19 100644 --- a/apps/analytics/app/_components/analytics/EventsTable/TableFilter.tsx +++ b/apps/analytics/app/_components/analytics/EventsTable/TableFilter.tsx @@ -1,5 +1,6 @@ "use client"; +import { type Dispatch, type SetStateAction } from "react"; import { Button } from "~/components/ui/button"; import { Checkbox } from "~/components/ui/checkbox"; import { @@ -9,8 +10,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu"; -import { EventType } from "./EventsTable"; -import { useEffect, useState, type Dispatch, type SetStateAction } from "react"; +import { type EventType } from "./EventsTable"; type TableFilterProps = { eventTypes: EventType[]; @@ -18,44 +18,26 @@ type TableFilterProps = { }; const TableFilter = ({ eventTypes, setEventTypes }: TableFilterProps) => { - const [allSelected, setAllSelected] = useState(true); - - useEffect(() => { - const updatedEventTypes = eventTypes.map((t) => ({ - ...t, - isSelected: allSelected, - })); - setEventTypes(updatedEventTypes); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [allSelected]); - - const handleCheckedChange = (value: boolean, currentType: string) => { - const updatedEventTypes = eventTypes.map((t) => { - if (t.text === currentType) { - return { ...t, isSelected: value }; - } - return t; - }); - - // If all event types are selected, set allSelected to true - if (updatedEventTypes.every((t) => t.isSelected)) { - setAllSelected(true); - return; - } - - // If no event types are selected, set allSelected to false - if (updatedEventTypes.every((t) => !t.isSelected)) { - setAllSelected(false); - return; - } + const toggleOption = (option: string) => { + setEventTypes((prevState) => + prevState.map((t) => + t.text === option ? { ...t, isSelected: !t.isSelected } : t + ) + ); + }; - setEventTypes(updatedEventTypes); + const toggleAllOptions = (isSelected: boolean) => { + setEventTypes((prevState) => prevState.map((t) => ({ ...t, isSelected }))); }; + const isAllSelected = eventTypes.every((option) => option.isSelected); + return ( - + Select events @@ -64,11 +46,12 @@ const TableFilter = ({ eventTypes, setEventTypes }: TableFilterProps) => {
+ {eventTypes.map((type) => ( diff --git a/apps/analytics/app/options/page.tsx b/apps/analytics/app/options/page.tsx new file mode 100644 index 00000000..adaba41c --- /dev/null +++ b/apps/analytics/app/options/page.tsx @@ -0,0 +1,64 @@ +"use client"; + +import React, { useState } from "react"; + +const eventTypes = [ + "AppSetup", + "ProtocolInstalled", + "InterviewStarted", + "InterviewCompleted", + "DataExported", + "Error", +]; + +const DropdownMenu = () => { + const [selectedOptions, setSelectedOptions] = useState( + eventTypes.map((eventType) => ({ text: eventType, isSelected: true })) + ); + + const toggleOption = (option: string) => { + setSelectedOptions((prevOptions) => + prevOptions.map((prevOption) => + prevOption.text === option + ? { ...prevOption, isSelected: !prevOption.isSelected } + : prevOption + ) + ); + }; + + const toggleAllOptions = (isSelected: boolean) => { + setSelectedOptions((prevOptions) => + prevOptions.map((prevOption) => ({ ...prevOption, isSelected })) + ); + }; + + const isAllSelected = selectedOptions.every((option) => option.isSelected); + + return ( +
+ + {selectedOptions.map((option) => ( + + ))} +
+ ); +}; + +export default DropdownMenu; diff --git a/apps/analytics/components/DataTable/column-header.tsx b/apps/analytics/components/DataTable/column-header.tsx index b70fc25f..7a1e2378 100644 --- a/apps/analytics/components/DataTable/column-header.tsx +++ b/apps/analytics/components/DataTable/column-header.tsx @@ -13,7 +13,7 @@ import { cn } from "~/utils/shadcn"; interface DataTableColumnHeaderProps extends React.HTMLAttributes { column: Column; - title: string; + title?: string; } export function DataTableColumnHeader({ @@ -36,11 +36,15 @@ export function DataTableColumnHeader({ > {title} {column.getIsSorted() === "desc" ? ( - + ) : column.getIsSorted() === "asc" ? ( - + ) : ( - + )}