Skip to content

Commit

Permalink
feat: Sort search result (#351)
Browse files Browse the repository at this point in the history
* chore: add pgadmin

* chore: fix key

* chore: missing keys

* chore: typo

* chore: numeric user

* chore: secret

* chore: containerPort

* chore: auth

* chore: probespath

* feat: add sort search result

* fix order search result

* fix order search result

* fix order search result

* fix order search result

* fix order search result

---------

Co-authored-by: Gary van Woerkens <gary.van-woerkens@sg.social.gouv.fr>
Co-authored-by: Matéo Mévollon <m.mevollon@proton.me>
  • Loading branch information
3 people authored Sep 25, 2024
1 parent 1169393 commit f4d2f0b
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 58 deletions.
8 changes: 7 additions & 1 deletion src/client/src/components/Search/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const Search = ({
searchTerm,
setSearchTerm,
resetSearch,
resetSort,
handlePageChange,
addFilter,
removeFilter,
Expand Down Expand Up @@ -94,7 +95,10 @@ const Search = ({
setSearchTerm={setSearchTerm}
resetSearch={resetSearch}
isLoading={isLoading}
onEnterPress={() => sendRequest(searchTerm, options)}
onEnterPress={() => {
resetSort();
sendRequest(searchTerm, options);
}}
/>
</div>
<div className="column is-3 ">
Expand All @@ -105,6 +109,7 @@ const Search = ({
})}
onClick={(e) => {
e.preventDefault();
resetSort();
sendRequest(searchTerm, options);
}}
>
Expand Down Expand Up @@ -257,6 +262,7 @@ Search.propTypes = {
removeFilter: PropTypes.func.isRequired,
removeFilters: PropTypes.func.isRequired,
resetSearch: PropTypes.func.isRequired,
resetSort: PropTypes.func.isRequired,
results: PropTypes.array,
searchTerm: PropTypes.string.isRequired,
sendRequest: PropTypes.func.isRequired,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import "./awesomeTable.scss";

import {
faSort,
faSortDown,
faSortUp,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import classNames from "classnames";
import PropTypes from "prop-types";
import React from "react";
Expand All @@ -9,6 +15,12 @@ import LeftArrow from "../shared/Icons/LeftArrow.jsx";
import RightArrow from "../shared/Icons/RightArrow.jsx";
import LoadSpinner from "../shared/LoadSpinner";

const getSortIcon = (field, sortField, sortDirection) => {
if (field === sortField) {
return sortDirection === "asc" ? faSortDown : faSortUp;
}
return faSort;
};
const SearchAwesomeTable = ({
showPagination = false,
pagination,
Expand All @@ -17,6 +29,10 @@ const SearchAwesomeTable = ({
isLoading = false,
data,
fields,
// isSortable = true,
sortColumn,
sortField,
sortDirection,
}) => {
const handleRowClick = (event, element) => {
if (event.target.tagName === "A") {
Expand All @@ -29,9 +45,23 @@ const SearchAwesomeTable = ({
<thead className="at__head">
<tr className="at__head__tr">
{fields.map((field) => {
const isSortableField = field.sortKey;
return (
<th key={field.headName} className="at__head__th">
<th
key={field.headName}
className={classNames({
at__head__th: true,
"at__head__th--important": field.importantHead,
"at__head__th--is-sortable": !!isSortableField,
})}
onClick={() => isSortableField && sortColumn(field.sortKey)}
>
{field.headName}
{isSortableField && (
<FontAwesomeIcon
icon={getSortIcon(field.sortKey, sortField, sortDirection)}
/>
)}
</th>
);
})}
Expand Down
14 changes: 4 additions & 10 deletions src/client/src/components/SearchResults/SearchResults.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,7 @@ const SearchResults = ({
});
},
headName: "SIRET",
importantHead: true,
link: ({ siret }) => `/establishment/${siret}`,
sortKey: "siret",
},
{
accessor: ({ etatAdministratifEtablissement, siret }) => {
Expand All @@ -130,7 +128,7 @@ const SearchResults = ({
});
},
headName: "État",
sortKey: "etatadministratifetablissement",
sortKey: "etatAdministratifEtablissement",
},
{
accessor: (etablissement) => {
Expand All @@ -140,7 +138,6 @@ const SearchResults = ({
},
headName: "Raison sociale / Nom",
html: true,
sortKey: "enterprise_name",
},
{
accessor: (fields) => {
Expand Down Expand Up @@ -172,10 +169,8 @@ const SearchResults = ({
},

headName: "Dirigeants",
importantHead: true,
link: ({ fields }) =>
`/enterprise/${fields?.siren}#mandataires`,
sortKey: "dirigeants",
},
{
accessor: ({ etablissementSiege }) => {
Expand All @@ -186,7 +181,6 @@ const SearchResults = ({
});
},
headName: "Catégorie établissement",
sortKey: "etablissementsiege",
},
{
accessor: ({
Expand All @@ -201,8 +195,8 @@ const SearchResults = ({
});
},
headName: "Code postal",
sortKey: "codepostaletablissement",
},

{
accessor: ({
trancheEffectifsEtablissement,
Expand All @@ -222,7 +216,7 @@ const SearchResults = ({
});
},
headName: "Effectif (DSN)",
sortKey: "lastdsntrancheeffectifsetablissement",
sortKey: "trancheEffectifsEtablissement",
},
{
accessor: ({
Expand All @@ -239,7 +233,7 @@ const SearchResults = ({
);
},
headName: "Activité",
sortKey: "activiteprincipaleetablissement",
sortKey: "codeActivitePrincipale",
},
]}
/>
Expand Down
38 changes: 31 additions & 7 deletions src/client/src/containers/Search/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { groupBy, omit } from "lodash";
import { prop } from "lodash/fp";
import moment from "moment";
import React, { useEffect } from "react";
import { useSelector } from "react-redux";

import SearchView from "../../components/Search";
import Http from "../../services/Http";
import {
useResetSearch,
useResetSort,
useSearchFilters,
useSearchPage,
useSearchQuery,
Expand All @@ -23,7 +25,7 @@ const PAGE_SIZE = 10;
const XLSX_DOC_TYPE =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

const formatLocationFilter = (filters) => {
const formatLocationFilter = (filters, sortDirection, sortField) => {
const locationFilters = groupBy(filters.location, "type");
const codesCommunes = locationFilters?.commune?.map(prop("value")) || [];
const departements = [
Expand All @@ -32,39 +34,52 @@ const formatLocationFilter = (filters) => {
regionItem.regions.map((region) => region.value)
) || []),
];

return {
...omit(filters, "location"),
codesCommunes: normalizeCodeCommunes(codesCommunes),
departements,

sortField: sortField,
sortOrder: sortDirection,
};
};

const Search = () => {
const [searchQuery, setSearchQuery] = useSearchTerms();
const [searchPage, setSearchPage] = useSearchPage();
const sortFieldFromStore = useSelector(
(state) => state?.search?.sort?.sortField
);

const sortOrderFromStore = useSelector(
(state) => state?.search?.sort?.sortOrder
);

const { filters, addFilter, removeFilter, removeFilters } =
useSearchFilters();
const { sortField, sortDirection, toggleSortField } = useSort();

const { data, loading, error, makeQuery, query } = useSearchQuery();
const resetSearch = useResetSearch();

const resetSort = useResetSort();
useEffect(() => {
if (searchQuery) {
onSearch();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [sortField, sortDirection]);

const downloadQuery = async () => {
const trimmedQuery = searchQuery?.trim();

const response = await Http.get("/downloadXlsx", {
params: {
q: trimmedQuery,
...formatLocationFilter(filters),
...formatLocationFilter(
filters,
sortOrderFromStore != null ? sortDirection : null,
sortFieldFromStore != null ? sortField : null
),
},
responseType: "blob",
});
Expand All @@ -89,15 +104,23 @@ const Search = () => {
setSearchPage(nextCurrentPage);
makeQuery(searchQuery, {
page: { current: nextCurrentPage - 1, size: PAGE_SIZE },
params: formatLocationFilter(filters),
params: formatLocationFilter(
filters,
sortOrderFromStore != null ? sortDirection : null,
sortFieldFromStore != null ? sortField : null
),
});
};

const onSearch = () => {
setSearchPage(1);
makeQuery(searchQuery, {
page: { current: 0, size: PAGE_SIZE },
params: formatLocationFilter(filters),
params: formatLocationFilter(
filters,
sortOrderFromStore != null ? sortDirection : null,
sortFieldFromStore != null ? sortField : null
),
});
};

Expand All @@ -114,6 +137,7 @@ const Search = () => {
searchTerm={searchQuery || ""}
setSearchTerm={setSearchQuery}
resetSearch={resetSearch}
resetSort={resetSort}
handlePageChange={handlePageChange}
addFilter={addFilter}
removeFilter={removeFilter}
Expand Down
18 changes: 18 additions & 0 deletions src/client/src/services/Store/actions/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ export const setSearchTerm = (term) => (dispatch) => {
type: types.SET_SEARCH_TERM,
});
};
export const setSearchSortOrder = (sortOrder) => (dispatch) => {
dispatch({
sortOrder,
type: types.SET_SEARCH_SORT_ORDER,
});
};
export const setSearchSortField = (sortField) => (dispatch) => {
dispatch({
sortField,
type: types.SET_SEARCH_SORT_FIELD,
});
};

export const setSearchPage = (page) => (dispatch) => {
dispatch({
Expand Down Expand Up @@ -33,3 +45,9 @@ export const resetSearch = () => (dispatch) => {
type: types.RESET_SEARCH,
});
};

export const resetSort = () => (dispatch) => {
dispatch({
type: types.RESET_SORT,
});
};
3 changes: 3 additions & 0 deletions src/client/src/services/Store/constants/ActionTypes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
export const SET_SEARCH_TERM = "SET_SEARCH_TERM";
export const SET_SEARCH_SORT_ORDER = "SET_SEARCH_SORT_ORDER";
export const SET_SEARCH_SORT_FIELD = "SET_SEARCH_SORT_FIELD";
export const SET_SEARCH_PAGE = "SET_SEARCH_PAGE";
export const SET_SEARCH_FILTERS = "SET_SEARCH_FILTERS";
export const SET_SEARCH_SORT = "SET_SEARCH_SORT";
export const SET_SEARCH_RESULTS = "SET_SEARCH_RESULTS";
export const RESET_SEARCH = "RESET_SEARCH";
export const RESET_SORT = "RESET_SORT";
21 changes: 20 additions & 1 deletion src/client/src/services/Store/hooks/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import { useDispatch, useSelector } from "react-redux";
import { useElasticQuery } from "../../Elastic/elastic";
import {
resetSearch,
resetSort,
setSearchFilters,
setSearchPage as setSearchPageAction,
setSearchResults,
setSearchSortField as setSearchSortFieldAction,
setSearchSortOrder as setSearchSortOrderAction,
setSearchTerm as setSearchTermAction,
} from "../actions";

Expand All @@ -23,6 +26,17 @@ export const useSearchTerms = () => {

return [searchTerm, setSearchTerm];
};
export const useSearchSortTerms = () => {
const dispatch = useDispatch();
const setSearchSortOrder = (term) => {
dispatch(setSearchSortOrderAction(term));
};
const setSearchSortField = (term) => {
dispatch(setSearchSortFieldAction(term));
};

return [setSearchSortOrder, setSearchSortField];
};

export const useSearchPage = () => {
const dispatch = useDispatch();
Expand All @@ -39,12 +53,12 @@ export const useSearchFilters = () => {
const dispatch = useDispatch();
const savedFilters = useSelector((state) => getSearchState(state).filters);
// cache busting mechanism

const validFilters = savedFilters.etats
? savedFilters
: {
etats: ["A"],
};

const addFilter = (key, value) => {
dispatch(setSearchFilters({ ...savedFilters, [key]: value }));
};
Expand Down Expand Up @@ -104,3 +118,8 @@ export const useResetSearch = () => {

return () => dispatch(resetSearch());
};
export const useResetSort = () => {
const dispatch = useDispatch();

return () => dispatch(resetSort());
};
Loading

0 comments on commit f4d2f0b

Please sign in to comment.