1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-22 19:07:54 +01:00

feat: add search in projects

This commit is contained in:
Youssef 2022-02-28 17:00:12 +01:00
parent cd50f66dd5
commit 55de43ad07
3 changed files with 53 additions and 21 deletions

View File

@ -15,7 +15,7 @@ import { P, C, E, EEA, RE } from '../common/flags';
import { NewUser } from '../user/NewUser/NewUser'; import { NewUser } from '../user/NewUser/NewUser';
import ResetPassword from '../user/ResetPassword/ResetPassword'; import ResetPassword from '../user/ResetPassword/ResetPassword';
import ForgottenPassword from '../user/ForgottenPassword/ForgottenPassword'; import ForgottenPassword from '../user/ForgottenPassword/ForgottenPassword';
import ProjectListNew from '../project/ProjectList/ProjectList'; import { ProjectListNew } from '../project/ProjectList/ProjectList';
import Project from '../project/Project/Project'; import Project from '../project/Project/Project';
import RedirectArchive from '../archive/RedirectArchive'; import RedirectArchive from '../archive/RedirectArchive';
import EnvironmentList from '../environments/EnvironmentList/EnvironmentList'; import EnvironmentList from '../environments/EnvironmentList/EnvironmentList';

View File

@ -21,4 +21,20 @@ export const useStyles = makeStyles(theme => ({
fontFamily: theme.typography.fontFamily, fontFamily: theme.typography.fontFamily,
pointer: 'cursor', pointer: 'cursor',
}, },
searchBarContainer: {
marginBottom: '2rem',
display: 'flex',
gap: '1rem',
justifyContent: 'space-between',
alignItems: 'center',
[theme.breakpoints.down('xs')]: {
display: 'block',
},
},
searchBar: {
minWidth: '450px',
[theme.breakpoints.down('xs')]: {
minWidth: '100%',
},
},
})); }));

View File

@ -1,24 +1,24 @@
import { useContext, useState } from 'react'; import { useContext, useMemo, useState } from 'react';
import { Link, useHistory } from 'react-router-dom'; import { Link, useHistory } from 'react-router-dom';
import { mutate } from 'swr'; import { mutate } from 'swr';
import { getProjectFetcher } from '../../../hooks/api/getters/useProject/getProjectFetcher'; import { getProjectFetcher } from 'hooks/api/getters/useProject/getProjectFetcher';
import useProjects from '../../../hooks/api/getters/useProjects/useProjects'; import useProjects from 'hooks/api/getters/useProjects/useProjects';
import ConditionallyRender from '../../common/ConditionallyRender'; import ConditionallyRender from 'component/common/ConditionallyRender/ConditionallyRender';
import ProjectCard from '../ProjectCard/ProjectCard'; import ProjectCard from '../ProjectCard/ProjectCard';
import { useStyles } from './ProjectList.styles'; import { useStyles } from './ProjectList.styles';
import { IProjectCard } from '../../../interfaces/project'; import { IProjectCard } from 'interfaces/project';
import loadingData from './loadingData'; import loadingData from './loadingData';
import useLoading from '../../../hooks/useLoading'; import useLoading from 'hooks/useLoading';
import PageContent from '../../common/PageContent'; import PageContent from 'component/common/PageContent';
import AccessContext from '../../../contexts/AccessContext'; import AccessContext from 'contexts/AccessContext';
import HeaderTitle from '../../common/HeaderTitle'; import HeaderTitle from 'component/common/HeaderTitle';
import ResponsiveButton from '../../common/ResponsiveButton/ResponsiveButton'; import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton';
import { CREATE_PROJECT } from '../../providers/AccessProvider/permissions'; import { CREATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import { Add } from '@material-ui/icons'; import { Add } from '@material-ui/icons';
import ApiError from '../../common/ApiError/ApiError'; import ApiError from 'component/common/ApiError/ApiError';
import useUiConfig from '../../../hooks/api/getters/useUiConfig/useUiConfig'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { SearchField } from 'component/common/SearchField/SearchField';
import classnames from 'classnames';
type projectMap = { type projectMap = {
[index: string]: boolean; [index: string]: boolean;
@ -43,7 +43,7 @@ function resolveCreateButtonData(isOss: boolean, hasAccess: boolean) {
} }
} }
const ProjectListNew = () => { export const ProjectListNew = () => {
const { hasAccess } = useContext(AccessContext); const { hasAccess } = useContext(AccessContext);
const history = useHistory(); const history = useHistory();
const styles = useStyles(); const styles = useStyles();
@ -51,6 +51,14 @@ const ProjectListNew = () => {
const [fetchedProjects, setFetchedProjects] = useState<projectMap>({}); const [fetchedProjects, setFetchedProjects] = useState<projectMap>({});
const ref = useLoading(loading); const ref = useLoading(loading);
const { isOss } = useUiConfig(); const { isOss } = useUiConfig();
const [filter, setFilter] = useState('');
const filteredProjects = useMemo(() => {
const regExp = new RegExp(filter, 'i');
return filter
? projects?.filter(project => regExp.test(project?.name))
: projects;
}, [projects, filter]);
const handleHover = (projectId: string) => { const handleHover = (projectId: string) => {
if (fetchedProjects[projectId]) { if (fetchedProjects[projectId]) {
@ -82,7 +90,7 @@ const ProjectListNew = () => {
return renderLoading(); return renderLoading();
} }
return projects.map((project: IProjectCard) => { return filteredProjects?.map((project: IProjectCard) => {
return ( return (
<Link <Link
key={project.id} key={project.id}
@ -126,6 +134,16 @@ const ProjectListNew = () => {
return ( return (
<div ref={ref}> <div ref={ref}>
<div className={styles.searchBarContainer}>
<SearchField
initialValue={filter}
updateValue={setFilter}
showValueChip
className={classnames(styles.searchBar, {
skeleton: loading,
})}
/>
</div>
<PageContent <PageContent
headerContent={ headerContent={
<HeaderTitle <HeaderTitle
@ -148,7 +166,7 @@ const ProjectListNew = () => {
<ConditionallyRender condition={error} show={renderError()} /> <ConditionallyRender condition={error} show={renderError()} />
<div className={styles.container}> <div className={styles.container}>
<ConditionallyRender <ConditionallyRender
condition={projects.length < 1 && !loading} condition={filteredProjects?.length < 1 && !loading}
show={<div>No projects available.</div>} show={<div>No projects available.</div>}
elseShow={renderProjects()} elseShow={renderProjects()}
/> />
@ -157,5 +175,3 @@ const ProjectListNew = () => {
</div> </div>
); );
}; };
export default ProjectListNew;