diff --git a/apps/app/components/command-palette/index.tsx b/apps/app/components/command-palette/index.tsx index cd3870277..b626eac7a 100644 --- a/apps/app/components/command-palette/index.tsx +++ b/apps/app/components/command-palette/index.tsx @@ -9,7 +9,11 @@ import useTheme from "lib/hooks/useTheme"; import useToast from "lib/hooks/useToast"; // icons import { MagnifyingGlassIcon } from "@heroicons/react/20/solid"; -import { DocumentPlusIcon, FolderPlusIcon, FolderIcon } from "@heroicons/react/24/outline"; +import { + FolderIcon, + RectangleStackIcon, + ClipboardDocumentListIcon, +} from "@heroicons/react/24/outline"; // commons import { classNames, copyTextToClipboard } from "constants/common"; // components @@ -19,12 +23,19 @@ import CreateUpdateIssuesModal from "components/project/issues/CreateUpdateIssue import CreateUpdateCycleModal from "components/project/cycles/CreateUpdateCyclesModal"; // types import { IIssue } from "types"; +import { Button } from "ui"; +import { SubmitHandler, useForm } from "react-hook-form"; + type ItemType = { name: string; url?: string; onClick?: () => void; }; +type FormInput = { + issue: string[]; +}; + const CommandPalette: React.FC = () => { const router = useRouter(); @@ -51,7 +62,7 @@ const CommandPalette: React.FC = () => { const quickActions = [ { name: "Add new issue...", - icon: DocumentPlusIcon, + icon: RectangleStackIcon, shortcut: "I", onClick: () => { setIsIssueModalOpen(true); @@ -59,7 +70,7 @@ const CommandPalette: React.FC = () => { }, { name: "Add new project...", - icon: FolderPlusIcon, + icon: ClipboardDocumentListIcon, shortcut: "P", onClick: () => { setIsProjectModalOpen(true); @@ -116,6 +127,23 @@ const CommandPalette: React.FC = () => { [toggleCollapsed, setToastAlert, router] ); + const { + register, + formState: { errors, isSubmitting }, + handleSubmit, + reset, + setError, + control, + } = useForm(); + + const handleDelete: SubmitHandler = (data) => { + console.log("Deleting... " + JSON.stringify(data)); + }; + + const handleAddToCycle: SubmitHandler = (data) => { + console.log("Adding to cycle..."); + }; + useEffect(() => { document.addEventListener("keydown", handleKeyDown); return () => document.removeEventListener("keydown", handleKeyDown); @@ -137,7 +165,6 @@ const CommandPalette: React.FC = () => { setIsOpen={setIsIssueModalOpen} projectId={activeProject?.id} /> - { leaveTo="opacity-0 scale-95" > - { - const { url, onClick } = item; - if (url) router.push(url); - else if (onClick) onClick(); - handleCommandPaletteClose(); - }} - > -
-
- - + { + // const { url, onClick } = item; + // if (url) router.push(url); + // else if (onClick) onClick(); + // handleCommandPaletteClose(); + // }} > - {filteredIssues.length > 0 && ( - <> +
+
+ + + {filteredIssues.length > 0 && ( + <> +
  • + {query === "" && ( +

    + Issues +

    + )} +
      + {filteredIssues.map((issue) => ( + + classNames( + "flex cursor-pointer select-none items-center rounded-md px-3 py-2", + active ? "bg-gray-900 bg-opacity-5 text-gray-900" : "" + ) + } + > + {({ active }) => ( + <> + {/* + ))} +
    +
  • + + )} + {query === "" && (
  • - {query === "" && ( -

    - Issues -

    - )} +

    Quick actions

      - {filteredIssues.map((issue) => ( + {quickActions.map((action) => ( classNames( - "flex cursor-pointer select-none items-center rounded-md px-3 py-2", + "flex cursor-default select-none items-center rounded-md px-3 py-2", active ? "bg-gray-900 bg-opacity-5 text-gray-900" : "" ) } > {({ active }) => ( <> - ))}
  • - - )} - {query === "" && ( -
  • -

    Quick actions

    -
      - {quickActions.map((action) => ( - - classNames( - "flex cursor-default select-none items-center rounded-md px-3 py-2", - active ? "bg-gray-900 bg-opacity-5 text-gray-900" : "" - ) - } - > - {({ active }) => ( - <> - - ))} -
    -
  • - )} -
    + )} +
    - {query !== "" && filteredIssues.length === 0 && ( -
    -
    diff --git a/apps/app/components/project/cycles/CycleView.tsx b/apps/app/components/project/cycles/CycleView.tsx index 7cc28ed54..dd1ee9041 100644 --- a/apps/app/components/project/cycles/CycleView.tsx +++ b/apps/app/components/project/cycles/CycleView.tsx @@ -175,7 +175,7 @@ const SprintView: React.FC = ({ )) ) : ( -

    This sprint has no issues.

    +

    This cycle has no issues.

    ) ) : (
    diff --git a/apps/app/components/project/issues/BoardView/SingleBoard.tsx b/apps/app/components/project/issues/BoardView/SingleBoard.tsx index 63065de1d..4f2c3b1d6 100644 --- a/apps/app/components/project/issues/BoardView/SingleBoard.tsx +++ b/apps/app/components/project/issues/BoardView/SingleBoard.tsx @@ -18,6 +18,7 @@ import { PlusIcon, } from "@heroicons/react/24/outline"; import Image from "next/image"; +import { divide } from "lodash"; type Props = { selectedGroup: NestedKeyOf | null; @@ -190,7 +191,7 @@ const SingleBoard: React.FC = ({ {(provided, snapshot) => (
    = ({ key={key} className={`${ key === "name" - ? "text-sm font-medium mb-2" + ? "text-sm mb-2" : key === "description" ? "text-xs text-black" : key === "priority" @@ -236,7 +237,7 @@ const SingleBoard: React.FC = ({ ? "text-xs bg-indigo-50 px-2 py-1 mt-2 flex items-center gap-x-1 rounded w-min whitespace-nowrap" : "text-sm text-gray-500" } gap-1 - `} + `} > {key === "target_date" ? ( <> @@ -300,27 +301,27 @@ const SingleBoard: React.FC = ({
    {/*
    + +
    + -
    - - -
    -
    */} + +
    +
    */} )} diff --git a/apps/app/components/project/issues/BoardView/index.tsx b/apps/app/components/project/issues/BoardView/index.tsx index 2dfd5575c..557ec406f 100644 --- a/apps/app/components/project/issues/BoardView/index.tsx +++ b/apps/app/components/project/issues/BoardView/index.tsx @@ -21,6 +21,8 @@ import CreateUpdateIssuesModal from "components/project/issues/CreateUpdateIssue import { Spinner } from "ui"; // types import type { IState, IIssue, Properties, NestedKeyOf, ProjectMember } from "types"; +import ConfirmIssueDeletion from "../ConfirmIssueDeletion"; +import { TrashIcon } from "@heroicons/react/24/outline"; type Props = { properties: Properties; @@ -35,6 +37,8 @@ const BoardView: React.FC = ({ properties, selectedGroup, groupedByIssues const [isOpen, setIsOpen] = useState(false); const [isIssueOpen, setIsIssueOpen] = useState(false); + const [isIssueDeletionOpen, setIsIssueDeletionOpen] = useState(false); + const [issueDeletionData, setIssueDeletionData] = useState(); const [preloadedData, setPreloadedData] = useState< (Partial & { actionType: "createIssue" | "edit" | "delete" }) | undefined @@ -58,72 +62,96 @@ const BoardView: React.FC = ({ properties, selectedGroup, groupedByIssues if (!result.destination) return; const { source, destination, type } = result; - if (type === "state") { - const newStates = Array.from(states ?? []); - const [reorderedState] = newStates.splice(source.index, 1); - newStates.splice(destination.index, 0, reorderedState); - const prevSequenceNumber = newStates[destination.index - 1]?.sequence; - const nextSequenceNumber = newStates[destination.index + 1]?.sequence; + if (destination.droppableId === "trashBox") { + const removedItem = groupedByIssues[source.droppableId][source.index]; - const sequenceNumber = - prevSequenceNumber && nextSequenceNumber - ? (prevSequenceNumber + nextSequenceNumber) / 2 - : nextSequenceNumber - ? nextSequenceNumber - 15000 / 2 - : prevSequenceNumber - ? prevSequenceNumber + 15000 / 2 - : 15000; + setIssueDeletionData(removedItem); + setIsIssueDeletionOpen(true); - newStates[destination.index].sequence = sequenceNumber; - - mutateState(newStates, false); - if (!activeWorkspace) return; - stateServices - .patchState(activeWorkspace.slug, projectId as string, newStates[destination.index].id, { - sequence: sequenceNumber, - }) - .then((response) => { - console.log(response); - }) - .catch((err) => { - console.error(err); - }); + console.log(removedItem); } else { - if (source.droppableId !== destination.droppableId) { - const sourceGroup = source.droppableId; // source group id - const destinationGroup = destination.droppableId; // destination group id - if (!sourceGroup || !destinationGroup) return; + if (type === "state") { + const newStates = Array.from(states ?? []); + const [reorderedState] = newStates.splice(source.index, 1); + newStates.splice(destination.index, 0, reorderedState); + const prevSequenceNumber = newStates[destination.index - 1]?.sequence; + const nextSequenceNumber = newStates[destination.index + 1]?.sequence; - // removed/dragged item - const removedItem = groupedByIssues[source.droppableId][source.index]; + const sequenceNumber = + prevSequenceNumber && nextSequenceNumber + ? (prevSequenceNumber + nextSequenceNumber) / 2 + : nextSequenceNumber + ? nextSequenceNumber - 15000 / 2 + : prevSequenceNumber + ? prevSequenceNumber + 15000 / 2 + : 15000; - if (selectedGroup === "priority") { - // update the removed item for mutation - removedItem.priority = destinationGroup; + newStates[destination.index].sequence = sequenceNumber; - // patch request - issuesServices.patchIssue(activeWorkspace!.slug, projectId as string, removedItem.id, { - priority: destinationGroup, + mutateState(newStates, false); + if (!activeWorkspace) return; + stateServices + .patchState( + activeWorkspace.slug, + projectId as string, + newStates[destination.index].id, + { + sequence: sequenceNumber, + } + ) + .then((response) => { + console.log(response); + }) + .catch((err) => { + console.error(err); }); - } else if (selectedGroup === "state_detail.name") { - const destinationState = states?.find((s) => s.name === destinationGroup); - const destinationStateId = destinationState?.id; + } else { + if (source.droppableId !== destination.droppableId) { + const sourceGroup = source.droppableId; // source group id + const destinationGroup = destination.droppableId; // destination group id + if (!sourceGroup || !destinationGroup) return; - // update the removed item for mutation - if (!destinationStateId || !destinationState) return; - removedItem.state = destinationStateId; - removedItem.state_detail = destinationState; + // removed/dragged item + const removedItem = groupedByIssues[source.droppableId][source.index]; - // patch request - issuesServices.patchIssue(activeWorkspace!.slug, projectId as string, removedItem.id, { - state: destinationStateId, - }); + if (selectedGroup === "priority") { + // update the removed item for mutation + removedItem.priority = destinationGroup; + + // patch request + issuesServices.patchIssue( + activeWorkspace!.slug, + projectId as string, + removedItem.id, + { + priority: destinationGroup, + } + ); + } else if (selectedGroup === "state_detail.name") { + const destinationState = states?.find((s) => s.name === destinationGroup); + const destinationStateId = destinationState?.id; + + // update the removed item for mutation + if (!destinationStateId || !destinationState) return; + removedItem.state = destinationStateId; + removedItem.state_detail = destinationState; + + // patch request + issuesServices.patchIssue( + activeWorkspace!.slug, + projectId as string, + removedItem.id, + { + state: destinationStateId, + } + ); + } + + // remove item from the source group + groupedByIssues[source.droppableId].splice(source.index, 1); + // add item to the destination group + groupedByIssues[destination.droppableId].splice(destination.index, 0, removedItem); } - - // remove item from the source group - groupedByIssues[source.droppableId].splice(source.index, 1); - // add item to the destination group - groupedByIssues[destination.droppableId].splice(destination.index, 0, removedItem); } } }, @@ -155,6 +183,11 @@ const BoardView: React.FC = ({ properties, selectedGroup, groupedByIssues setIsOpen={setIsOpen} data={preloadedData as Partial} /> */} + setIsIssueDeletionOpen(false)} + data={issueDeletionData} + /> = ({ properties, selectedGroup, groupedByIssues projectId={projectId as string} /> {groupedByIssues ? ( - groupedByIssues ? ( -
    - -
    - - {(provided) => ( -
    -
    - {Object.keys(groupedByIssues).map((singleGroup, index) => ( - m.member.id === singleGroup)?.member - .first_name - : undefined - } - groupedByIssues={groupedByIssues} - index={index} - setIsIssueOpen={setIsIssueOpen} - properties={properties} - setPreloadedData={setPreloadedData} - stateId={ - selectedGroup === "state_detail.name" - ? states?.find((s) => s.name === singleGroup)?.id - : undefined - } - bgColor={ - selectedGroup === "state_detail.name" - ? states?.find((s) => s.name === singleGroup)?.color - : undefined - } - /> - ))} -
    - {provided.placeholder} +
    + + {/* + {(provided, snapshot) => ( + + )} + */} +
    + + {(provided) => ( +
    +
    + {Object.keys(groupedByIssues).map((singleGroup, index) => ( + m.member.id === singleGroup)?.member.first_name + : undefined + } + groupedByIssues={groupedByIssues} + index={index} + setIsIssueOpen={setIsIssueOpen} + properties={properties} + setPreloadedData={setPreloadedData} + stateId={ + selectedGroup === "state_detail.name" + ? states?.find((s) => s.name === singleGroup)?.id + : undefined + } + bgColor={ + selectedGroup === "state_detail.name" + ? states?.find((s) => s.name === singleGroup)?.color + : undefined + } + /> + ))}
    - )} - -
    - -
    - ) : null + {provided.placeholder} +
    + )} + +
    + +
    ) : ( -
    +
    )} diff --git a/apps/app/components/project/issues/CreateUpdateIssueModal/SelectParentIssues.tsx b/apps/app/components/project/issues/CreateUpdateIssueModal/SelectParentIssues.tsx index 7fead660b..83db0b895 100644 --- a/apps/app/components/project/issues/CreateUpdateIssueModal/SelectParentIssues.tsx +++ b/apps/app/components/project/issues/CreateUpdateIssueModal/SelectParentIssues.tsx @@ -52,6 +52,7 @@ const SelectParent: React.FC = ({ control }) => { }; })} value={value} + width="xs" buttonClassName="max-h-30 overflow-y-scroll" optionsClassName="max-h-30 overflow-y-scroll" onChange={onChange} diff --git a/apps/app/components/project/issues/ListView/index.tsx b/apps/app/components/project/issues/ListView/index.tsx index 9c12ac1c3..ff6fc68d9 100644 --- a/apps/app/components/project/issues/ListView/index.tsx +++ b/apps/app/components/project/issues/ListView/index.tsx @@ -77,11 +77,11 @@ const ListView: React.FC = ({ const handleHover = (issueId: string) => { document.addEventListener("keydown", (e) => { - if (e.code === "Space") { - e.preventDefault(); - setPreviewModalIssueId(issueId); - setIssuePreviewModal(true); - } + // if (e.code === "Space") { + // e.preventDefault(); + // setPreviewModalIssueId(issueId); + // setIssuePreviewModal(true); + // } }); }; diff --git a/apps/app/components/project/issues/issue-detail/IssueDetailSidebar.tsx b/apps/app/components/project/issues/issue-detail/IssueDetailSidebar.tsx index 985146cdc..efa2aebc2 100644 --- a/apps/app/components/project/issues/issue-detail/IssueDetailSidebar.tsx +++ b/apps/app/components/project/issues/issue-detail/IssueDetailSidebar.tsx @@ -21,7 +21,7 @@ import { // commons import { classNames, copyTextToClipboard } from "constants/common"; // ui -import { Input, Button } from "ui"; +import { Input, Button, Spinner } from "ui"; // icons import { UserIcon, @@ -32,6 +32,7 @@ import { ChartBarIcon, ClipboardDocumentIcon, LinkIcon, + ArrowPathIcon, } from "@heroicons/react/24/outline"; // types import type { Control } from "react-hook-form"; @@ -50,7 +51,7 @@ const defaultValues: Partial = { }; const IssueDetailSidebar: React.FC = ({ control, submitChanges, issueDetail }) => { - const { activeWorkspace, activeProject } = useUser(); + const { activeWorkspace, activeProject, cycles } = useUser(); const { data: states } = useSWR( activeWorkspace && activeProject ? STATE_LIST(activeProject.id) : null, @@ -121,6 +122,16 @@ const IssueDetailSidebar: React.FC = ({ control, submitChanges, issueDeta value: state.id, })), }, + { + label: "Cycle", + name: "cycle", + canSelectMultipleOptions: false, + icon: ArrowPathIcon, + options: cycles?.map((cycle) => ({ + label: cycle.name, + value: cycle.id, + })), + }, { label: "Assignees", name: "assignees_list", @@ -153,6 +164,13 @@ const IssueDetailSidebar: React.FC = ({ control, submitChanges, issueDeta }, ]; + const handleCycleChange = (cycleId: string) => { + if (activeWorkspace && activeProject && issueDetail) + issuesServices.addIssueToSprint(activeWorkspace.slug, activeProject.id, cycleId, { + issue: issueDetail.id, + }); + }; + return (
    @@ -193,7 +211,10 @@ const IssueDetailSidebar: React.FC = ({ control, submitChanges, issueDeta as="div" value={value} multiple={item.canSelectMultipleOptions} - onChange={(value: any) => submitChanges({ [item.name]: value })} + onChange={(value: any) => { + if (item.name === "cycle") handleCycleChange(value); + else submitChanges({ [item.name]: value }); + }} className="flex-shrink-0" > {({ open }) => ( @@ -229,21 +250,31 @@ const IssueDetailSidebar: React.FC = ({ control, submitChanges, issueDeta >
    - {item.options?.map((option) => ( - - `${ - active || selected ? "text-white bg-theme" : "text-gray-900" - } ${ - item.label === "Priority" && "capitalize" - } cursor-pointer select-none relative p-2 rounded-md truncate` - } - value={option.value} - > - {option.label} - - ))} + {item.options ? ( + item.options.length > 0 ? ( + item.options.map((option) => ( + + `${ + active || selected + ? "text-white bg-theme" + : "text-gray-900" + } ${ + item.label === "Priority" && "capitalize" + } cursor-pointer select-none relative p-2 rounded-md truncate` + } + value={option.value} + > + {option.label} + + )) + ) : ( +
    No {item.label}s found
    + ) + ) : ( + + )}
    @@ -321,19 +352,29 @@ const IssueDetailSidebar: React.FC = ({ control, submitChanges, issueDeta >
    - {issueLabels?.map((label: any) => ( - - `${ - active || selected ? "text-white bg-theme" : "text-gray-900" - } cursor-pointer select-none relative p-2 rounded-md truncate` - } - value={label.id} - > - {label.name} - - ))} + {issueLabels ? ( + issueLabels.length > 0 ? ( + issueLabels.map((label: any) => ( + + `${ + active || selected + ? "text-white bg-theme" + : "text-gray-900" + } cursor-pointer select-none relative p-2 rounded-md truncate` + } + value={label.id} + > + {label.name} + + )) + ) : ( +
    No labels found
    + ) + ) : ( + + )}
    diff --git a/apps/app/components/project/issues/issue-detail/activity/index.tsx b/apps/app/components/project/issues/issue-detail/activity/index.tsx index c48ba6ea8..45965ca24 100644 --- a/apps/app/components/project/issues/issue-detail/activity/index.tsx +++ b/apps/app/components/project/issues/issue-detail/activity/index.tsx @@ -45,7 +45,7 @@ const IssueActivitySection: React.FC = ({ issueActivities, states }) => {
    ) : ( -
    +
    {activity.actor_detail.avatar && activity.actor_detail.avatar !== "" ? (
    diff --git a/apps/app/components/workspace/SingleInvitation.tsx b/apps/app/components/workspace/SingleInvitation.tsx new file mode 100644 index 000000000..27614e984 --- /dev/null +++ b/apps/app/components/workspace/SingleInvitation.tsx @@ -0,0 +1,77 @@ +// next +import Image from "next/image"; +// react +import { useState } from "react"; +// types +import { IWorkspaceInvitation } from "types"; + +type Props = { + invitation: IWorkspaceInvitation; + invitationsRespond: string[]; + handleInvitation: any; +}; + +const SingleInvitation: React.FC = ({ + invitation, + invitationsRespond, + handleInvitation, +}) => { + const [isChecked, setIsChecked] = useState(invitationsRespond.includes(invitation.id)); + + return ( + <> +
  • + +
  • + + ); +}; + +export default SingleInvitation; diff --git a/apps/app/contexts/user.context.tsx b/apps/app/contexts/user.context.tsx index 55037af14..6b52b0939 100644 --- a/apps/app/contexts/user.context.tsx +++ b/apps/app/contexts/user.context.tsx @@ -16,7 +16,6 @@ import { CURRENT_USER, PROJECTS_LIST, USER_WORKSPACES, - USER_WORKSPACE_INVITATIONS, PROJECT_ISSUES_LIST, STATE_LIST, CYCLE_LIST, @@ -24,7 +23,8 @@ import { // types import type { KeyedMutator } from "swr"; -import type { IUser, IWorkspace, IProject, IIssue, IssueResponse, ICycle, IState } from "types"; +import type { IUser, IWorkspace, IProject, IssueResponse, ICycle, IState } from "types"; + interface IUserContextProps { user?: IUser; isUserLoading: boolean; @@ -38,8 +38,8 @@ interface IUserContextProps { activeProject?: IProject; issues?: IssueResponse; mutateIssues: KeyedMutator; - sprints?: ICycle[]; - mutateSprints: KeyedMutator; + cycles?: ICycle[]; + mutateCycles: KeyedMutator; states?: IState[]; mutateStates: KeyedMutator; } @@ -92,7 +92,7 @@ export const UserProvider = ({ children }: { children: ReactElement }) => { : null ); - const { data: sprints, mutate: mutateSprints } = useSWR( + const { data: cycles, mutate: mutateCycles } = useSWR( activeWorkspace && activeProject ? CYCLE_LIST(activeProject.id) : null, activeWorkspace && activeProject ? () => sprintsServices.getCycles(activeWorkspace.slug, activeProject.id) @@ -141,8 +141,8 @@ export const UserProvider = ({ children }: { children: ReactElement }) => { activeProject, issues, mutateIssues, - sprints, - mutateSprints, + cycles, + mutateCycles, states, mutateStates, setActiveProject, diff --git a/apps/app/layouts/Navbar/Sidebar.tsx b/apps/app/layouts/Navbar/Sidebar.tsx index 03863f4cf..48c6f7842 100644 --- a/apps/app/layouts/Navbar/Sidebar.tsx +++ b/apps/app/layouts/Navbar/Sidebar.tsx @@ -28,11 +28,13 @@ import { XMarkIcon, ArrowLongLeftIcon, QuestionMarkCircleIcon, + EllipsisHorizontalIcon, + ClipboardDocumentIcon, } from "@heroicons/react/24/outline"; // constants -import { classNames } from "constants/common"; +import { classNames, copyTextToClipboard } from "constants/common"; // ui -import { Spinner, Tooltip } from "ui"; +import { CustomListbox, Spinner, Tooltip } from "ui"; // types import type { IUser } from "types"; @@ -423,23 +425,66 @@ const Sidebar: React.FC = () => { {({ open }) => ( <> - - - {project?.name.charAt(0)} - - {!sidebarCollapse && ( - - {project?.name} - +
    + + + {project?.name.charAt(0)} + {!sidebarCollapse && ( + + {project?.name} + + + + + )} + + {!sidebarCollapse && ( + + + + + + + +
    + + {(active) => ( + + )} + +
    +
    +
    +
    )} - +
    { )}
    - + +
    diff --git a/apps/app/pages/me/my-issues.tsx b/apps/app/pages/me/my-issues.tsx index 91f79ae81..eaf206a26 100644 --- a/apps/app/pages/me/my-issues.tsx +++ b/apps/app/pages/me/my-issues.tsx @@ -145,7 +145,9 @@ const MyIssues: NextPage = () => { {myIssue.name} - {myIssue.description} + + {myIssue.description} + {myIssue.project_detail?.name}
    diff --git a/apps/app/pages/projects/[projectId]/cycles.tsx b/apps/app/pages/projects/[projectId]/cycles.tsx index be21dfc41..eec2bbc91 100644 --- a/apps/app/pages/projects/[projectId]/cycles.tsx +++ b/apps/app/pages/projects/[projectId]/cycles.tsx @@ -14,21 +14,18 @@ import { CYCLE_ISSUES, CYCLE_LIST } from "constants/fetch-keys"; // layouts import AdminLayout from "layouts/AdminLayout"; // components -import SprintView from "components/project/cycles/CycleView"; +import CycleView 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"; +import { BreadcrumbItem, Breadcrumbs, HeaderButton, Spinner, EmptySpace, EmptySpaceItem } from "ui"; // icons import { PlusIcon } from "@heroicons/react/20/solid"; +import { ArrowPathIcon } from "@heroicons/react/24/outline"; // 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); @@ -44,7 +41,7 @@ const ProjectSprints: NextPage = () => { const { projectId } = router.query; - const { data: sprints } = useSWR( + const { data: cycles } = useSWR( projectId && activeWorkspace ? CYCLE_LIST(projectId as string) : null, activeWorkspace && projectId ? () => sprintService.getCycles(activeWorkspace.slug, projectId as string) @@ -52,14 +49,14 @@ const ProjectSprints: NextPage = () => { ); const openIssueModal = ( - sprintId: string, + cycleId: string, issue?: IIssue, actionType: "create" | "edit" | "delete" = "create" ) => { - const sprint = sprints?.find((sprint) => sprint.id === sprintId); - if (sprint) { + const cycle = cycles?.find((cycle) => cycle.id === cycleId); + if (cycle) { setSelectedSprint({ - ...sprint, + ...cycle, actionType: "create-issue", }); if (issue) setSelectedIssues({ ...issue, actionType }); @@ -67,16 +64,16 @@ const ProjectSprints: NextPage = () => { } }; - const addIssueToSprint = (sprintId: string, issueId: string) => { + const addIssueToSprint = (cycleId: string, issueId: string) => { if (!activeWorkspace || !projectId) return; issuesServices - .addIssueToSprint(activeWorkspace.slug, projectId as string, sprintId, { + .addIssueToSprint(activeWorkspace.slug, projectId as string, cycleId, { issue: issueId, }) .then((response) => { console.log(response); - mutate(CYCLE_ISSUES(sprintId)); + mutate(CYCLE_ISSUES(cycleId)); }) .catch((error) => { console.log(error); @@ -134,8 +131,8 @@ const ProjectSprints: NextPage = () => { setIsOpen={setIsOpen} projectId={projectId as string} /> - {sprints ? ( - sprints.length > 0 ? ( + {cycles ? ( + cycles.length > 0 ? (
    @@ -146,15 +143,15 @@ const ProjectSprints: NextPage = () => { setIsOpen(true)} />
    - {sprints.map((sprint) => ( - ( + ))}
    diff --git a/apps/app/pages/projects/[projectId]/issues/[issueId].tsx b/apps/app/pages/projects/[projectId]/issues/[issueId].tsx index 0c3471983..4d98b33c5 100644 --- a/apps/app/pages/projects/[projectId]/issues/[issueId].tsx +++ b/apps/app/pages/projects/[projectId]/issues/[issueId].tsx @@ -162,12 +162,14 @@ const IssueDetail: NextPage = () => { />
    -

    {`${activeProject?.name}/${activeProject?.identifier}-${issueDetail?.sequence_id}`}

    +

    {`${activeProject?.name ?? "Project"}/${ + activeProject?.identifier ?? "..." + }-${issueDetail?.sequence_id ?? "..."}`}

    { if (!prevIssue) return; router.push(`/projects/${prevIssue.project}/issues/${prevIssue.id}`); @@ -177,6 +179,7 @@ const IssueDetail: NextPage = () => { Icon={ChevronRightIcon} disabled={!nextIssue} label="Next" + className={`${!nextIssue ? "cursor-not-allowed opacity-70" : ""}`} onClick={() => { if (!nextIssue) return; router.push(`/projects/${nextIssue.project}/issues/${nextIssue?.id}`); @@ -188,7 +191,7 @@ const IssueDetail: NextPage = () => { {issueDetail && activeProject ? (
    -
    +