diff --git a/api/src/graphql/uploads.sdl.ts b/api/src/graphql/uploads.sdl.ts index 12f56e4b..403d1c10 100644 --- a/api/src/graphql/uploads.sdl.ts +++ b/api/src/graphql/uploads.sdl.ts @@ -21,6 +21,7 @@ export const schema = gql` type Query { uploads: [Upload!]! @requireAuth upload(id: Int!): Upload @requireAuth + getValidUploadsInCurrentPeriod: [Upload!]! @requireAuth } input CreateUploadInput { diff --git a/api/src/services/uploads/uploads.ts b/api/src/services/uploads/uploads.ts index b60062e6..5de1f2d5 100644 --- a/api/src/services/uploads/uploads.ts +++ b/api/src/services/uploads/uploads.ts @@ -42,6 +42,7 @@ export const uploads: QueryResolvers['uploads'] = () => { return db.upload.findMany({ where: whereInputs, + orderBy: { createdAt: 'desc' }, }) } diff --git a/web/src/components/TableBuilder/TableBuilder.tsx b/web/src/components/TableBuilder/TableBuilder.tsx index 267f1dd6..2ecb3b69 100644 --- a/web/src/components/TableBuilder/TableBuilder.tsx +++ b/web/src/components/TableBuilder/TableBuilder.tsx @@ -7,7 +7,7 @@ import { getFilteredRowModel, ColumnFiltersState, } from '@tanstack/react-table' -import { Button } from 'react-bootstrap' +import { Button, Form } from 'react-bootstrap' import Table from 'react-bootstrap/Table' import TableHeader from './TableHeader' @@ -16,9 +16,9 @@ import TableRow from './TableRow' /* This component uses TanStack Table to add filtering and sorting functionality. - For documentation, visit: https://tanstack.com/table/v8/docs/guide/introduction + For documentation, visit: https://tanstack.com/table/v8/docs/introduction */ -function TableBuilder({ data, columns, filterableInputs = [] }) { +function TableBuilder({ data, columns, filterableInputs = [], globalFilter }) { const [columnFilters, setColumnFilters] = useState([]) const [sorting, setSorting] = useState([]) @@ -36,25 +36,57 @@ function TableBuilder({ data, columns, filterableInputs = [] }) { getFilteredRowModel: getFilteredRowModel(), }) - const resetColumnFilters = () => { + const resetFilters = () => { table.resetColumnFilters() + if (globalFilter) { + globalFilter.onChange() + } + } + + const renderTableBody = () => { + const rows = table.getRowModel().rows + + if (!rows.length) { + return ( + + + No results found + + + ) + } + + return rows.map((row) => ) } return (
- {!!filterableInputs.length && ( + {(!!filterableInputs.length || globalFilter) && ( - + )} {table.getHeaderGroups().map((headerGroup) => ( @@ -65,11 +97,7 @@ function TableBuilder({ data, columns, filterableInputs = [] }) { /> ))} - - {table.getRowModel().rows.map((row) => ( - - ))} - + {renderTableBody()}
- - +
+ {globalFilter && ( + + )} + +
+
) diff --git a/web/src/components/Upload/Uploads/Uploads.tsx b/web/src/components/Upload/Uploads/Uploads.tsx index 89235955..8f27a8d0 100644 --- a/web/src/components/Upload/Uploads/Uploads.tsx +++ b/web/src/components/Upload/Uploads/Uploads.tsx @@ -4,7 +4,19 @@ import TableBuilder from 'src/components/TableBuilder/TableBuilder' import { columnDefs } from './columns' -const UploadsList = ({ uploads }: FindUploads) => { +interface UploadsListProps { + uploads: FindUploads['uploads'] + showTreasuryFiles: boolean + onTreasuryFilesChange: () => void + isLoading?: boolean +} + +const UploadsList = ({ + uploads, + showTreasuryFiles, + onTreasuryFilesChange, + isLoading, +}: UploadsListProps) => { const filterableInputs = [ 'agency_code', 'expenditureCategory_code', @@ -18,6 +30,12 @@ const UploadsList = ({ uploads }: FindUploads) => { data={uploads} columns={columnDefs} filterableInputs={filterableInputs} + globalFilter={{ + label: 'Only Treasury Files', + checked: showTreasuryFiles, + onChange: onTreasuryFilesChange, + loading: isLoading, + }} /> ) } diff --git a/web/src/components/Upload/UploadsCell/UploadsCell.tsx b/web/src/components/Upload/UploadsCell/UploadsCell.tsx index c3b0b067..58baa085 100644 --- a/web/src/components/Upload/UploadsCell/UploadsCell.tsx +++ b/web/src/components/Upload/UploadsCell/UploadsCell.tsx @@ -1,7 +1,10 @@ +import { useState } from 'react' + import type { FindUploads } from 'types/graphql' import { Link, routes } from '@redwoodjs/router' import type { CellSuccessProps, CellFailureProps } from '@redwoodjs/web' +import { useQuery } from '@redwoodjs/web' import Uploads from 'src/components/Upload/Uploads' @@ -39,6 +42,40 @@ export const QUERY = gql` } ` +export const VALID_UPLOADS_QUERY = gql` + query GetValidUploadsInCurrentPeriod { + getValidUploadsInCurrentPeriod { + id + filename + uploadedBy { + id + email + } + agency { + id + code + } + expenditureCategory { + id + code + } + reportingPeriod { + id + name + } + latestValidation { + id + createdAt + passed + isManual + results + } + createdAt + updatedAt + } + } +` + export const Loading = () =>
Loading...
export const Empty = () => { @@ -57,5 +94,25 @@ export const Failure = ({ error }: CellFailureProps) => ( ) export const Success = ({ uploads }: CellSuccessProps) => { - return + const [showTreasuryFiles, setShowTreasuryFiles] = useState(false) + const { data: validUploadsData, loading: validUploadsLoading } = useQuery( + VALID_UPLOADS_QUERY, + { + skip: !showTreasuryFiles, + } + ) + + const displayedUploads = + showTreasuryFiles && validUploadsData + ? validUploadsData.getValidUploadsInCurrentPeriod + : uploads + + return ( + setShowTreasuryFiles(!showTreasuryFiles)} + isLoading={validUploadsLoading} + /> + ) }