From 59c3f51bc491a9a6b06aad9f46c42c57fcf0f2b8 Mon Sep 17 00:00:00 2001 From: Lea Renaux Date: Wed, 17 Apr 2024 10:46:45 +0200 Subject: [PATCH] add sort --- src/types/temporaryTypes.ts | 10 ++++ src/ui/FiltersCard.tsx | 4 +- src/ui/HomeTable.tsx | 100 ++++++++++++++++++++++++++++++---- src/ui/HomeTableCard.tsx | 21 ++++--- src/ui/HomeTableRow.tsx | 5 +- src/ui/SelectWithCheckbox.tsx | 4 +- src/ui/TableHeadCell.tsx | 36 +++++++++++- 7 files changed, 150 insertions(+), 30 deletions(-) create mode 100644 src/types/temporaryTypes.ts diff --git a/src/types/temporaryTypes.ts b/src/types/temporaryTypes.ts new file mode 100644 index 0000000..bbc8159 --- /dev/null +++ b/src/types/temporaryTypes.ts @@ -0,0 +1,10 @@ +export type SurveyUnitTemporaryType = { + id: string; + campaignLabel: string; + ssech: number; + interviewer: string; + states: string; + closingCause: string; + contactOutcome: string; + priority: boolean; +}; diff --git a/src/ui/FiltersCard.tsx b/src/ui/FiltersCard.tsx index 9451e5a..3588179 100644 --- a/src/ui/FiltersCard.tsx +++ b/src/ui/FiltersCard.tsx @@ -61,8 +61,8 @@ const surveysMock = [ const subsampleMock = [ { label: "-", value: "undefined" }, - { label: "10", value: "10" }, - { label: "11", value: "11" }, + { label: 10, value: "10" }, + { label: 11, value: "11" }, ]; export const FiltersCard = () => { diff --git a/src/ui/HomeTable.tsx b/src/ui/HomeTable.tsx index bf8fd99..4419edb 100644 --- a/src/ui/HomeTable.tsx +++ b/src/ui/HomeTable.tsx @@ -5,14 +5,79 @@ import { useState } from "react"; import { HomeTableRow } from "./HomeTableRow"; import { TableFooter } from "./TableFooter"; import { theme } from "../theme"; +import { SurveyUnitTemporaryType } from "../types/temporaryTypes"; type Props = { - surveyUnits: Record[]; // TODO change type after backend rework + surveyUnits: SurveyUnitTemporaryType[]; // TODO change type after backend rework }; +const columns = [ + { + columnId: "id", + label: "id", + }, + { + columnId: "campaignLabel", + label: "surveys", + }, + { + columnId: "ssech", + label: "subSample", + }, + { + columnId: "interviewer", + label: "interviewer", + }, + { + columnId: "states", + label: "state", + }, + { + columnId: "closingCause", + label: "closingCause", + }, + { + columnId: "contactOutcome", + label: "contactOutcome", + }, + { + columnId: "priority", + label: "priority", + }, + { + columnId: "actions", + label: "actions", + sort: false, + }, +]; + +function descendingComparator(a: T, b: T, orderBy: keyof T) { + if (b[orderBy] < a[orderBy]) { + return -1; + } + if (b[orderBy] > a[orderBy]) { + return 1; + } + return 0; +} + +function getComparator( + order: "asc" | "desc", + orderBy: Key, +): ( + a: { [key in Key]: number | string | boolean }, + b: { [key in Key]: number | string | boolean }, +) => number { + return order === "desc" + ? (a, b) => descendingComparator(a, b, orderBy) + : (a, b) => -descendingComparator(a, b, orderBy); +} + export const HomeTable = ({ surveyUnits }: Props) => { const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(10); + const [order, setOrder] = useState<"asc" | "desc">("asc"); + const [orderBy, setOrderBy] = useState("id"); const handleChangePage = (_: React.MouseEvent | null, newPage: number) => { setPage(newPage); @@ -22,6 +87,15 @@ export const HomeTable = ({ surveyUnits }: Props) => { setRowsPerPage(parseInt(event.target.value, 10)); setPage(0); }; + + const handleRequestSort = (_: React.MouseEvent, property: string) => { + const isAsc = orderBy === property && order === "asc"; + setOrder(isAsc ? "desc" : "asc"); + setOrderBy(property); + }; + + const sortedRows = surveyUnits.sort(getComparator(order, orderBy)); + return ( @@ -31,24 +105,26 @@ export const HomeTable = ({ surveyUnits }: Props) => { borderBottom: `solid 1px ${theme.palette.text.hint}`, }} > - - - - - - - - - + {columns.map(c => ( + + ))} - {surveyUnits.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map(su => ( + {sortedRows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map(su => ( ))} { }; type FilterSurveyUnitsProps = { - surveyUnits: Record[]; // TODO change type after backend rework + surveyUnits: SurveyUnitTemporaryType[]; // TODO change type after backend rework search?: string; filters: Filter; }; @@ -70,7 +71,7 @@ const filterSurveyUnits = ({ surveyUnits, search, filters }: FilterSurveyUnitsPr (surveyUnits = surveyUnits.filter(item => filters.campaigns.includes(item.campaignLabel))); filters.ssech.length !== 0 && - (surveyUnits = surveyUnits.filter(item => filters.ssech.includes(item.ssech))); + (surveyUnits = surveyUnits.filter(item => filters.ssech.toString().includes(item.ssech.toString()))); filters.interviewer.length !== 0 && (surveyUnits = surveyUnits.filter(item => filters.interviewer.includes(item.interviewer))); @@ -82,7 +83,9 @@ const filterSurveyUnits = ({ surveyUnits, search, filters }: FilterSurveyUnitsPr (surveyUnits = surveyUnits.filter(item => filters.closingCause.includes(item.closingCause))); filters.priority.length !== 0 && - (surveyUnits = surveyUnits.filter(item => filters.priority.includes(item.priority))); + (surveyUnits = surveyUnits.filter(item => + filters.priority.includes(item.priority ? "true" : "false"), + )); return surveyUnits; }; diff --git a/src/ui/HomeTableRow.tsx b/src/ui/HomeTableRow.tsx index 6c39265..5111193 100644 --- a/src/ui/HomeTableRow.tsx +++ b/src/ui/HomeTableRow.tsx @@ -9,9 +9,10 @@ import { Divider, IconButton } from "@mui/material"; import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; import NotInterestedIcon from "@mui/icons-material/NotInterested"; import InsertCommentIcon from "@mui/icons-material/InsertComment"; +import { SurveyUnitTemporaryType } from "../types/temporaryTypes"; type Props = { - surveyUnit: Record; // TODO change type after backend rework + surveyUnit: SurveyUnitTemporaryType; // TODO change type after backend rework }; const StyledTableRow = styled(TableRow)(({ theme }) => ({ @@ -40,7 +41,7 @@ export const HomeTableRow = ({ surveyUnit }: Props) => { {surveyUnit.ssech ?? "-"} {surveyUnit.interviewer} - {intl.formatMessage({ id: surveyUnit.state })} + {intl.formatMessage({ id: surveyUnit.states })} {surveyUnit.closingCause ? intl.formatMessage({ id: surveyUnit.closingCause }) : "-"} diff --git a/src/ui/SelectWithCheckbox.tsx b/src/ui/SelectWithCheckbox.tsx index 27ab276..8e2af78 100644 --- a/src/ui/SelectWithCheckbox.tsx +++ b/src/ui/SelectWithCheckbox.tsx @@ -16,7 +16,7 @@ const style = { }, }; -export type Option = { label: string; value: string }; +export type Option = { label: string | number; value: string }; type Props = { label: string; @@ -110,7 +110,7 @@ export const SelectWithCheckbox = ({ const filterOptions = ({ options, search }: { options: Option[]; search?: string }) => { if (search) { - return options.filter(item => item.label.toLowerCase().includes(search.toLowerCase())); + return options.filter(item => item.label.toString().toLowerCase().includes(search.toLowerCase())); } return options; }; diff --git a/src/ui/TableHeadCell.tsx b/src/ui/TableHeadCell.tsx index 7ec927f..f9ec9db 100644 --- a/src/ui/TableHeadCell.tsx +++ b/src/ui/TableHeadCell.tsx @@ -1,16 +1,46 @@ -import { TableCell as MuiTableCell, TableCellProps } from "@mui/material"; +import { TableCell as MuiTableCell, TableCellProps, TableSortLabel } from "@mui/material"; import { useIntl } from "react-intl"; type Props = { + columnId: string; label: string; + sort?: boolean; + order?: "asc" | "desc"; + orderBy?: string; + onRequestSort?: (event: React.MouseEvent, property: string) => void; } & Pick; -export const TableHeadCell = ({ label, sx }: Props) => { +export const TableHeadCell = ({ + columnId, + label, + sort = true, + order, + orderBy, + onRequestSort, + sx, +}: Props) => { const intl = useIntl(); + const createSortHandler = (property: string) => (event: React.MouseEvent) => { + if (!onRequestSort) { + return; + } + onRequestSort(event, property); + }; + return ( - {intl.formatMessage({ id: label })} + {sort ? ( + + {intl.formatMessage({ id: label })} + + ) : ( + intl.formatMessage({ id: label }) + )} ); };