diff --git a/electron/main/api.ts b/electron/main/api.ts index 32d4de7..90b8848 100644 --- a/electron/main/api.ts +++ b/electron/main/api.ts @@ -229,9 +229,9 @@ export const router = t.router({ await upsertAccount({ plaidId: account.id, name: account.name, - mask: account.mask, - type: account.type, - subtype: account.subtype, + mask: account.mask ?? '', + type: account.type ?? '', + subtype: account.subtype ?? '', institutionPlaidId: input.institutionId, }) } diff --git a/electron/main/models/transactions.ts b/electron/main/models/transactions.ts index 8faebbb..3fce03e 100644 --- a/electron/main/models/transactions.ts +++ b/electron/main/models/transactions.ts @@ -3,6 +3,12 @@ import { z } from 'zod' import { prisma } from '../prisma' import { Prisma } from '@prisma/client' +function narrowFilterType( + filter: unknown, +): asserts filter is string | string[] { + z.union([z.string(), z.array(z.string())]).parse(filter) +} + export async function fetchTransactions({ sort, sortColumn, @@ -18,11 +24,24 @@ export async function fetchTransactions({ } if (columnFilters.length) { - where.OR = columnFilters.map((filter) => ({ - [filter.id]: { - contains: filter.value as string, - }, - })) + where.OR = columnFilters.map((filter) => { + narrowFilterType(filter.value) + + switch (filter.id) { + case 'account': + return { + account: { + plaidId: Array.isArray(filter.value) + ? { in: filter.value } + : filter.value, + }, + } + default: + return { + [filter.id]: { contains: filter.value }, + } + } + }) } const [results, total] = await Promise.all([ diff --git a/src/components/pages/TablePage.tsx b/src/components/pages/TablePage.tsx index f855ec4..c8936bb 100644 --- a/src/components/pages/TablePage.tsx +++ b/src/components/pages/TablePage.tsx @@ -9,10 +9,8 @@ import { Transaction } from '@prisma/client' export function TablePage() { const [input, setInput] = useDataTableInput() const [selectedRows, setSelectedRows] = useState([]) - - const { data /*, refetch*/ } = trpc.transactions.useQuery(input, { - keepPreviousData: true, - }) + const { data } = trpc.transactions.useQuery(input, { keepPreviousData: true }) + const { data: accounts } = trpc.accounts.useQuery() const table = useDataTable({ data: data?.results ?? [], @@ -40,7 +38,20 @@ export function TablePage() { return ( <> - + ({ + label: account.name, + value: account.plaidId, + })) ?? [], + }, + ]} + /> {Boolean(selectedRows.length) && ( diff --git a/src/components/ui/data-table/data-table-faceted-filter.tsx b/src/components/ui/data-table/data-table-faceted-filter.tsx index fce1cab..03eeea0 100644 --- a/src/components/ui/data-table/data-table-faceted-filter.tsx +++ b/src/components/ui/data-table/data-table-faceted-filter.tsx @@ -21,14 +21,16 @@ import { } from '@/components/ui/popover' import { Separator } from '@/components/ui/separator' +export interface FacetedFilterOption { + label: string + value: string + icon?: React.ComponentType<{ className?: string }> +} + interface DataTableFacetedFilterProps { column?: Column title?: string - options: { - label: string - value: string - icon?: React.ComponentType<{ className?: string }> - }[] + options: FacetedFilterOption[] } export function DataTableFacetedFilter({ diff --git a/src/components/ui/data-table/data-table-toolbar.tsx b/src/components/ui/data-table/data-table-toolbar.tsx index 5db3633..f565193 100644 --- a/src/components/ui/data-table/data-table-toolbar.tsx +++ b/src/components/ui/data-table/data-table-toolbar.tsx @@ -4,13 +4,22 @@ import { Table } from '@tanstack/react-table' import { Input } from '@/components/ui/input' import { DataTableViewOptions } from './data-table-view-options' -import { DataTableFacetedFilter } from './data-table-faceted-filter' +import { + DataTableFacetedFilter, + FacetedFilterOption, +} from './data-table-faceted-filter' import { Button } from '../button' import { Cross2Icon } from '@radix-ui/react-icons' +export interface DataTableFilter { + column: keyof TData + title: string + options: FacetedFilterOption[] +} + interface DataTableToolbarProps { table: Table - filters?: { column: keyof TData }[] + filters?: DataTableFilter[] } export function DataTableToolbar({ @@ -30,28 +39,15 @@ export function DataTableToolbar({ } className="h-8 w-[150px] lg:w-[250px]" /> + {filters?.map((filter) => ( ))} - {/* {table.getColumn('merchantName') && ( - - )} - {table.getColumn('date') && ( - - )} */} {isFiltered && (