mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-29 01:15:48 +02:00
parent
a3decb543f
commit
f2e2952c31
@ -1,4 +1,4 @@
|
|||||||
import type { VFC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { safeRegExp } from '@server/util/escape-regex';
|
import { safeRegExp } from '@server/util/escape-regex';
|
||||||
import { styled } from '@mui/material';
|
import { styled } from '@mui/material';
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ export const StyledSpan = styled('span')(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const Highlighter: VFC<IHighlighterProps> = ({
|
export const Highlighter: FC<IHighlighterProps> = ({
|
||||||
search,
|
search,
|
||||||
children,
|
children,
|
||||||
caseSensitive,
|
caseSensitive,
|
||||||
|
@ -28,6 +28,8 @@ import {
|
|||||||
import Undo from '@mui/icons-material/Undo';
|
import Undo from '@mui/icons-material/Undo';
|
||||||
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
|
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
|
||||||
import Delete from '@mui/icons-material/Delete';
|
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 = {
|
export type ProjectArchiveCardProps = {
|
||||||
id: string;
|
id: string;
|
||||||
@ -51,16 +53,21 @@ export const ProjectArchiveCard: FC<ProjectArchiveCardProps> = ({
|
|||||||
owners,
|
owners,
|
||||||
}) => {
|
}) => {
|
||||||
const { locationSettings } = useLocationSettings();
|
const { locationSettings } = useLocationSettings();
|
||||||
|
const { searchQuery } = useSearchHighlightContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledProjectCard disabled>
|
<StyledProjectCard disabled data-testid={id}>
|
||||||
<StyledProjectCardBody>
|
<StyledProjectCardBody>
|
||||||
<StyledDivHeader>
|
<StyledDivHeader>
|
||||||
<StyledIconBox>
|
<StyledIconBox>
|
||||||
<ProjectIcon color='action' />
|
<ProjectIcon color='action' />
|
||||||
</StyledIconBox>
|
</StyledIconBox>
|
||||||
<StyledBox data-loading>
|
<StyledBox data-loading>
|
||||||
<StyledCardTitle>{name}</StyledCardTitle>
|
<StyledCardTitle>
|
||||||
|
<Highlighter search={searchQuery}>
|
||||||
|
{name}
|
||||||
|
</Highlighter>
|
||||||
|
</StyledCardTitle>
|
||||||
</StyledBox>
|
</StyledBox>
|
||||||
<ProjectModeBadge mode={mode} />
|
<ProjectModeBadge mode={mode} />
|
||||||
</StyledDivHeader>
|
</StyledDivHeader>
|
||||||
@ -89,6 +96,7 @@ export const ProjectArchiveCard: FC<ProjectArchiveCardProps> = ({
|
|||||||
date={
|
date={
|
||||||
new Date(archivedAt as string)
|
new Date(archivedAt as string)
|
||||||
}
|
}
|
||||||
|
live={false}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -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(<ArchiveProjectList />);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByText('Project One')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Project Two')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('search in header works', async () => {
|
||||||
|
render(<ArchiveProjectList />);
|
||||||
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
});
|
@ -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 { useSearchParams } from 'react-router-dom';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
@ -15,6 +15,8 @@ import {
|
|||||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||||
import { ReviveProjectDialog } from './ReviveProjectDialog/ReviveProjectDialog';
|
import { ReviveProjectDialog } from './ReviveProjectDialog/ReviveProjectDialog';
|
||||||
import { DeleteProjectDialogue } from '../Project/DeleteProject/DeleteProjectDialogue';
|
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 }) => ({
|
const StyledApiError = styled(ApiError)(({ theme }) => ({
|
||||||
maxWidth: '500px',
|
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 (
|
return (
|
||||||
<PageContent
|
<PageContent
|
||||||
isLoading={loading}
|
isLoading={loading}
|
||||||
@ -123,14 +135,16 @@ export const ArchiveProjectList: FC = () => {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ProjectGroup
|
<SearchHighlightProvider value={searchValue}>
|
||||||
loading={loading}
|
<ProjectGroup
|
||||||
searchValue={searchValue}
|
loading={loading}
|
||||||
projects={projects}
|
searchValue={searchValue}
|
||||||
placeholder='No archived projects found'
|
projects={filteredProjects}
|
||||||
ProjectCardComponent={ProjectCard}
|
placeholder='No archived projects found'
|
||||||
link={false}
|
ProjectCardComponent={ProjectCard}
|
||||||
/>
|
link={false}
|
||||||
|
/>
|
||||||
|
</SearchHighlightProvider>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
<ReviveProjectDialog
|
<ReviveProjectDialog
|
||||||
id={reviveProject.id || ''}
|
id={reviveProject.id || ''}
|
||||||
|
@ -112,6 +112,7 @@ export const ProjectGroup = <T extends { id: string }>({
|
|||||||
</StyledCardLink>
|
</StyledCardLink>
|
||||||
) : (
|
) : (
|
||||||
<ProjectCardComponent
|
<ProjectCardComponent
|
||||||
|
key={project.id}
|
||||||
onHover={() => {}}
|
onHover={() => {}}
|
||||||
{...project}
|
{...project}
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user