mirror of
https://github.com/Unleash/unleash.git
synced 2024-10-23 20:07:40 +02:00
1a63d91f95
* feat: change color scheme * feat: add navigation menu * fix: add bg image * fix: add archive and strategies to navigation * fix: round corners * feat: mobile view project details * feat: mobile view navigation * fix: only show menu if user is admin * fix: rename navigation * fix: only render relevant routes for oss context * feat: add project actions * feat: add icons * feat: add breadcrumbs * fix: place breadcrumbs absolutely * fix: adjust breadcrumbs * fix: toast * fix: cleanup * fix login * fix: breadcrumbs * fix: add billing link * fix: links * fix: feature view * fix: path to go back * fix: remove default value * fix: remove unused imports * refactor: delete outdated test * fix: add item to filter in breadcrumb * fix: remove console log
147 lines
5.0 KiB
TypeScript
147 lines
5.0 KiB
TypeScript
import { useContext, useState } from 'react';
|
|
import { Link, useHistory } from 'react-router-dom';
|
|
import { mutate } from 'swr';
|
|
import { getProjectFetcher } from '../../../hooks/api/getters/useProject/getProjectFetcher';
|
|
import useProjects from '../../../hooks/api/getters/useProjects/useProjects';
|
|
import ConditionallyRender from '../../common/ConditionallyRender';
|
|
import ProjectCard from '../ProjectCard/ProjectCard';
|
|
import { useStyles } from './ProjectList.styles';
|
|
import { IProjectCard } from '../../../interfaces/project';
|
|
|
|
import loadingData from './loadingData';
|
|
import useLoading from '../../../hooks/useLoading';
|
|
import PageContent from '../../common/PageContent';
|
|
import AccessContext from '../../../contexts/AccessContext';
|
|
import HeaderTitle from '../../common/HeaderTitle';
|
|
import ResponsiveButton from '../../common/ResponsiveButton/ResponsiveButton';
|
|
import { CREATE_PROJECT } from '../../AccessProvider/permissions';
|
|
|
|
import { Add } from '@material-ui/icons';
|
|
import ApiError from '../../common/ApiError/ApiError';
|
|
import useToast from '../../../hooks/useToast';
|
|
|
|
type projectMap = {
|
|
[index: string]: boolean;
|
|
};
|
|
|
|
const ProjectListNew = () => {
|
|
const { hasAccess } = useContext(AccessContext);
|
|
const history = useHistory();
|
|
const { toast, setToastData } = useToast();
|
|
|
|
const styles = useStyles();
|
|
const { projects, loading, error, refetch } = useProjects();
|
|
const [fetchedProjects, setFetchedProjects] = useState<projectMap>({});
|
|
const ref = useLoading(loading);
|
|
|
|
const handleHover = (projectId: string) => {
|
|
if (fetchedProjects[projectId]) {
|
|
return;
|
|
}
|
|
|
|
const { KEY, fetcher } = getProjectFetcher(projectId);
|
|
mutate(KEY, fetcher);
|
|
setFetchedProjects(prev => ({ ...prev, [projectId]: true }));
|
|
};
|
|
|
|
const renderError = () => {
|
|
return (
|
|
<ApiError
|
|
onClick={refetch}
|
|
className={styles.apiError}
|
|
text="Error fetching projects"
|
|
/>
|
|
);
|
|
};
|
|
|
|
const renderProjects = () => {
|
|
if (loading) {
|
|
return renderLoading();
|
|
}
|
|
|
|
return projects.map((project: IProjectCard) => {
|
|
return (
|
|
<Link
|
|
key={project.id}
|
|
to={{
|
|
pathname: `/projects/${project.id}`,
|
|
state: {
|
|
projectName: project.name,
|
|
},
|
|
}}
|
|
className={styles.cardLink}
|
|
>
|
|
<ProjectCard
|
|
onHover={() => handleHover(project?.id)}
|
|
name={project?.name}
|
|
memberCount={project?.memberCount}
|
|
health={project?.health}
|
|
id={project?.id}
|
|
featureCount={project?.featureCount}
|
|
setToastData={setToastData}
|
|
/>
|
|
</Link>
|
|
);
|
|
});
|
|
};
|
|
|
|
const renderLoading = () => {
|
|
return loadingData.map((project: IProjectCard) => {
|
|
return (
|
|
<ProjectCard
|
|
data-loading
|
|
onHover={() => {}}
|
|
key={project.id}
|
|
name={project.name}
|
|
id={project.id}
|
|
memberCount={2}
|
|
health={95}
|
|
featureCount={4}
|
|
setToastData={setToastData}
|
|
/>
|
|
);
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div ref={ref}>
|
|
<PageContent
|
|
headerContent={
|
|
<HeaderTitle
|
|
title="Projects"
|
|
actions={
|
|
<ConditionallyRender
|
|
condition={hasAccess(CREATE_PROJECT)}
|
|
show={
|
|
<ResponsiveButton
|
|
Icon={Add}
|
|
onClick={() =>
|
|
history.push('/projects/create')
|
|
}
|
|
maxWidth="700px"
|
|
tooltip="Add new project"
|
|
>
|
|
Add new project
|
|
</ResponsiveButton>
|
|
}
|
|
/>
|
|
}
|
|
/>
|
|
}
|
|
>
|
|
<ConditionallyRender condition={error} show={renderError()} />
|
|
<div className={styles.container}>
|
|
<ConditionallyRender
|
|
condition={projects.length < 1 && !loading}
|
|
show={<div>No projects available.</div>}
|
|
elseShow={renderProjects()}
|
|
/>
|
|
</div>
|
|
{toast}
|
|
</PageContent>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ProjectListNew;
|