2022-11-19 14:21:26 +00:00
import React , { useEffect , useState } from "react" ;
// next
import { useRouter } from "next/router" ;
import type { NextPage } from "next" ;
// swr
import useSWR , { mutate } from "swr" ;
// services
import issuesServices from "lib/services/issues.services" ;
import sprintService from "lib/services/cycles.services" ;
// hooks
import useUser from "lib/hooks/useUser" ;
// fetching keys
import { CYCLE_ISSUES , CYCLE_LIST } from "constants/fetch-keys" ;
// layouts
2022-11-24 13:48:18 +00:00
import AdminLayout from "layouts/AdminLayout" ;
2022-11-19 14:21:26 +00:00
// components
import SprintView from "components/project/cycles/CycleView" ;
import ConfirmIssueDeletion from "components/project/issues/ConfirmIssueDeletion" ;
import ConfirmSprintDeletion from "components/project/cycles/ConfirmCycleDeletion" ;
import CreateUpdateIssuesModal from "components/project/issues/CreateUpdateIssueModal" ;
import CreateUpdateSprintsModal from "components/project/cycles/CreateUpdateCyclesModal" ;
// ui
import { Spinner } from "ui" ;
// icons
import { PlusIcon } from "@heroicons/react/20/solid" ;
// types
import { IIssue , ICycle , SelectSprintType , SelectIssue } from "types" ;
import { EmptySpace , EmptySpaceItem } from "ui/EmptySpace" ;
import { ArrowPathIcon } from "@heroicons/react/24/outline" ;
import HeaderButton from "ui/HeaderButton" ;
import { BreadcrumbItem , Breadcrumbs } from "ui/Breadcrumbs" ;
const ProjectSprints : NextPage = ( ) = > {
const [ isOpen , setIsOpen ] = useState ( false ) ;
const [ selectedSprint , setSelectedSprint ] = useState < SelectSprintType > ( ) ;
const [ isIssueModalOpen , setIsIssueModalOpen ] = useState ( false ) ;
const [ selectedIssues , setSelectedIssues ] = useState < SelectIssue > ( ) ;
const [ deleteIssue , setDeleteIssue ] = useState < string | undefined > ( ) ;
const { activeWorkspace , activeProject } = useUser ( ) ;
const router = useRouter ( ) ;
const { projectId } = router . query ;
const { data : sprints } = useSWR < ICycle [ ] > (
projectId && activeWorkspace ? CYCLE_LIST ( projectId as string ) : null ,
activeWorkspace && projectId
? ( ) = > sprintService . getCycles ( activeWorkspace . slug , projectId as string )
: null
) ;
const openIssueModal = (
sprintId : string ,
issue? : IIssue ,
actionType : "create" | "edit" | "delete" = "create"
) = > {
const sprint = sprints ? . find ( ( sprint ) = > sprint . id === sprintId ) ;
if ( sprint ) {
setSelectedSprint ( {
. . . sprint ,
actionType : "create-issue" ,
} ) ;
if ( issue ) setSelectedIssues ( { . . . issue , actionType } ) ;
setIsIssueModalOpen ( true ) ;
}
} ;
const addIssueToSprint = ( sprintId : string , issueId : string ) = > {
if ( ! activeWorkspace || ! projectId ) return ;
issuesServices
. addIssueToSprint ( activeWorkspace . slug , projectId as string , sprintId , {
issue : issueId ,
} )
. then ( ( response ) = > {
console . log ( response ) ;
mutate ( CYCLE_ISSUES ( sprintId ) ) ;
} )
. catch ( ( error ) = > {
console . log ( error ) ;
} ) ;
} ;
useEffect ( ( ) = > {
if ( isOpen ) return ;
const timer = setTimeout ( ( ) = > {
setSelectedSprint ( undefined ) ;
clearTimeout ( timer ) ;
} , 500 ) ;
} , [ isOpen ] ) ;
useEffect ( ( ) = > {
if ( selectedIssues ? . actionType === "delete" ) {
setDeleteIssue ( selectedIssues . id ) ;
}
} , [ selectedIssues ] ) ;
return (
2022-11-24 13:48:18 +00:00
< AdminLayout
2022-11-19 14:21:26 +00:00
meta = { {
title : "Plane - Cycles" ,
} }
>
< CreateUpdateSprintsModal
isOpen = {
isOpen &&
selectedSprint ? . actionType !== "delete" &&
selectedSprint ? . actionType !== "create-issue"
}
setIsOpen = { setIsOpen }
data = { selectedSprint }
projectId = { projectId as string }
/ >
< ConfirmSprintDeletion
isOpen = { isOpen && ! ! selectedSprint && selectedSprint . actionType === "delete" }
setIsOpen = { setIsOpen }
data = { selectedSprint }
/ >
< ConfirmIssueDeletion
handleClose = { ( ) = > setDeleteIssue ( undefined ) }
isOpen = { ! ! deleteIssue }
data = { selectedIssues }
/ >
< CreateUpdateIssuesModal
isOpen = {
isIssueModalOpen &&
selectedSprint ? . actionType === "create-issue" &&
selectedIssues ? . actionType !== "delete"
}
data = { selectedIssues }
prePopulateData = { { sprints : selectedSprint?.id } }
setIsOpen = { setIsOpen }
projectId = { projectId as string }
/ >
2022-11-24 13:48:18 +00:00
{ sprints ? (
sprints . length > 0 ? (
< div className = "h-full w-full space-y-5" >
< Breadcrumbs >
< BreadcrumbItem title = "Projects" link = "/projects" / >
< BreadcrumbItem title = { ` ${ activeProject ? . name ? ? "Project" } Cycles ` } / >
< / Breadcrumbs >
< div className = "flex items-center justify-between cursor-pointer w-full" >
< h2 className = "text-2xl font-medium" > Project Cycle < / h2 >
< HeaderButton Icon = { PlusIcon } label = "Add Cycle" onClick = { ( ) = > setIsOpen ( true ) } / >
2022-11-19 14:21:26 +00:00
< / div >
2022-11-24 13:48:18 +00:00
< div className = "h-full w-full" >
{ sprints . map ( ( sprint ) = > (
< SprintView
sprint = { sprint }
selectSprint = { setSelectedSprint }
projectId = { projectId as string }
workspaceSlug = { activeWorkspace ? . slug as string }
openIssueModal = { openIssueModal }
addIssueToSprint = { addIssueToSprint }
key = { sprint . id }
/ >
) ) }
< / div >
< / div >
2022-11-19 14:21:26 +00:00
) : (
2022-11-24 13:48:18 +00:00
< div className = "w-full h-full flex flex-col justify-center items-center px-4" >
< EmptySpace
title = "You don't have any cycle yet."
description = "A cycle is a fixed time period where a team commits to a set number of issues from their backlog. Cycles are usually one, two, or four weeks long."
Icon = { ArrowPathIcon }
>
< EmptySpaceItem
title = "Create a new cycle"
description = {
< span >
Use < pre className = "inline bg-gray-100 px-2 py-1 rounded" > Ctrl / Command + Q < / pre > { " " }
shortcut to create a new cycle
< / span >
}
Icon = { PlusIcon }
action = { ( ) = > setIsOpen ( true ) }
/ >
< / EmptySpace >
2022-11-19 14:21:26 +00:00
< / div >
2022-11-24 13:48:18 +00:00
)
) : (
< div className = "w-full h-full flex justify-center items-center" >
< Spinner / >
< / div >
) }
< / AdminLayout >
2022-11-19 14:21:26 +00:00
) ;
} ;
export default ProjectSprints ;