Skip to content

Commit

Permalink
feat: réagencement des éléments #605
Browse files Browse the repository at this point in the history
  • Loading branch information
ocruze committed Feb 10, 2025
1 parent c042763 commit 1f84261
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 118 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const { i18n } = declareComponentKeys<
| { K: "sandbox_datastore_explanation"; R: ReactNode }
| "refresh_datasheet_list"
| { K: "last_refresh_date"; P: { dataUpdatedAt: number }; R: string }
| { K: "nb_results"; P: { nb: number }; R: string }
| "filter_label"
| "filter_placeholder"
| { K: "filter_option"; P: { filter: FilterEnum }; R: string }
Expand Down Expand Up @@ -43,10 +44,13 @@ export const DatasheetListFrTranslations: Translations<"fr">["DatasheetList"] =
),
refresh_datasheet_list: "Rafraîchir",
last_refresh_date: ({ dataUpdatedAt }) => `Données mises à jour le ${formatDateFromISO(new Date(dataUpdatedAt).toISOString())}`,
nb_results: ({ nb }) => `(${nb}) résultats`,
filter_label: "Filtrer",
filter_placeholder: "Sélectionner un filtre",
filter_option: ({ filter }) => {
switch (filter) {
case FilterEnum.ALL:
return "Toutes les fiches";
case FilterEnum.PUBLISHED:
return "Fiches publiées";
case FilterEnum.NOT_PUBLISHED:
Expand All @@ -60,21 +64,21 @@ export const DatasheetListFrTranslations: Translations<"fr">["DatasheetList"] =
sort_option: ({ sort }) => {
switch (sort) {
case SortByEnum.NAME:
return "Nom";
return "Trier par : Nom";
case SortByEnum.NB_SERVICES:
return "Fiches publiées";
return "Trier par : Nombre de services publiés";
default:
return "Tri inconnu";
}
},
sort_order_label: "Trier",
sort_order_placeholder: "Dans l'ordre",
sort_order_label: "Ordre de tri",
sort_order_placeholder: "Ordre",
sort_order_option: ({ sortOrder }) => {
switch (sortOrder) {
case SortOrderEnum.ASCENDING:
return "Croissant";
return "Ordre : Croissant";
case SortOrderEnum.DESCENDING:
return "Décroissant";
return "Ordre : Décroissant";
default:
return "Ordre inconnu";
}
Expand All @@ -91,6 +95,7 @@ export const DatasheetListEnTranslations: Translations<"en">["DatasheetList"] =
sandbox_datastore_explanation: undefined,
refresh_datasheet_list: undefined,
last_refresh_date: undefined,
nb_results: undefined,
filter_label: undefined,
filter_placeholder: undefined,
filter_option: undefined,
Expand Down
222 changes: 110 additions & 112 deletions assets/entrepot/pages/datasheet/DatasheetList/DatasheetList.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { fr } from "@codegouvfr/react-dsfr";
import Alert from "@codegouvfr/react-dsfr/Alert";
import ButtonsGroup from "@codegouvfr/react-dsfr/ButtonsGroup";
import Checkbox from "@codegouvfr/react-dsfr/Checkbox";
import Pagination from "@codegouvfr/react-dsfr/Pagination";
import SearchBar from "@codegouvfr/react-dsfr/SearchBar";
import SelectNext from "@codegouvfr/react-dsfr/SelectNext";
import Tag from "@codegouvfr/react-dsfr/Tag";
import { useQuery } from "@tanstack/react-query";
import { FC, useMemo, useState } from "react";
import { ChangeEvent, FC, useMemo, useState } from "react";

import { Datasheet, EndpointTypeEnum } from "../../../../@types/app";
import Main from "../../../../components/Layout/Main";
Expand Down Expand Up @@ -91,8 +91,18 @@ const DatasheetList: FC<DatasheetListProps> = ({ datastoreId }) => {

const datasheetList = getSortedList(getFilteredList(datasheetListQuery.data ?? [], filters, searchDatasheetName), sort);

function toggleFilter(e: ChangeEvent<HTMLInputElement>): void {
const selectedFilter = Number(e.currentTarget.value);

if (isNaN(selectedFilter) || selectedFilter === 0) return;

setFilters((prev) => (prev.includes(selectedFilter) ? prev.filter((f) => f !== selectedFilter) : [...prev, selectedFilter]));
e.currentTarget.value = "";
routes.datasheet_list({ datastoreId }).replace();
}

return (
<Main title="Mes données">
<Main title={t("title", { datastoreName: datastore?.name })}>
<div className={fr.cx("fr-grid-row")}>
<div className={fr.cx("fr-col-12")}>
<h1>
Expand Down Expand Up @@ -157,128 +167,116 @@ const DatasheetList: FC<DatasheetListProps> = ({ datastoreId }) => {
</div>
</div>

{/* <div className={fr.cx("fr-grid-row", "fr-grid-row--gutters")}>
<div className={fr.cx("fr-col-12", "fr-col-md-4")}>
<Chec
</div>
<div className={fr.cx("fr-col-12", "fr-col-md-4")}></div>
</div> */}

<div className={fr.cx("fr-grid-row", "fr-grid-row--gutters")}>
<div className={fr.cx("fr-col-12", "fr-col-md-4")}>
<SelectNext
label={null}
<div className={fr.cx("fr-grid-row", "fr-grid-row--gutters", "fr-mt-4v")}>
<div className={fr.cx("fr-col-12", "fr-col-sm-4", "fr-col-xl-2")}>
<Checkbox
legend={<strong className={fr.cx("fr-text--xl")}>{t("filter_label")}</strong>}
options={[
{
value: FilterEnum.PUBLISHED.toString(),
label: t("filter_option", { filter: FilterEnum.ALL }),
nativeInputProps: {
value: FilterEnum.ALL.toString(),
checked: filters.length === 0,
onChange: () => {
setFilters([]);
routes.datasheet_list({ datastoreId }).replace();
},
},
},
{
label: t("filter_option", { filter: FilterEnum.PUBLISHED }),
nativeInputProps: {
value: FilterEnum.PUBLISHED.toString(),
checked: filters.includes(FilterEnum.PUBLISHED),
onChange: toggleFilter,
},
},
{
value: FilterEnum.NOT_PUBLISHED.toString(),
label: t("filter_option", { filter: FilterEnum.NOT_PUBLISHED }),
nativeInputProps: {
value: FilterEnum.NOT_PUBLISHED.toString(),
checked: filters.includes(FilterEnum.NOT_PUBLISHED),
onChange: toggleFilter,
},
},
]}
nativeSelectProps={{
"aria-label": t("filter_label"),
onClick: (e) => {
const selectedFilter = Number(e.currentTarget.value);
if (isNaN(selectedFilter) || selectedFilter === 0) return;

setFilters((prev) => (prev.includes(selectedFilter) ? [...prev] : [...prev, selectedFilter]));
e.currentTarget.value = "";
routes.datasheet_list({ datastoreId }).replace();
},
}}
placeholder={t("filter_placeholder")}
/>
</div>
<div className={fr.cx("fr-col-12", "fr-col-md-8")}>
<ul className={fr.cx("fr-tags-group")}>
{filters.map((filter) => (
<li key={filter}>
<Tag
dismissible
nativeButtonProps={{
onClick: () => {
setFilters((prev) => prev.filter((f) => f !== filter));
routes.datasheet_list({ datastoreId }).replace();
},
}}
>
{t("filter_option", { filter: Number(filter) })}
</Tag>
</li>
))}
</ul>
</div>
</div>
<div className={fr.cx("fr-grid-row", "fr-grid-row--gutters", "fr-grid-row--right", "fr-mb-4v")}>
<div className={fr.cx("fr-col-12", "fr-col-sm-8")}>
<SelectNext
label={null}
options={[
{
label: t("sort_option", { sort: SortByEnum.NAME }),
value: SortByEnum.NAME.toString(),
},
{
label: t("sort_option", { sort: SortByEnum.NB_SERVICES }),
value: SortByEnum.NB_SERVICES.toString(),
},
]}
nativeSelectProps={{
"aria-label": t("sort_label"),
value: sort.by.toString(),
onChange: (e) => {
const selectedSortBy = Number(e.currentTarget.value);
<div className={fr.cx("fr-col-12", "fr-col-sm-8", "fr-col-xl-10")}>
<div className={fr.cx("fr-grid-row", "fr-grid-row--gutters", "fr-mb-4v")}>
<div className={fr.cx("fr-col-12", "fr-col-sm-4", "fr-col-md-2", "fr-col--middle")}>
<span className={fr.cx("fr-text--sm")}>{t("nb_results", { nb: datasheetList.length })}</span>
</div>
<div className={fr.cx("fr-col-12", "fr-col-sm", "fr-col-md")}>
<SelectNext
label={null}
options={[
{
label: t("sort_option", { sort: SortByEnum.NAME }),
value: SortByEnum.NAME.toString(),
},
{
label: t("sort_option", { sort: SortByEnum.NB_SERVICES }),
value: SortByEnum.NB_SERVICES.toString(),
},
]}
nativeSelectProps={{
"aria-label": t("sort_label"),
value: sort.by.toString(),
onChange: (e) => {
const selectedSortBy = Number(e.currentTarget.value);

if (isNaN(selectedSortBy) || selectedSortBy === 0) return;
setSort((prev) => ({ ...prev, by: selectedSortBy }));
},
}}
placeholder={t("sort_placeholder")}
/>
</div>
<div className={fr.cx("fr-col-12", "fr-col-sm-4")}>
<SelectNext
label={null}
options={[
{
label: t("sort_order_option", { sortOrder: SortOrderEnum.ASCENDING }),
value: SortOrderEnum.ASCENDING.toString(),
},
{
label: t("sort_order_option", { sortOrder: SortOrderEnum.DESCENDING }),
value: SortOrderEnum.DESCENDING.toString(),
},
]}
nativeSelectProps={{
"aria-label": t("sort_order_label"),
value: sort.order.toString(),
onChange: (e) => {
const selectedSortOrder = Number(e.currentTarget.value);
if (isNaN(selectedSortOrder) || selectedSortOrder === 0) return;
setSort((prev) => ({ ...prev, order: selectedSortOrder }));
},
}}
placeholder={t("sort_order_placeholder")}
/>
</div>
</div>
if (isNaN(selectedSortBy) || selectedSortBy === 0) return;
setSort((prev) => ({ ...prev, by: selectedSortBy }));
},
}}
placeholder={t("sort_placeholder")}
/>
</div>
<div className={fr.cx("fr-col-12", "fr-col-sm", "fr-col-md")}>
<SelectNext
label={null}
options={[
{
label: t("sort_order_option", { sortOrder: SortOrderEnum.ASCENDING }),
value: SortOrderEnum.ASCENDING.toString(),
},
{
label: t("sort_order_option", { sortOrder: SortOrderEnum.DESCENDING }),
value: SortOrderEnum.DESCENDING.toString(),
},
]}
nativeSelectProps={{
"aria-label": t("sort_order_label"),
value: sort.order.toString(),
onChange: (e) => {
const selectedSortOrder = Number(e.currentTarget.value);
if (isNaN(selectedSortOrder) || selectedSortOrder === 0) return;
setSort((prev) => ({ ...prev, order: selectedSortOrder }));
},
}}
placeholder={t("sort_order_placeholder")}
/>
</div>
</div>

{datasheetList
?.slice((pagination.page - 1) * pagination.limit, pagination.page * pagination.limit)
.map((datasheet: Datasheet) => <DatasheetListItem key={datasheet.name} datastoreId={datastoreId} datasheet={datasheet} />)}
<hr className={fr.cx("fr-hr")} />

<div className={fr.cx("fr-grid-row", "fr-grid-row--center", "fr-mt-6v")}>
<Pagination
count={Math.ceil(datasheetList.length / pagination.limit)}
showFirstLast={true}
getPageLinkProps={(pageNumber) => ({
...routes.datasheet_list({ datastoreId, page: pageNumber, limit: pagination.limit }).link,
})}
defaultPage={pagination.page}
/>
{datasheetList
?.slice((pagination.page - 1) * pagination.limit, pagination.page * pagination.limit)
.map((datasheet: Datasheet) => <DatasheetListItem key={datasheet.name} datastoreId={datastoreId} datasheet={datasheet} />)}

<div className={fr.cx("fr-grid-row", "fr-grid-row--center", "fr-mt-6v")}>
<Pagination
count={Math.ceil(datasheetList.length / pagination.limit)}
showFirstLast={true}
getPageLinkProps={(pageNumber) => ({
...routes.datasheet_list({ datastoreId, page: pageNumber, limit: pagination.limit }).link,
})}
defaultPage={pagination.page}
/>
</div>
</div>
</div>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum FilterEnum {
ALL = 0,
PUBLISHED = 1,
NOT_PUBLISHED = 2,
}
Expand Down

0 comments on commit 1f84261

Please sign in to comment.