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:
parent
cd50f66dd5
commit
55de43ad07
@ -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';
|
||||||
|
@ -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%',
|
||||||
|
},
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -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;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user