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

feat(j-s): Sort cases by IndictmentAppealDeadline #15336

Merged
merged 24 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
edaaa2b
Checkpoint
oddsson Jun 20, 2024
031895a
Merge branch 'main' of github.com:island-is/island.is into j-s/deadli…
oddsson Jun 20, 2024
693799a
Merge branch 'main' of github.com:island-is/island.is into j-s/deadli…
oddsson Jun 21, 2024
6eff5a0
Merge branch 'j-s/deadline-sort' of github.com:island-is/island.is in…
oddsson Jun 21, 2024
ea51faf
Checkpoint
oddsson Jun 21, 2024
565823c
Sort now works
oddsson Jun 24, 2024
9597195
Merge branch 'main' of github.com:island-is/island.is into j-s/deadli…
oddsson Jun 24, 2024
fdaa42b
Testing sort now works with existing sorting mechanims
oddsson Jun 24, 2024
50a0359
Cleanup
oddsson Jun 24, 2024
83a2caa
sortableTableColumn now has better types
oddsson Jun 24, 2024
fade5c3
Fix build errors
oddsson Jun 24, 2024
da77b8a
Checkpoint
oddsson Jun 24, 2024
6706da9
Tests correct
oddsson Jun 24, 2024
e960fa1
Refactor
oddsson Jun 24, 2024
b72b192
Fix lint
oddsson Jun 24, 2024
68e5c80
Merge branch 'main' of github.com:island-is/island.is into j-s/deadli…
oddsson Jun 25, 2024
9bbeb01
Revert RTL update
oddsson Jun 25, 2024
51431ef
Revert RTL update
oddsson Jun 25, 2024
aa6b30a
Revert RTL update
oddsson Jun 25, 2024
3512ce8
Merge branch 'main' of github.com:island-is/island.is into j-s/deadli…
oddsson Jun 25, 2024
dfc8aab
Use better types
oddsson Jun 25, 2024
76f2042
Merge branch 'main' of github.com:island-is/island.is into j-s/deadli…
oddsson Jun 25, 2024
8c0493d
Merge branch 'main' into j-s/deadline-sort
oddsson Jun 26, 2024
7c534d5
Merge branch 'main' into j-s/deadline-sort
kodiakhq[bot] Jun 26, 2024
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
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' },
oddsson marked this conversation as resolved.
Show resolved Hide resolved
},
{
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')}
oddsson marked this conversation as resolved.
Show resolved Hide resolved
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')}
oddsson marked this conversation as resolved.
Show resolved Hide resolved
/>
</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
Loading