Skip to content

Commit

Permalink
add sort
Browse files Browse the repository at this point in the history
  • Loading branch information
RenauxLeaInsee committed Apr 17, 2024
1 parent ee4eaa8 commit 59c3f51
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 30 deletions.
10 changes: 10 additions & 0 deletions src/types/temporaryTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export type SurveyUnitTemporaryType = {
id: string;
campaignLabel: string;
ssech: number;
interviewer: string;
states: string;
closingCause: string;
contactOutcome: string;
priority: boolean;
};
4 changes: 2 additions & 2 deletions src/ui/FiltersCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => {
Expand Down
100 changes: 88 additions & 12 deletions src/ui/HomeTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, string>[]; // 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<T>(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<Key extends keyof any>(
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<string>("id");

const handleChangePage = (_: React.MouseEvent<HTMLButtonElement> | null, newPage: number) => {
setPage(newPage);
Expand All @@ -22,6 +87,15 @@ export const HomeTable = ({ surveyUnits }: Props) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};

const handleRequestSort = (_: React.MouseEvent<unknown>, property: string) => {
const isAsc = orderBy === property && order === "asc";
setOrder(isAsc ? "desc" : "asc");
setOrderBy(property);
};

const sortedRows = surveyUnits.sort(getComparator(order, orderBy));

return (
<TableContainer>
<Table aria-label="survey units table" size="small">
Expand All @@ -31,24 +105,26 @@ export const HomeTable = ({ surveyUnits }: Props) => {
borderBottom: `solid 1px ${theme.palette.text.hint}`,
}}
>
<TableHeadCell key={"id"} label={"id"} />
<TableHeadCell key={"campaignLabel"} label={"surveys"} />
<TableHeadCell key={"ssech"} label={"subSample"} />
<TableHeadCell key={"interviewer"} label={"interviewer"} />
<TableHeadCell key={"state"} label={"state"} />
<TableHeadCell key={"closingCause"} label={"closingCause"} />
<TableHeadCell key={"contactOutcome"} label={"contactOutcome"} />
<TableHeadCell key={"priority"} label={"priority"} />
<TableHeadCell key={"actions"} label={"actions"} />
{columns.map(c => (
<TableHeadCell
key={c.label}
columnId={c.columnId}
label={c.label}
sort={c.sort}
order={order}
orderBy={orderBy}
onRequestSort={handleRequestSort}
/>
))}
</TableRow>
</TableHead>
<TableBody>
{surveyUnits.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map(su => (
{sortedRows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map(su => (
<HomeTableRow surveyUnit={su} key={`surveyUnit-${su.id}`} />
))}
</TableBody>
<TableFooter
count={surveyUnits.length}
count={sortedRows.length}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={handleChangePage}
Expand Down
21 changes: 12 additions & 9 deletions src/ui/HomeTableCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,28 @@ import { useIntl } from "react-intl";
import { useDebouncedState } from "../hooks/useDebouncedState";
import { HomeTable } from "./HomeTable";
import { Filter, useGetSearchFilter } from "../hooks/useSearchFilter";
import { SurveyUnitTemporaryType } from "../types/temporaryTypes";

const surveyUnitsMock = [
{
id: "10000000000",
campaignLabel: "Logement",
ssech: "10",
ssech: 10,
interviewer: "enquêteur 1",
state: "état",
states: "état",
closingCause: "ACCEPTED",
contactOutcome: "bilan des contacts",
priority: "true",
priority: true,
},
{
id: "20000000000",
campaignLabel: "Autonomie",
ssech: "2",
ssech: 2,
interviewer: "enquêteur 2",
state: "état 2",
states: "état 2",
closingCause: "WASTE",
contactOutcome: "bilan des contacts 2",
priority: "true",
priority: false,
},
];

Expand All @@ -52,7 +53,7 @@ export const HomeTableCard = () => {
};

type FilterSurveyUnitsProps = {
surveyUnits: Record<string, string>[]; // TODO change type after backend rework
surveyUnits: SurveyUnitTemporaryType[]; // TODO change type after backend rework
search?: string;
filters: Filter;
};
Expand All @@ -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)));
Expand All @@ -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;
};
5 changes: 3 additions & 2 deletions src/ui/HomeTableRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, string>; // TODO change type after backend rework
surveyUnit: SurveyUnitTemporaryType; // TODO change type after backend rework
};

const StyledTableRow = styled(TableRow)(({ theme }) => ({
Expand Down Expand Up @@ -40,7 +41,7 @@ export const HomeTableRow = ({ surveyUnit }: Props) => {
<TableCell sx={{ typography: "itemSmall" }}>{surveyUnit.ssech ?? "-"}</TableCell>
<TableCell sx={{ typography: "itemSmall" }}>{surveyUnit.interviewer}</TableCell>
<TableCell sx={{ typography: "itemSmall" }}>
{intl.formatMessage({ id: surveyUnit.state })}
{intl.formatMessage({ id: surveyUnit.states })}
</TableCell>
<TableCell sx={{ typography: "itemSmall" }}>
{surveyUnit.closingCause ? intl.formatMessage({ id: surveyUnit.closingCause }) : "-"}
Expand Down
4 changes: 2 additions & 2 deletions src/ui/SelectWithCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
};
36 changes: 33 additions & 3 deletions src/ui/TableHeadCell.tsx
Original file line number Diff line number Diff line change
@@ -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<unknown>, property: string) => void;
} & Pick<TableCellProps, "sx">;

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<unknown>) => {
if (!onRequestSort) {
return;
}
onRequestSort(event, property);
};

return (
<MuiTableCell sx={{ ...sx, typography: "titleSmall", pb: 2 }}>
{intl.formatMessage({ id: label })}
{sort ? (
<TableSortLabel
active={orderBy === columnId}
direction={orderBy === columnId ? order : "asc"}
onClick={createSortHandler(columnId)}
>
{intl.formatMessage({ id: label })}
</TableSortLabel>
) : (
intl.formatMessage({ id: label })
)}
</MuiTableCell>
);
};

0 comments on commit 59c3f51

Please sign in to comment.