mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	
							parent
							
								
									c978ed6c6b
								
							
						
					
					
						commit
						7c00b760f8
					
				| @ -0,0 +1,50 @@ | ||||
| import { Dialogue } from 'component/common/Dialogue/Dialogue'; | ||||
| import React from 'react'; | ||||
| import { formatUnknownError } from 'utils/formatUnknownError'; | ||||
| import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi'; | ||||
| import useProjects from 'hooks/api/getters/useProjects/useProjects'; | ||||
| import useToast from 'hooks/useToast'; | ||||
| 
 | ||||
| interface IDeleteProjectDialogueProps { | ||||
|     project: string; | ||||
|     open: boolean; | ||||
|     onClose?: () => void; | ||||
|     onSuccess?: () => void; | ||||
| } | ||||
| 
 | ||||
| export const DeleteProjectDialogue = ({ | ||||
|     open, | ||||
|     onClose, | ||||
|     project, | ||||
|     onSuccess, | ||||
| }: IDeleteProjectDialogueProps) => { | ||||
|     const { deleteProject } = useProjectApi(); | ||||
|     const { refetch: refetchProjectOverview } = useProjects(); | ||||
|     const { setToastData, setToastApiError } = useToast(); | ||||
| 
 | ||||
|     const onClick = async (e: React.SyntheticEvent) => { | ||||
|         e.preventDefault(); | ||||
|         try { | ||||
|             await deleteProject(project); | ||||
|             refetchProjectOverview(); | ||||
|             setToastData({ | ||||
|                 title: 'Deleted project', | ||||
|                 type: 'success', | ||||
|                 text: 'Successfully deleted project', | ||||
|             }); | ||||
|             onSuccess?.(); | ||||
|         } catch (ex: unknown) { | ||||
|             setToastApiError(formatUnknownError(ex)); | ||||
|         } | ||||
|         onClose?.(); | ||||
|     }; | ||||
| 
 | ||||
|     return ( | ||||
|         <Dialogue | ||||
|             open={open} | ||||
|             onClick={onClick} | ||||
|             onClose={onClose} | ||||
|             title="Really delete project" | ||||
|         /> | ||||
|     ); | ||||
| }; | ||||
| @ -18,7 +18,7 @@ export const useStyles = makeStyles()(theme => ({ | ||||
|         marginBottom: '1rem', | ||||
|     }, | ||||
|     innerContainer: { | ||||
|         padding: '1rem 2rem', | ||||
|         padding: '1.25rem 2rem', | ||||
|         display: 'flex', | ||||
|         alignItems: 'center', | ||||
|     }, | ||||
|  | ||||
| @ -4,21 +4,44 @@ import useLoading from 'hooks/useLoading'; | ||||
| import ApiError from 'component/common/ApiError/ApiError'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { useStyles } from './Project.styles'; | ||||
| import { Tab, Tabs } from '@mui/material'; | ||||
| import { Edit } from '@mui/icons-material'; | ||||
| import { styled, Tab, Tabs } from '@mui/material'; | ||||
| import { Delete, Edit } from '@mui/icons-material'; | ||||
| import useToast from 'hooks/useToast'; | ||||
| import useQueryParams from 'hooks/useQueryParams'; | ||||
| import { useEffect } from 'react'; | ||||
| import { useEffect, useState } from 'react'; | ||||
| import { ProjectAccess } from '../ProjectAccess/ProjectAccess'; | ||||
| import ProjectEnvironment from '../ProjectEnvironment/ProjectEnvironment'; | ||||
| import { ProjectFeaturesArchive } from './ProjectFeaturesArchive/ProjectFeaturesArchive'; | ||||
| import ProjectOverview from './ProjectOverview'; | ||||
| import ProjectHealth from './ProjectHealth/ProjectHealth'; | ||||
| import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; | ||||
| import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions'; | ||||
| import { | ||||
|     DELETE_PROJECT, | ||||
|     UPDATE_PROJECT, | ||||
| } from 'component/providers/AccessProvider/permissions'; | ||||
| import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; | ||||
| import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | ||||
| import { Routes, Route, useLocation } from 'react-router-dom'; | ||||
| import { DeleteProjectDialogue } from './DeleteProject/DeleteProjectDialogue'; | ||||
| 
 | ||||
| const StyledDiv = styled('div')(() => ({ | ||||
|     display: 'flex', | ||||
| })); | ||||
| 
 | ||||
| const StyledName = styled('div')(({ theme }) => ({ | ||||
|     overflow: 'hidden', | ||||
|     textOverflow: 'ellipsis', | ||||
|     whiteSpace: 'nowrap', | ||||
|     paddingBottom: theme.spacing(2), | ||||
| })); | ||||
| 
 | ||||
| const StyledTitle = styled('span')(({ theme }) => ({ | ||||
|     fontSize: theme.fontSizes.smallBody, | ||||
|     fontWeight: 'normal', | ||||
| })); | ||||
| const StyledText = styled(StyledTitle)(({ theme }) => ({ | ||||
|     color: theme.palette.grey[800], | ||||
| })); | ||||
| 
 | ||||
| const Project = () => { | ||||
|     const projectId = useRequiredPathParam('projectId'); | ||||
| @ -33,6 +56,8 @@ const Project = () => { | ||||
|     const basePath = `/projects/${projectId}`; | ||||
|     const projectName = project?.name || projectId; | ||||
| 
 | ||||
|     const [showDelDialog, setShowDelDialog] = useState(false); | ||||
| 
 | ||||
|     const tabs = [ | ||||
|         { | ||||
|             title: 'Overview', | ||||
| @ -85,21 +110,60 @@ const Project = () => { | ||||
|             <div className={styles.header}> | ||||
|                 <div className={styles.innerContainer}> | ||||
|                     <h2 className={styles.title}> | ||||
|                         <div className={styles.titleText} data-loading> | ||||
|                             {projectName} | ||||
|                         <div> | ||||
|                             <StyledName data-loading>{projectName}</StyledName> | ||||
|                             <ConditionallyRender | ||||
|                                 condition={Boolean(project.description)} | ||||
|                                 show={ | ||||
|                                     <StyledDiv> | ||||
|                                         <StyledTitle data-loading> | ||||
|                                             Description:  | ||||
|                                         </StyledTitle> | ||||
|                                         <StyledText data-loading> | ||||
|                                             {project.description} | ||||
|                                         </StyledText> | ||||
|                                     </StyledDiv> | ||||
|                                 } | ||||
|                             /> | ||||
|                             <StyledDiv> | ||||
|                                 <StyledTitle data-loading> | ||||
|                                     projectId:  | ||||
|                                 </StyledTitle> | ||||
|                                 <StyledText data-loading> | ||||
|                                     {projectId} | ||||
|                                 </StyledText> | ||||
|                             </StyledDiv> | ||||
|                         </div> | ||||
|                         <PermissionIconButton | ||||
|                             permission={UPDATE_PROJECT} | ||||
|                             projectId={projectId} | ||||
|                             sx={{ visibility: isOss() ? 'hidden' : 'visible' }} | ||||
|                             onClick={() => | ||||
|                                 navigate(`/projects/${projectId}/edit`) | ||||
|                             } | ||||
|                             tooltipProps={{ title: 'Edit project' }} | ||||
|                             data-loading | ||||
|                         > | ||||
|                             <Edit /> | ||||
|                         </PermissionIconButton> | ||||
|                         <StyledDiv> | ||||
|                             <PermissionIconButton | ||||
|                                 permission={UPDATE_PROJECT} | ||||
|                                 projectId={projectId} | ||||
|                                 sx={{ | ||||
|                                     visibility: isOss() ? 'hidden' : 'visible', | ||||
|                                 }} | ||||
|                                 onClick={() => | ||||
|                                     navigate(`/projects/${projectId}/edit`) | ||||
|                                 } | ||||
|                                 tooltipProps={{ title: 'Edit project' }} | ||||
|                                 data-loading | ||||
|                             > | ||||
|                                 <Edit /> | ||||
|                             </PermissionIconButton> | ||||
|                             <PermissionIconButton | ||||
|                                 permission={DELETE_PROJECT} | ||||
|                                 projectId={projectId} | ||||
|                                 sx={{ | ||||
|                                     visibility: isOss() ? 'hidden' : 'visible', | ||||
|                                 }} | ||||
|                                 onClick={() => { | ||||
|                                     setShowDelDialog(true); | ||||
|                                 }} | ||||
|                                 tooltipProps={{ title: 'Delete project' }} | ||||
|                                 data-loading | ||||
|                             > | ||||
|                                 <Delete /> | ||||
|                             </PermissionIconButton> | ||||
|                         </StyledDiv> | ||||
|                     </h2> | ||||
|                 </div> | ||||
|                 <ConditionallyRender | ||||
| @ -132,6 +196,16 @@ const Project = () => { | ||||
|                     </Tabs> | ||||
|                 </div> | ||||
|             </div> | ||||
|             <DeleteProjectDialogue | ||||
|                 project={projectId} | ||||
|                 open={showDelDialog} | ||||
|                 onClose={() => { | ||||
|                     setShowDelDialog(false); | ||||
|                 }} | ||||
|                 onSuccess={() => { | ||||
|                     navigate('/projects'); | ||||
|                 }} | ||||
|             /> | ||||
|             <Routes> | ||||
|                 <Route path="health" element={<ProjectHealth />} /> | ||||
|                 <Route path="access/*" element={<ProjectAccess />} /> | ||||
|  | ||||
| @ -32,6 +32,7 @@ export const useStyles = makeStyles()(theme => ({ | ||||
|         boxOrient: 'vertical', | ||||
|         textOverflow: 'ellipsis', | ||||
|         overflow: 'hidden', | ||||
|         alignItems: 'flex-start', | ||||
|     }, | ||||
| 
 | ||||
|     projectIcon: { | ||||
|  | ||||
| @ -4,21 +4,17 @@ import MoreVertIcon from '@mui/icons-material/MoreVert'; | ||||
| import { ReactComponent as ProjectIcon } from 'assets/icons/projectIcon.svg'; | ||||
| import React, { useState, SyntheticEvent, useContext } from 'react'; | ||||
| import { useNavigate } from 'react-router-dom'; | ||||
| import { Dialogue } from 'component/common/Dialogue/Dialogue'; | ||||
| import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi'; | ||||
| import useProjects from 'hooks/api/getters/useProjects/useProjects'; | ||||
| import { Delete, Edit } from '@mui/icons-material'; | ||||
| import { getProjectEditPath } from 'utils/routePathHelpers'; | ||||
| import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; | ||||
| import useToast from 'hooks/useToast'; | ||||
| import { | ||||
|     UPDATE_PROJECT, | ||||
|     DELETE_PROJECT, | ||||
| } from 'component/providers/AccessProvider/permissions'; | ||||
| import { formatUnknownError } from 'utils/formatUnknownError'; | ||||
| import AccessContext from 'contexts/AccessContext'; | ||||
| import { DEFAULT_PROJECT_ID } from 'hooks/api/getters/useDefaultProject/useDefaultProjectId'; | ||||
| import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | ||||
| import { DeleteProjectDialogue } from '../Project/DeleteProject/DeleteProjectDialogue'; | ||||
| 
 | ||||
| interface IProjectCardProps { | ||||
|     name: string; | ||||
| @ -40,36 +36,15 @@ export const ProjectCard = ({ | ||||
|     const { classes } = useStyles(); | ||||
|     const { hasAccess } = useContext(AccessContext); | ||||
|     const { isOss } = useUiConfig(); | ||||
|     const { refetch: refetchProjectOverview } = useProjects(); | ||||
|     const [anchorEl, setAnchorEl] = useState(null); | ||||
|     const [showDelDialog, setShowDelDialog] = useState(false); | ||||
|     const { deleteProject } = useProjectApi(); | ||||
|     const navigate = useNavigate(); | ||||
|     const { setToastData, setToastApiError } = useToast(); | ||||
| 
 | ||||
|     // @ts-expect-error
 | ||||
|     const handleClick = e => { | ||||
|         e.preventDefault(); | ||||
|         setAnchorEl(e.currentTarget); | ||||
|     }; | ||||
| 
 | ||||
|     const onRemoveProject = async (e: React.SyntheticEvent) => { | ||||
|         e.preventDefault(); | ||||
|         try { | ||||
|             await deleteProject(id); | ||||
|             refetchProjectOverview(); | ||||
|             setToastData({ | ||||
|                 title: 'Deleted project', | ||||
|                 type: 'success', | ||||
|                 text: 'Successfully deleted project', | ||||
|             }); | ||||
|         } catch (e: unknown) { | ||||
|             setToastApiError(formatUnknownError(e)); | ||||
|         } | ||||
|         setShowDelDialog(false); | ||||
|         setAnchorEl(null); | ||||
|     }; | ||||
| 
 | ||||
|     const canDeleteProject = | ||||
|         hasAccess(DELETE_PROJECT, id) && id !== DEFAULT_PROJECT_ID; | ||||
| 
 | ||||
| @ -152,15 +127,13 @@ export const ProjectCard = ({ | ||||
|                     <p data-loading>members</p> | ||||
|                 </div> | ||||
|             </div> | ||||
|             <Dialogue | ||||
|             <DeleteProjectDialogue | ||||
|                 project={id} | ||||
|                 open={showDelDialog} | ||||
|                 onClick={onRemoveProject} | ||||
|                 onClose={event => { | ||||
|                     event.preventDefault(); | ||||
|                 onClose={() => { | ||||
|                     setAnchorEl(null); | ||||
|                     setShowDelDialog(false); | ||||
|                 }} | ||||
|                 title="Really delete project" | ||||
|             /> | ||||
|         </Card> | ||||
|     ); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user