Skip to content

Commit

Permalink
feat(j-s): Sort cases by IndictmentAppealDeadline (#15336)
Browse files Browse the repository at this point in the history
* Checkpoint

* Checkpoint

* Sort now works

* Testing sort now works with existing sorting mechanims

* Cleanup

* sortableTableColumn now has better types

* Fix build errors

* Checkpoint

* Tests correct

* Refactor

* Fix lint

* Revert RTL update

* Revert RTL update

* Revert RTL update

* Use better types

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
2 people authored and sigruntg committed Jun 27, 2024
1 parent 2644044 commit 553f52e
Show file tree
Hide file tree
Showing 17 changed files with 204 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const AppealCasesTable: React.FC<Props> = (props) => {
},
{
title: capitalize(formatMessage(core.defendant, { suffix: 'i' })),
sortable: { isSortable: true, key: 'defendant' },
sortable: { isSortable: true, key: 'defendants' },
},
{
title: formatMessage(tables.type),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const PastCasesTable: React.FC<React.PropsWithChildren<Props>> = (props) => {
const { isOpeningCaseId, handleOpenCase, LoadingIndicator, showLoading } =
useCaseList()
const { sortedData, requestSort, getClassNamesFor, isActiveColumn } =
useSortCases('createdAt', 'descending', cases)
useSortCases('created', 'descending', cases)

const {
withdrawAppealMenuOption,
Expand Down Expand Up @@ -108,10 +108,10 @@ const PastCasesTable: React.FC<React.PropsWithChildren<Props>> = (props) => {
title={capitalize(
formatMessage(core.defendant, { suffix: 'i' }),
)}
onClick={() => requestSort('defendant')}
sortAsc={getClassNamesFor('defendant') === 'ascending'}
sortDes={getClassNamesFor('defendant') === 'descending'}
isActive={isActiveColumn('defendant')}
onClick={() => requestSort('defendants')}
sortAsc={getClassNamesFor('defendants') === 'ascending'}
sortDes={getClassNamesFor('defendants') === 'descending'}
isActive={isActiveColumn('defendants')}
/>
</th>
<TableHeaderText title={formatMessage(tables.type)} />
Expand All @@ -120,10 +120,10 @@ const PastCasesTable: React.FC<React.PropsWithChildren<Props>> = (props) => {
title={capitalize(
formatMessage(tables.created, { suffix: 'i' }),
)}
onClick={() => requestSort('createdAt')}
sortAsc={getClassNamesFor('createdAt') === 'ascending'}
sortDes={getClassNamesFor('createdAt') === 'descending'}
isActive={isActiveColumn('createdAt')}
onClick={() => requestSort('created')}
sortAsc={getClassNamesFor('created') === 'ascending'}
sortDes={getClassNamesFor('created') === 'descending'}
isActive={isActiveColumn('created')}
/>
</th>
<TableHeaderText title={formatMessage(tables.state)} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const SortButton: React.FC<Props> = (props) => {
>
<Icon icon="caretDown" size="small" />
</Box>
<p className="visually-hidden">Sort button</p>
</Box>
)
}
Expand Down
91 changes: 91 additions & 0 deletions apps/judicial-system/web/src/components/Table/Table.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import faker from 'faker'
import { act, render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

import { CaseListEntry } from '@island.is/judicial-system-web/src/graphql/schema'
import {
ApolloProviderWrapper,
IntlProviderWrapper,
} from '@island.is/judicial-system-web/src/utils/testHelpers'

import { sortableTableColumn } from '../../types'
import Table from './Table'

import '@testing-library/react'

jest.mock('next/router', () => ({
useRouter() {
return {
pathname: '',
query: {
id: 'test_id',
},
}
},
}))

describe('Table', () => {
it('should sort by deadline', async () => {
const user = userEvent.setup()

const thead = [
{
title: 'Title',
sortable: {
isSortable: true,
key: 'indictmentAppealDeadline' as sortableTableColumn,
},
},
]

const data: CaseListEntry[] = [
{
created: '2021-01-01T00:00:00Z',
id: faker.datatype.uuid(),
indictmentAppealDeadline: '2021-01-01T00:00:00Z',
},
{
created: '2021-01-02T00:00:00Z',
id: faker.datatype.uuid(),
indictmentAppealDeadline: '2021-01-02T00:00:00Z',
},
]

const columns = [
{
cell: (row: CaseListEntry) => <p>{row.indictmentAppealDeadline}</p>,
},
]

render(
<IntlProviderWrapper>
<ApolloProviderWrapper>
<Table thead={thead} data={data} columns={columns} />
</ApolloProviderWrapper>
</IntlProviderWrapper>,
)

await act(async () => {
await user.click(
await screen.findByTestId('indictmentAppealDeadlineSortButton'),
)
})

const tableRows = await screen.findAllByTestId('tableRow')

// The first click sorts by ascending order, so the first row should be the one with the earliest date
expect(tableRows[0]).toHaveTextContent('2021-01-01T00:00:00Z')
expect(tableRows[1]).toHaveTextContent('2021-01-02T00:00:00Z')

await act(async () => {
await user.click(
await screen.findByTestId('indictmentAppealDeadlineSortButton'),
)
})

// The second click sorts by descending order, so the first row should be the one with the latest date
const tableRows2 = await screen.findAllByTestId('tableRow')
expect(tableRows2[0]).toHaveTextContent('2021-01-02T00:00:00Z')
expect(tableRows2[1]).toHaveTextContent('2021-01-01T00:00:00Z')
})
})
39 changes: 24 additions & 15 deletions apps/judicial-system/web/src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import React, { PropsWithChildren, ReactNode, useContext, useMemo } from 'react'
import React, {
FC,
PropsWithChildren,
ReactNode,
useContext,
useMemo,
} from 'react'
import { useIntl } from 'react-intl'
import { useLocalStorage } from 'react-use'
import parseISO from 'date-fns/parseISO'
Expand All @@ -23,13 +29,15 @@ import TableSkeleton from './TableSkeleton/TableSkeleton'
import { table as strings } from './Table.strings'
import * as styles from './Table.css'

interface Sortable {
isSortable: boolean
key: sortableTableColumn
}

interface TableProps {
thead: {
title: string
sortable?: {
isSortable: boolean
key: sortableTableColumn
}
sortable?: Sortable
}[]
data: CaseListEntry[]
columns: { cell: (row: CaseListEntry) => ReactNode }[]
Expand All @@ -41,7 +49,7 @@ interface TableWrapperProps {
loading: boolean
}

export const TableWrapper: React.FC<PropsWithChildren<TableWrapperProps>> = ({
export const TableWrapper: FC<PropsWithChildren<TableWrapperProps>> = ({
loading,
children,
}) => (
Expand Down Expand Up @@ -80,7 +88,7 @@ export const useTable = () => {
return { requestSort, getClassNamesFor, sortConfig, setSortConfig }
}

const Table: React.FC<TableProps> = (props) => {
const Table: FC<TableProps> = (props) => {
const { thead, data, columns, generateContextMenuItems, onClick } = props
const { isOpeningCaseId, handleOpenCase, LoadingIndicator, showLoading } =
useCaseList()
Expand All @@ -95,17 +103,17 @@ const Table: React.FC<TableProps> = (props) => {
data.sort((a: CaseListEntry, b: CaseListEntry) => {
const getColumnValue = (entry: CaseListEntry) => {
if (
sortConfig.column === 'defendant' &&
sortConfig.column === 'defendants' &&
entry.defendants &&
entry.defendants.length > 0
entry.defendants.length > 0 &&
entry.defendants[0].name
) {
return entry.defendants[0].name ?? ''
return entry.defendants[0].name
}
if (sortConfig.column === 'courtDate') {
return entry.courtDate ?? ''
}
return entry.created

return entry[sortConfig.column]?.toString()
}

const compareResult = compareLocaleIS(
getColumnValue(a),
getColumnValue(b),
Expand Down Expand Up @@ -169,7 +177,7 @@ const Table: React.FC<TableProps> = (props) => {
sortAsc={getClassNamesFor(th.sortable.key) === 'ascending'}
sortDes={getClassNamesFor(th.sortable.key) === 'descending'}
isActive={sortConfig?.column === th.sortable.key}
dataTestid="accusedNameSortButton"
dataTestid={`${th.sortable.key}SortButton`}
/>
) : (
<Text as="span" fontWeight="regular">
Expand All @@ -194,6 +202,7 @@ const Table: React.FC<TableProps> = (props) => {
handleOpenCase(row.id)
}
}}
data-testid="tableRow"
>
{columns.map((td) => (
<td key={`${td}-${columns.indexOf(td)}`} className={styles.td}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const CasesAwaitingAssignmentTable: React.FC<
title: capitalize(
formatMessage(core.defendant, { suffix: 'i' }),
),
sortable: { isSortable: true, key: 'defendant' },
sortable: { isSortable: true, key: 'defendants' },
},
{
title: formatMessage(tables.type),
Expand All @@ -60,7 +60,7 @@ const CasesAwaitingAssignmentTable: React.FC<
title: capitalize(
formatMessage(tables.created, { suffix: 'i' }),
),
sortable: { isSortable: true, key: 'createdAt' },
sortable: { isSortable: true, key: 'created' },
},
{ title: formatMessage(tables.state) },
]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ const CasesInProgressTable: FC<CasesInProgressTableProps> = (props) => {
title: capitalize(
formatMessage(core.defendant, { suffix: 'i' }),
),
sortable: { isSortable: true, key: 'defendant' },
sortable: { isSortable: true, key: 'defendants' },
},
{ title: formatMessage(tables.type) },
{
title: capitalize(
formatMessage(tables.created, { suffix: 'i' }),
),
sortable: { isSortable: true, key: 'createdAt' },
sortable: { isSortable: true, key: 'created' },
},
{ title: formatMessage(tables.state) },
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const DefenderCasesTable: React.FC<React.PropsWithChildren<Props>> = (
const { formatMessage } = useIntl()
const { cases, showingCompletedCases, loading } = props
const { sortedData, requestSort, getClassNamesFor, isActiveColumn } =
useSortCases('createdAt', 'descending', cases)
useSortCases('created', 'descending', cases)
const { isOpeningCaseId, LoadingIndicator, showLoading, handleOpenCase } =
useCaseList()

Expand Down Expand Up @@ -74,10 +74,10 @@ export const DefenderCasesTable: React.FC<React.PropsWithChildren<Props>> = (
title={capitalize(
formatMessage(core.defendant, { suffix: 'i' }),
)}
onClick={() => requestSort('defendant')}
sortAsc={getClassNamesFor('defendant') === 'ascending'}
sortDes={getClassNamesFor('defendant') === 'descending'}
isActive={isActiveColumn('defendant')}
onClick={() => requestSort('defendants')}
sortAsc={getClassNamesFor('defendants') === 'ascending'}
sortDes={getClassNamesFor('defendants') === 'descending'}
isActive={isActiveColumn('defendants')}
dataTestid="accusedNameSortButton"
/>
</th>
Expand All @@ -91,10 +91,10 @@ export const DefenderCasesTable: React.FC<React.PropsWithChildren<Props>> = (
title={capitalize(
formatMessage(tables.created, { suffix: 'i' }),
)}
onClick={() => requestSort('createdAt')}
sortAsc={getClassNamesFor('createdAt') === 'ascending'}
sortDes={getClassNamesFor('createdAt') === 'descending'}
isActive={isActiveColumn('createdAt')}
onClick={() => requestSort('created')}
sortAsc={getClassNamesFor('created') === 'ascending'}
sortDes={getClassNamesFor('created') === 'descending'}
isActive={isActiveColumn('created')}
/>
</th>
<th className={cn(styles.th, styles.largeColumn)}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ const CasesAwaitingConfirmationTable: React.FC<
title: capitalize(
formatMessage(core.defendant, { suffix: 'i' }),
),
sortable: { isSortable: true, key: 'defendant' },
sortable: { isSortable: true, key: 'defendants' },
},
{
title: formatMessage(tables.type),
},
{
title: capitalize(formatMessage(tables.created)),
sortable: { isSortable: true, key: 'createdAt' },
sortable: { isSortable: true, key: 'created' },
},
{ title: formatMessage(tables.state) },
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,16 @@ const CasesForReview: React.FC<CasesForReviewTableProps> = ({
title: capitalize(
formatMessage(core.defendant, { suffix: 'i' }),
),
sortable: { isSortable: true, key: 'defendant' },
sortable: { isSortable: true, key: 'defendants' },
},
{ title: formatMessage(tables.state) },
{ title: formatMessage(tables.deadline) },
{
title: formatMessage(tables.deadline),
sortable: {
isSortable: true,
key: 'indictmentAppealDeadline',
},
},
]}
data={cases}
generateContextMenuItems={(row) => {
Expand Down
Loading

0 comments on commit 553f52e

Please sign in to comment.