From f2e2952c3145c8c167181cc0b2e80602e09ffb2f Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:19:29 +0200 Subject: [PATCH] fix: projects archive search (#7898) Filter projects when searching --- .../common/Highlighter/Highlighter.tsx | 4 +- .../NewProjectCard/ProjectArchiveCard.tsx | 12 ++++- .../ProjectList/ArchiveProjectList.test.tsx | 52 +++++++++++++++++++ .../ProjectList/ArchiveProjectList.tsx | 32 ++++++++---- .../project/ProjectList/ProjectGroup.tsx | 1 + 5 files changed, 88 insertions(+), 13 deletions(-) create mode 100644 frontend/src/component/project/ProjectList/ArchiveProjectList.test.tsx diff --git a/frontend/src/component/common/Highlighter/Highlighter.tsx b/frontend/src/component/common/Highlighter/Highlighter.tsx index 9d92eeea20..577a3c1eaf 100644 --- a/frontend/src/component/common/Highlighter/Highlighter.tsx +++ b/frontend/src/component/common/Highlighter/Highlighter.tsx @@ -1,4 +1,4 @@ -import type { VFC } from 'react'; +import type { FC } from 'react'; import { safeRegExp } from '@server/util/escape-regex'; import { styled } from '@mui/material'; @@ -14,7 +14,7 @@ export const StyledSpan = styled('span')(({ theme }) => ({ }, })); -export const Highlighter: VFC = ({ +export const Highlighter: FC = ({ search, children, caseSensitive, diff --git a/frontend/src/component/project/NewProjectCard/ProjectArchiveCard.tsx b/frontend/src/component/project/NewProjectCard/ProjectArchiveCard.tsx index 8dd8c879b1..522d7cbf57 100644 --- a/frontend/src/component/project/NewProjectCard/ProjectArchiveCard.tsx +++ b/frontend/src/component/project/NewProjectCard/ProjectArchiveCard.tsx @@ -28,6 +28,8 @@ import { import Undo from '@mui/icons-material/Undo'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; import Delete from '@mui/icons-material/Delete'; +import { Highlighter } from 'component/common/Highlighter/Highlighter'; +import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; export type ProjectArchiveCardProps = { id: string; @@ -51,16 +53,21 @@ export const ProjectArchiveCard: FC = ({ owners, }) => { const { locationSettings } = useLocationSettings(); + const { searchQuery } = useSearchHighlightContext(); return ( - + - {name} + + + {name} + + @@ -89,6 +96,7 @@ export const ProjectArchiveCard: FC = ({ date={ new Date(archivedAt as string) } + live={false} />

diff --git a/frontend/src/component/project/ProjectList/ArchiveProjectList.test.tsx b/frontend/src/component/project/ProjectList/ArchiveProjectList.test.tsx new file mode 100644 index 0000000000..c91b25ade3 --- /dev/null +++ b/frontend/src/component/project/ProjectList/ArchiveProjectList.test.tsx @@ -0,0 +1,52 @@ +import { screen, waitFor } from '@testing-library/react'; +import { render } from 'utils/testRenderer'; +import { testServerRoute, testServerSetup } from 'utils/testServer'; +import { ArchiveProjectList } from './ArchiveProjectList'; +import userEvent from '@testing-library/user-event'; + +const server = testServerSetup(); + +const setupApi = () => { + testServerRoute(server, '/api/admin/projects', { + projects: [ + { id: 'testid-1', name: 'Project One', archived: true }, + { id: 'testid-2', name: 'Project Two', archived: true }, + ], + }); + + testServerRoute(server, '/api/admin/ui-config', { + flags: { + archiveFeature: true, + }, + versionInfo: { + current: { enterprise: 'version' }, + }, + }); +}; + +beforeEach(() => { + setupApi(); +}); + +test('displays archived projects correctly', async () => { + render(); + + await waitFor(() => { + expect(screen.getByText('Project One')).toBeInTheDocument(); + expect(screen.getByText('Project Two')).toBeInTheDocument(); + }); +}); + +test('search in header works', async () => { + render(); + + const searchInput = screen.getByPlaceholderText(/^Search/); + expect(searchInput).toBeInTheDocument(); + + await userEvent.type(searchInput, 'One'); + + await waitFor(() => { + expect(screen.queryByTestId('testid-1')).toBeInTheDocument(); + expect(screen.queryByTestId('testid-2')).not.toBeInTheDocument(); + }); +}); diff --git a/frontend/src/component/project/ProjectList/ArchiveProjectList.tsx b/frontend/src/component/project/ProjectList/ArchiveProjectList.tsx index c8ff91f127..f76caef908 100644 --- a/frontend/src/component/project/ProjectList/ArchiveProjectList.tsx +++ b/frontend/src/component/project/ProjectList/ArchiveProjectList.tsx @@ -1,4 +1,4 @@ -import { type FC, useEffect, useState } from 'react'; +import { type FC, useEffect, useMemo, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageContent } from 'component/common/PageContent/PageContent'; @@ -15,6 +15,8 @@ import { import useProjects from 'hooks/api/getters/useProjects/useProjects'; import { ReviveProjectDialog } from './ReviveProjectDialog/ReviveProjectDialog'; import { DeleteProjectDialogue } from '../Project/DeleteProject/DeleteProjectDialogue'; +import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; +import { safeRegExp } from '@server/util/escape-regex'; const StyledApiError = styled(ApiError)(({ theme }) => ({ maxWidth: '500px', @@ -82,6 +84,16 @@ export const ArchiveProjectList: FC = () => { /> ); + const filteredProjects = useMemo( + () => + searchValue + ? projects.filter((project) => + safeRegExp(searchValue, 'i').test(project.name), + ) + : projects, + [projects, searchValue], + ); + return ( { )} /> - + + + ({ ) : ( {}} {...project} />