From 697d0d48f3e665a9c2b059905cc0d90d5f5f8d5c Mon Sep 17 00:00:00 2001 From: Mihoub Date: Mon, 1 Jul 2024 10:28:46 +0200 Subject: [PATCH] fix(search): add dismissible tag of query and show contribution ID --- src/api/utils/buildURL.tsx | 19 +++-- .../contribution-production-card.tsx | 2 +- .../link-publications/index.tsx | 52 +++++++++++--- .../contribution-page/contribution-item.tsx | 4 +- src/pages/contribution-page/index.tsx | 69 ++++++++++++++----- 5 files changed, 113 insertions(+), 33 deletions(-) diff --git a/src/api/utils/buildURL.tsx b/src/api/utils/buildURL.tsx index 18e418b..b3962a7 100644 --- a/src/api/utils/buildURL.tsx +++ b/src/api/utils/buildURL.tsx @@ -10,18 +10,29 @@ export const buildURL = ( const baseApiUrl = isDevelopment ? "https://scanr-api.dataesr.ovh" : "/api"; let baseUrl = "contact"; - if (location?.pathname?.includes("contributionpage")) { baseUrl = "contribute"; } else if (location?.pathname?.includes("apioperations")) { baseUrl = "contribute_productions"; } + const sorted = sort === "ASC" ? "sort=created_at" : "sort=-created_at"; + const where: any = {}; if (query.trim() !== "") { - where.$or = [{ name: { $regex: `.*${query}.*`, $options: "i" } }]; - if (searchInMessages) { - where.$or.push({ message: { $regex: `.*${query}.*`, $options: "i" } }); + const isObjectId = /^[0-9a-fA-F]{24}$/.test(query); + + if (isObjectId) { + where._id = query; + } else { + where.$or = [ + { name: { $regex: `.*${query}.*`, $options: "i" } }, + { _id: { $regex: `.*${query}.*`, $options: "i" } }, + ]; + + if (searchInMessages) { + where.$or.push({ message: { $regex: `.*${query}.*`, $options: "i" } }); + } } } diff --git a/src/pages/api-operation-page/link-publications/contribution-production-card.tsx b/src/pages/api-operation-page/link-publications/contribution-production-card.tsx index 22a0edd..fe7d2ae 100644 --- a/src/pages/api-operation-page/link-publications/contribution-production-card.tsx +++ b/src/pages/api-operation-page/link-publications/contribution-production-card.tsx @@ -56,7 +56,7 @@ const ContributionProductionItem = ({ - {data.name} + {data.name} ({data?._id}) diff --git a/src/pages/api-operation-page/link-publications/index.tsx b/src/pages/api-operation-page/link-publications/index.tsx index b750e63..c978c09 100644 --- a/src/pages/api-operation-page/link-publications/index.tsx +++ b/src/pages/api-operation-page/link-publications/index.tsx @@ -2,6 +2,7 @@ import { useState, useEffect } from "react"; import { Col, Container, + DismissibleTag, Row, SearchBar, Text, @@ -22,7 +23,7 @@ const ContributionPage: React.FC = () => { const [reload] = useState(0); const [sort, setSort] = useState("DESC"); const [status, setStatus] = useState("new"); - const [query, setQuery] = useState(""); + const [query, setQuery] = useState([]); const [page, setPage] = useState(1); const [, setData] = useState(null); const location = useLocation(); @@ -31,13 +32,14 @@ const ContributionPage: React.FC = () => { useEffect(() => { const params = new URLSearchParams(location.search); setPage(parseInt(params.get("page") || "1")); - setQuery(params.get("query") || ""); + const queryParam = params.get("query") || ""; + setQuery(queryParam ? queryParam.split(",") : []); }, [location.search]); useEffect(() => { const newSearchParams = new URLSearchParams(); newSearchParams.set("page", page.toString()); - newSearchParams.set("query", query); + newSearchParams.set("query", query.join(",")); const newURL = `${window.location.pathname}?${newSearchParams.toString()}`; window.history.pushState({}, "", newURL); @@ -52,7 +54,7 @@ const ContributionPage: React.FC = () => { } }, [location.pathname]); - const url = buildURL(location, sort, status, query, page); + const url = buildURL(location, sort, status, query.join(" "), page); const { data: fetchedData, isLoading, @@ -71,14 +73,28 @@ const ContributionPage: React.FC = () => { )?.data; const handleSearch = (value: string) => { - setQuery(value.trim()); + const trimmedValue = value.trim(); + if (trimmedValue !== "" && !query.includes(trimmedValue)) { + setQuery([...query, trimmedValue]); + } + }; + + const handleRemoveQueryItem = (item: string) => { + setQuery(query.filter((q) => q !== item)); }; const filteredContributions = contrib?.filter((contribution) => { - const nameMatches = contribution.name - .toLowerCase() - .includes(query.toLowerCase()); - return nameMatches; + if (query.length === 0) { + return true; + } + const queryLower = query.map((q) => q.toLowerCase()); + const nameMatches = queryLower.some((q) => + contribution.name.toLowerCase().includes(q) + ); + const idMatches = queryLower.some((q) => + contribution._id.toLowerCase().includes(q) + ); + return nameMatches || idMatches; }); if (isLoading) @@ -106,8 +122,22 @@ const ContributionPage: React.FC = () => { onSearch={(value) => handleSearch(value || "")} isLarge buttonLabel="Rechercher" - placeholder="Rechercher par nom" + placeholder="Rechercher par nom ou ID" /> +
+ {query + .filter((item) => item.trim() !== "") + .map((item, index) => ( + handleRemoveQueryItem(item)} + > + {item} + + ))} +
= () => { ))} {dataList.some((item) => item.export === true) && ( - )}{" "} + )} = ({ - {data?.name} + + {data?.name} ({data?._id}) + {!data?.mailSent && ( Aucune réponse apportée à ce message pour l'instant diff --git a/src/pages/contribution-page/index.tsx b/src/pages/contribution-page/index.tsx index 4a610ad..711c284 100644 --- a/src/pages/contribution-page/index.tsx +++ b/src/pages/contribution-page/index.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import { useLocation } from "react-router-dom"; import { Col, @@ -7,6 +7,7 @@ import { Text, Title, SearchBar, + DismissibleTag, } from "@dataesr/dsfr-plus"; import ContributionData from "../../api/contribution-api/getData"; import { buildURL } from "../../api/utils/buildURL"; @@ -20,7 +21,7 @@ import ContributorSummary from "./contributor-summary"; const ContributionPage: React.FC = () => { const [sort, setSort] = useState("DESC"); const [status, setStatus] = useState("choose"); - const [query, setQuery] = useState(""); + const [query, setQuery] = useState([]); const [page, setPage] = useState(1); const [searchInMessage, setSearchInMessage] = useState(false); const [highlightedQuery, setHighlightedQuery] = useState(""); @@ -32,7 +33,8 @@ const ContributionPage: React.FC = () => { const params = new URLSearchParams(location.search); setPage(parseInt(params.get("page") || "1")); setSearchInMessage(params.get("searchInMessage") === "true"); - setQuery(params.get("query") || ""); + const queryParam = params.get("query") || ""; + setQuery(queryParam ? queryParam.split(",") : []); setSort(params.get("sort") || "DESC"); setStatus(params.get("status") || "choose"); }, [location.search]); @@ -40,7 +42,7 @@ const ContributionPage: React.FC = () => { useEffect(() => { const newSearchParams = new URLSearchParams(); newSearchParams.set("page", page.toString()); - newSearchParams.set("query", query); + newSearchParams.set("query", query.join(",")); newSearchParams.set("searchInMessage", searchInMessage.toString()); newSearchParams.set("sort", sort); newSearchParams.set("status", status); @@ -49,7 +51,14 @@ const ContributionPage: React.FC = () => { window.history.pushState({}, "", newURL); }, [page, query, searchInMessage, sort, status]); - const url = buildURL(location, sort, status, query, page, searchInMessage); + const url = buildURL( + location, + sort, + status, + query.join(" "), + page, + searchInMessage + ); const { data, isLoading, isError, refetch } = ContributionData(url); const meta = (data as { meta: any })?.meta; @@ -64,8 +73,15 @@ const ContributionPage: React.FC = () => { }, [contributions]); const handleSearch = (value: string) => { - setQuery(value.trim()); - setHighlightedQuery(value.trim()); + const trimmedValue = value.trim(); + if (trimmedValue !== "" && !query.includes(trimmedValue)) { + setQuery([...query, trimmedValue]); + setHighlightedQuery(trimmedValue); + } + }; + + const handleRemoveQueryItem = (item: string) => { + setQuery(query.filter((q) => q !== item)); }; const onSelectContribution = (id: string) => { @@ -73,16 +89,23 @@ const ContributionPage: React.FC = () => { }; const filteredContributions = contributions?.filter((contribution) => { - const nameMatches = contribution.name - .toLowerCase() - .includes(query.toLowerCase()); + if (query.length === 0) { + return true; + } + const queryLower = query.map((q) => q.toLowerCase()); + const nameMatches = queryLower.some((q) => + contribution.name.toLowerCase().includes(q) + ); + const idMatches = queryLower.some((q) => + contribution._id.toLowerCase().includes(q) + ); if (searchInMessage) { - const messageMatches = contribution.message - .toLowerCase() - .includes(query.toLowerCase()); - return nameMatches || messageMatches; + const messageMatches = queryLower.some((q) => + contribution.message.toLowerCase().includes(q) + ); + return nameMatches || idMatches || messageMatches; } - return nameMatches; + return nameMatches || idMatches; }); if (isLoading) @@ -113,8 +136,22 @@ const ContributionPage: React.FC = () => { onSearch={(value) => handleSearch(value || "")} isLarge buttonLabel="Rechercher" - placeholder="Rechercher par nom" + placeholder="Rechercher par nom ou ID" /> +
+ {query + .filter((item) => item.trim() !== "") + .map((item, index) => ( + handleRemoveQueryItem(item)} + > + {item} + + ))} +