Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPF-492 Add "Only Treasury Uploads" filter #504

Merged
merged 6 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/src/graphql/uploads.sdl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const schema = gql`
type Query {
uploads: [Upload!]! @requireAuth
upload(id: Int!): Upload @requireAuth
getValidUploadsInCurrentPeriod: [Upload!]! @requireAuth
}

input CreateUploadInput {
Expand Down
1 change: 1 addition & 0 deletions api/src/services/uploads/uploads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const uploads: QueryResolvers['uploads'] = () => {

return db.upload.findMany({
where: whereInputs,
orderBy: { createdAt: 'desc' },
})
}

Expand Down
66 changes: 47 additions & 19 deletions web/src/components/TableBuilder/TableBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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<ColumnFiltersState>([])
const [sorting, setSorting] = useState([])

Expand All @@ -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 (
<tr className="border">
<td colSpan={100} className="text-center py-4">
<span className="text-muted">No results found</span>
</td>
</tr>
)
}

return rows.map((row) => <TableRow row={row} key={row.id} />)
}

return (
<div className="p-2">
<Table striped borderless>
<thead>
{!!filterableInputs.length && (
{(!!filterableInputs.length || globalFilter) && (
<tr className="border">
<th className="text-end" colSpan={100}>
<Button
className="btn btn-secondary"
size="sm"
onClick={resetColumnFilters}
>
Reset filters
</Button>
</th>
<td colSpan={100} className="text-end pe-2">
<div className="d-inline-flex align-items-center gap-3">
{globalFilter && (
<Form.Check
type="checkbox"
id="treasury-files-filter"
label={globalFilter.label}
checked={globalFilter.checked}
onChange={globalFilter.onChange}
disabled={globalFilter.loading}
className="mb-0"
/>
)}
<Button
className="btn btn-secondary"
size="sm"
onClick={resetFilters}
>
Reset filters
</Button>
</div>
</td>
</tr>
)}
{table.getHeaderGroups().map((headerGroup) => (
Expand All @@ -65,11 +97,7 @@ function TableBuilder({ data, columns, filterableInputs = [] }) {
/>
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
<TableRow row={row} key={row.id} />
))}
</tbody>
<tbody>{renderTableBody()}</tbody>
</Table>
</div>
)
Expand Down
20 changes: 19 additions & 1 deletion web/src/components/Upload/Uploads/Uploads.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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,
}}
/>
)
}
Expand Down
59 changes: 58 additions & 1 deletion web/src/components/Upload/UploadsCell/UploadsCell.tsx
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -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 = () => <div>Loading...</div>

export const Empty = () => {
Expand All @@ -57,5 +94,25 @@ export const Failure = ({ error }: CellFailureProps) => (
)

export const Success = ({ uploads }: CellSuccessProps<FindUploads>) => {
return <Uploads uploads={uploads} />
const [showTreasuryFiles, setShowTreasuryFiles] = useState(false)
const { data: validUploadsData, loading: validUploadsLoading } = useQuery(
VALID_UPLOADS_QUERY,
{
skip: !showTreasuryFiles,
}
)

const displayedUploads =
showTreasuryFiles && validUploadsData
? validUploadsData.getValidUploadsInCurrentPeriod
: uploads

return (
<Uploads
uploads={displayedUploads}
showTreasuryFiles={showTreasuryFiles}
onTreasuryFilesChange={() => setShowTreasuryFiles(!showTreasuryFiles)}
isLoading={validUploadsLoading}
/>
)
}
Loading