From 3372089440924ee42beabf5b533624e53caf8074 Mon Sep 17 00:00:00 2001 From: Joakim Uddholm Date: Tue, 4 Jun 2024 11:26:34 +0200 Subject: [PATCH] refactor: improve search page further. fix pagination --- app/src/App.js | 10 +- app/src/api/gram/search.js | 4 +- .../navbar/__snapshots__/Navbar.spec.js.snap | 4 +- app/src/components/search/Search.js | 88 ------------ app/src/components/search/SearchPage.js | 44 ++++++ .../{Search.spec.js => SearchPage.spec.js} | 4 +- app/src/components/search/SearchResultBox.js | 64 +++++++++ .../__snapshots__/SearchPage.spec.js.snap | 136 ++++++++++++++++++ 8 files changed, 255 insertions(+), 99 deletions(-) delete mode 100644 app/src/components/search/Search.js create mode 100644 app/src/components/search/SearchPage.js rename app/src/components/search/{Search.spec.js => SearchPage.spec.js} (88%) create mode 100644 app/src/components/search/SearchResultBox.js create mode 100644 app/src/components/search/__snapshots__/SearchPage.spec.js.snap diff --git a/app/src/App.js b/app/src/App.js index a119c916..b29810fd 100644 --- a/app/src/App.js +++ b/app/src/App.js @@ -1,10 +1,10 @@ import { Box, CssBaseline, darkScrollbar, useMediaQuery } from "@mui/material"; -import { createTheme, ThemeProvider } from "@mui/material/styles"; +import { ThemeProvider, createTheme } from "@mui/material/styles"; import React, { useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { BrowserRouter, Route, Routes, useNavigate } from "react-router-dom"; -import { getAuthToken } from "./api/gram/util/authToken"; import "./App.css"; +import { getAuthToken } from "./api/gram/util/authToken"; import AdminPage from "./components/admin/AdminPage"; import { ErrorPage } from "./components/elements/ErrorPage"; import { ModalManager } from "./components/elements/modal/ModalManager"; @@ -15,13 +15,13 @@ import { Model } from "./components/model/Model"; import { NewWizard } from "./components/model/New"; import { Navbar } from "./components/navbar/Navbar"; import { Reviews } from "./components/reviews/Reviews"; +import SearchPage from "./components/search/SearchPage"; +import { LatestSystem } from "./components/system/LatestSystem"; import { System } from "./components/system/System"; -import Search from "./components/search/Search"; import { TeamSystemsPage } from "./components/systems/TeamSystems/TeamSystemPage"; import UserModels from "./components/user-models/UserModels/UserModels"; import { useIsFramed } from "./hooks/useIsFramed"; import { authActions } from "./redux/authSlice"; -import { LatestSystem } from "./components/system/LatestSystem"; function LoginRedirect() { const navigate = useNavigate(); @@ -116,7 +116,7 @@ export default function App() { element={} /> } /> - } /> + } /> } /> } /> diff --git a/app/src/api/gram/search.js b/app/src/api/gram/search.js index 5e148f18..c476101e 100644 --- a/app/src/api/gram/search.js +++ b/app/src/api/gram/search.js @@ -15,10 +15,10 @@ const searchApi = api.injectEndpoints({ transformResponse: (response, meta, arg) => response.results, }), getSearchTypes: build.query({ - query: ({ systemId }) => ({ + query: () => ({ url: `/search/types`, }), - transformResponse: (response, meta, arg) => response, + transformResponse: (response, meta, arg) => response.searchTypes, }), }), }); diff --git a/app/src/components/navbar/__snapshots__/Navbar.spec.js.snap b/app/src/components/navbar/__snapshots__/Navbar.spec.js.snap index fc687c49..dc3e40ed 100644 --- a/app/src/components/navbar/__snapshots__/Navbar.spec.js.snap +++ b/app/src/components/navbar/__snapshots__/Navbar.spec.js.snap @@ -57,7 +57,7 @@ exports[`Navbar renders Navbar 1`] = ` @@ -209,7 +209,7 @@ exports[`Navbar renders Navbar 1`] = ` diff --git a/app/src/components/search/Search.js b/app/src/components/search/Search.js deleted file mode 100644 index 6a78a945..00000000 --- a/app/src/components/search/Search.js +++ /dev/null @@ -1,88 +0,0 @@ -import React from "react"; -import { Link, useLocation } from "react-router-dom"; -import { - Card, - CardActionArea, - CardContent, - CardHeader, - Divider, - List, - ListItemButton, - ListItemText, - Pagination, - TablePagination, - Typography, -} from "@mui/material"; -import { uniq } from "lodash"; -import { useListSystemsQuery } from "../../api/gram/system"; -import { SystemComplianceBadge } from "../elements/SystemComplianceBadge"; -import Loading from "../loading"; - -import { CenteredPage } from "../elements/CenteredPage"; -import { useSearchQuery } from "../../api/gram/search"; - -export default function Search() { - const { search } = useLocation(); - const query = new URLSearchParams(search); - const queryValue = query.get("query") || ""; - - const { data, isLoading } = useSearchQuery({ - searchText: queryValue, - types: ["system", "team", "model"], - }); - - return ( - - - - - Search results for "{queryValue}" - - - -
- -
- <> - {!isLoading ? ( - <> - {data.map((r) => ( - <> - - - {r.type}s - {r.items && r.items.length === 0 && ( - - No {r.type}s found - - )} - - {r.items && - r.items.map((item) => ( - - - {/* */} - - ))} - - {r.count > 0 && } - - -
- - ))} - - ) : ( - - )} - -
- ); -} diff --git a/app/src/components/search/SearchPage.js b/app/src/components/search/SearchPage.js new file mode 100644 index 00000000..d8593899 --- /dev/null +++ b/app/src/components/search/SearchPage.js @@ -0,0 +1,44 @@ +import { Card, CardContent, Divider, Grid, Typography } from "@mui/material"; +import React from "react"; +import { useLocation } from "react-router-dom"; +import Loading from "../loading"; + +import { useGetSearchTypesQuery } from "../../api/gram/search"; +import { CenteredPage } from "../elements/CenteredPage"; +import { SearchResultBox } from "./SearchResultBox"; + +export default function SearchPage() { + const { search } = useLocation(); + const query = new URLSearchParams(search); + const queryValue = query.get("query") || ""; + + const { data, isLoading } = useGetSearchTypesQuery(); + + return ( + + + + + Search results for "{queryValue}" + + + +
+ +
+ <> + {!isLoading ? ( + + {data?.map((searchType) => ( + + + + ))} + + ) : ( + + )} + +
+ ); +} diff --git a/app/src/components/search/Search.spec.js b/app/src/components/search/SearchPage.spec.js similarity index 88% rename from app/src/components/search/Search.spec.js rename to app/src/components/search/SearchPage.spec.js index 9e51fa0e..88980d69 100644 --- a/app/src/components/search/Search.spec.js +++ b/app/src/components/search/SearchPage.spec.js @@ -1,6 +1,6 @@ import React from "react"; import { cleanup, render } from "@testing-library/react"; -import Search from "./Search"; +import SearchPage from "./SearchPage"; import { BrowserRouter as Router } from "react-router-dom"; import { createMockStore } from "redux-test-utils"; import { Provider } from "react-redux"; @@ -11,7 +11,7 @@ const renderComponent = (props) => render( - + ); diff --git a/app/src/components/search/SearchResultBox.js b/app/src/components/search/SearchResultBox.js new file mode 100644 index 00000000..e41a0667 --- /dev/null +++ b/app/src/components/search/SearchResultBox.js @@ -0,0 +1,64 @@ +import { + Card, + CardContent, + CircularProgress, + List, + ListItemButton, + ListItemText, + Pagination, + Typography, +} from "@mui/material"; +import { useState } from "react"; +import { Link } from "react-router-dom"; +import { useSearchQuery } from "../../api/gram/search"; + +export function SearchResultBox({ searchText, type }) { + const [page, setPage] = useState(1); + + const { data, isLoading } = useSearchQuery({ + searchText, + types: [type.key], + page: page - 1, + }); + + const r = isLoading ? null : data[0]; + + if (isLoading || !r) { + return ; + } + + return ( + + + + {type.label}s {r.count > 0 && <>({r.count})} + + {r.items && r.items.length === 0 && ( + + No {type.label}s found + + )} + + {r.items && + r.items.map((item) => ( + + + + ))} + + {r.count > 0 && ( + setPage(np)} + /> + )} + + + ); +} diff --git a/app/src/components/search/__snapshots__/SearchPage.spec.js.snap b/app/src/components/search/__snapshots__/SearchPage.spec.js.snap new file mode 100644 index 00000000..165a2886 --- /dev/null +++ b/app/src/components/search/__snapshots__/SearchPage.spec.js.snap @@ -0,0 +1,136 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Search renders Search 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+
+
+
+ Search results for " + + " +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ , + "container":
+
+
+
+
+
+ Search results for " + + " +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`;