diff --git a/apps/app/components/command-palette/index.tsx b/apps/app/components/command-palette/index.tsx index 671aa9509d1..b58525459bc 100644 --- a/apps/app/components/command-palette/index.tsx +++ b/apps/app/components/command-palette/index.tsx @@ -8,11 +8,10 @@ import useSWR from "swr"; // hooks import useTheme from "lib/hooks/useTheme"; import useToast from "lib/hooks/useToast"; -// constants -import { PROJECT_DETAILS, PROJECT_ISSUES_LIST } from "constants/fetch-keys"; // services import issuesServices from "lib/services/issues.service"; -import projectService from "lib/services/project.service"; +import projectServices from "lib/services/project.service"; +import userService from "lib/services/user.service"; // components import ShortcutsModal from "components/command-palette/shortcuts"; import { CreateProjectModal } from "components/project"; @@ -22,6 +21,8 @@ import CreateUpdateModuleModal from "components/project/modules/create-update-mo import BulkDeleteIssuesModal from "components/common/bulk-delete-issues-modal"; // headless ui import { Combobox, Dialog, Transition } from "@headlessui/react"; +// constants +import { PROJECTS_LIST, PROJECT_ISSUES_LIST, USER_ISSUE } from "constants/fetch-keys"; // ui import { Button } from "ui"; // icons @@ -48,8 +49,12 @@ const CommandPalette: React.FC = () => { const [isBulkDeleteIssuesModalOpen, setIsBulkDeleteIssuesModalOpen] = useState(false); const router = useRouter(); + const { workspaceSlug, projectId } = router.query; + const { setToastAlert } = useToast(); + const { toggleCollapsed } = useTheme(); + const { data: issues } = useSWR( workspaceSlug && projectId ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string) @@ -59,20 +64,23 @@ const CommandPalette: React.FC = () => { : null ); - const { data: projectDetails } = useSWR( - workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null, - workspaceSlug && projectId - ? () => projectService.getProject(workspaceSlug as string, projectId as string) - : null + const { data: myIssues } = useSWR( + workspaceSlug ? USER_ISSUE(workspaceSlug as string) : null, + workspaceSlug ? () => userService.userIssues(workspaceSlug as string) : null ); - const { toggleCollapsed } = useTheme(); + const { data: projects } = useSWR( + workspaceSlug ? PROJECTS_LIST(workspaceSlug as string) : null, + workspaceSlug ? () => projectServices.getProjects(workspaceSlug as string) : null + ); - const { setToastAlert } = useToast(); + const activeProject = !projectId + ? projects?.[0] + : projects?.find((project) => project.id === projectId); const filteredIssues: IIssue[] = query === "" - ? issues?.results ?? [] + ? issues?.results ?? myIssues ?? [] : issues?.results.filter((issue) => issue.name.toLowerCase().includes(query.toLowerCase())) ?? []; @@ -159,25 +167,25 @@ const CommandPalette: React.FC = () => { <> - {projectId && ( + {activeProject && ( <> + )} - { }} /> - {projectDetails?.identifier}-{issue.sequence_id} + {activeProject?.identifier}-{issue.sequence_id} {issue.name} diff --git a/apps/app/components/common/bulk-delete-issues-modal.tsx b/apps/app/components/common/bulk-delete-issues-modal.tsx index 5f6370ce3dd..3dca96704d0 100644 --- a/apps/app/components/common/bulk-delete-issues-modal.tsx +++ b/apps/app/components/common/bulk-delete-issues-modal.tsx @@ -8,8 +8,8 @@ import useSWR, { mutate } from "swr"; import { SubmitHandler, useForm } from "react-hook-form"; // services import issuesServices from "lib/services/issues.service"; +import projectService from "lib/services/project.service"; // hooks -import useUser from "lib/hooks/useUser"; import useToast from "lib/hooks/useToast"; // headless ui import { Combobox, Dialog, Transition } from "@headlessui/react"; @@ -20,7 +20,7 @@ import { FolderIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline"; // types import { IIssue, IssueResponse } from "types"; // fetch keys -import { PROJECT_ISSUES_LIST } from "constants/fetch-keys"; +import { PROJECT_ISSUES_LIST, PROJECT_DETAILS } from "constants/fetch-keys"; // common import { classNames } from "constants/common"; @@ -40,30 +40,35 @@ const BulkDeleteIssuesModal: React.FC = ({ isOpen, setIsOpen }) => { const router = useRouter(); const { - query: { workspaceSlug }, + query: { workspaceSlug, projectId }, } = router; - const { activeWorkspace, activeProject } = useUser(); - const { data: issues } = useSWR( - activeWorkspace && activeProject - ? PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId + ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string) : null, - activeWorkspace && activeProject - ? () => issuesServices.getIssues(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId + ? () => issuesServices.getIssues(workspaceSlug as string, projectId as string) + : null + ); + + const { data: projectDetails } = useSWR( + workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null, + workspaceSlug && projectId + ? () => projectService.getProject(workspaceSlug as string, projectId as string) : null ); const { setToastAlert } = useToast(); + const { register, handleSubmit, reset } = useForm(); + const filteredIssues: IIssue[] = query === "" ? issues?.results ?? [] : issues?.results.filter((issue) => issue.name.toLowerCase().includes(query.toLowerCase())) ?? []; - const { register, handleSubmit, reset } = useForm(); - const handleClose = () => { setIsOpen(false); setQuery(""); @@ -80,9 +85,9 @@ const BulkDeleteIssuesModal: React.FC = ({ isOpen, setIsOpen }) => { return; } - if (activeWorkspace && activeProject) { + if (workspaceSlug && projectId) { issuesServices - .bulkDeleteIssues(activeWorkspace.slug, activeProject.id, data) + .bulkDeleteIssues(workspaceSlug as string, projectId as string, data) .then((res) => { setToastAlert({ title: "Success", @@ -90,7 +95,7 @@ const BulkDeleteIssuesModal: React.FC = ({ isOpen, setIsOpen }) => { message: res.message, }); mutate( - PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id), + PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string), (prevData) => { return { ...(prevData as IssueResponse), @@ -197,7 +202,7 @@ const BulkDeleteIssuesModal: React.FC = ({ isOpen, setIsOpen }) => { }} /> - {activeProject?.identifier}-{issue.sequence_id} + {projectDetails?.identifier}-{issue.sequence_id} {issue.name} diff --git a/apps/app/components/common/list-view/single-issue.tsx b/apps/app/components/common/list-view/single-issue.tsx index 2ec970294e0..8635cb80dd5 100644 --- a/apps/app/components/common/list-view/single-issue.tsx +++ b/apps/app/components/common/list-view/single-issue.tsx @@ -79,10 +79,6 @@ const SingleListIssue: React.FC = ({ )} {issue.name} - {/*
-
Name
-
{issue.name}
-
*/} diff --git a/apps/app/components/project/confirm-project-deletion.tsx b/apps/app/components/project/confirm-project-deletion.tsx index 159ef8db444..4e7c7efcd88 100644 --- a/apps/app/components/project/confirm-project-deletion.tsx +++ b/apps/app/components/project/confirm-project-deletion.tsx @@ -1,4 +1,6 @@ import React, { useEffect, useRef, useState } from "react"; +// next +import { useRouter } from "next/router"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services @@ -21,15 +23,17 @@ type Props = { const ConfirmProjectDeletion: React.FC = ({ isOpen, data, onClose }) => { const [isDeleteLoading, setIsDeleteLoading] = useState(false); - - const [selectedProject, setSelectedProject] = useState(null); - const [confirmProjectName, setConfirmProjectName] = useState(""); const [confirmDeleteMyProject, setConfirmDeleteMyProject] = useState(false); + const [selectedProject, setSelectedProject] = useState(null); const canDelete = confirmProjectName === data?.name && confirmDeleteMyProject; - const { activeWorkspace, mutateProjects } = useUser(); + const router = useRouter(); + + const { + query: { workspaceSlug }, + } = router; const { setToastAlert } = useToast(); @@ -47,12 +51,12 @@ const ConfirmProjectDeletion: React.FC = ({ isOpen, data, onClose }) => { const handleDeletion = async () => { setIsDeleteLoading(true); - if (!data || !activeWorkspace || !canDelete) return; + if (!data || !workspaceSlug || !canDelete) return; await projectService - .deleteProject(activeWorkspace.slug, data.id) + .deleteProject(workspaceSlug as string, data.id) .then(() => { handleClose(); - mutateProjects((prevData) => (prevData ?? []).filter((item) => item.id !== data.id), false); + // TODO: add project mutation here setToastAlert({ title: "Success", type: "success", @@ -127,7 +131,7 @@ const ConfirmProjectDeletion: React.FC = ({ isOpen, data, onClose }) => { removed. This action cannot be undone.

-
+

Enter the project name{" "} diff --git a/apps/app/components/project/create-project-modal.tsx b/apps/app/components/project/create-project-modal.tsx index eb9a5e12b79..24bccb6f37f 100644 --- a/apps/app/components/project/create-project-modal.tsx +++ b/apps/app/components/project/create-project-modal.tsx @@ -15,14 +15,8 @@ import { createSimilarString, getRandomEmoji } from "constants/common"; // constants import { NETWORK_CHOICES } from "constants/"; // fetch keys -import { - PROJECTS_LIST, - WORKSPACE_DETAILS, - WORKSPACE_MEMBERS, - WORKSPACE_MEMBERS_ME, -} from "constants/fetch-keys"; +import { PROJECTS_LIST, WORKSPACE_DETAILS, WORKSPACE_MEMBERS_ME } from "constants/fetch-keys"; // hooks -import useUser from "lib/hooks/useUser"; import useToast from "lib/hooks/useToast"; // ui import { Button, Input, TextArea, Select, EmojiIconPicker } from "ui"; @@ -169,20 +163,10 @@ export const CreateProjectModal: React.FC = (props) => { }; // FIXME: remove this and authorize using getServerSideProps - - if (myWorkspaceMembership) { + if (myWorkspaceMembership && isOpen) { if (myWorkspaceMembership.role <= 10) return ; } - // if (workspaceMembers) { - // const isMember = workspaceMembers.find((member) => member.member.id === user?.id); - // const isGuest = workspaceMembers.find( - // (member) => member.member.id === user?.id && member.role === 5 - // ); - - // if ((!isMember || isGuest) && isOpen) return ; - // } - return (

diff --git a/apps/app/components/project/cycles/confirm-cycle-deletion.tsx b/apps/app/components/project/cycles/confirm-cycle-deletion.tsx index b3571831a3e..51e93d3df79 100644 --- a/apps/app/components/project/cycles/confirm-cycle-deletion.tsx +++ b/apps/app/components/project/cycles/confirm-cycle-deletion.tsx @@ -1,4 +1,6 @@ import React, { useEffect, useRef, useState } from "react"; +// next +import { useRouter } from "next/router"; // swr import { mutate } from "swr"; // headless ui @@ -23,11 +25,14 @@ type Props = { }; const ConfirmCycleDeletion: React.FC = ({ isOpen, setIsOpen, data }) => { + const cancelButtonRef = useRef(null); const [isDeleteLoading, setIsDeleteLoading] = useState(false); - const { activeWorkspace } = useUser(); + const router = useRouter(); - const cancelButtonRef = useRef(null); + const { + query: { workspaceSlug }, + } = router; const handleClose = () => { setIsOpen(false); @@ -36,9 +41,9 @@ const ConfirmCycleDeletion: React.FC = ({ isOpen, setIsOpen, data }) => { const handleDeletion = async () => { setIsDeleteLoading(true); - if (!data || !activeWorkspace) return; + if (!data || !workspaceSlug) return; await cycleService - .deleteCycle(activeWorkspace.slug, data.project, data.id) + .deleteCycle(workspaceSlug as string, data.project, data.id) .then(() => { mutate( CYCLE_LIST(data.project), diff --git a/apps/app/components/project/cycles/create-update-cycle-modal.tsx b/apps/app/components/project/cycles/create-update-cycle-modal.tsx index 5d52183b857..b63e22b4f66 100644 --- a/apps/app/components/project/cycles/create-update-cycle-modal.tsx +++ b/apps/app/components/project/cycles/create-update-cycle-modal.tsx @@ -1,4 +1,6 @@ import React, { useEffect } from "react"; +// next +import { useRouter } from "next/router"; // swr import { mutate } from "swr"; // react hook form @@ -39,7 +41,11 @@ const CreateUpdateCycleModal: React.FC = ({ isOpen, setIsOpen, data, proj }, 500); }; - const { activeWorkspace } = useUser(); + const router = useRouter(); + + const { + query: { workspaceSlug }, + } = router; const { register, @@ -52,7 +58,7 @@ const CreateUpdateCycleModal: React.FC = ({ isOpen, setIsOpen, data, proj }); const onSubmit = async (formData: ICycle) => { - if (!activeWorkspace) return; + if (!workspaceSlug) return; const payload = { ...formData, start_date: formData.start_date ? renderDateFormat(formData.start_date) : null, @@ -60,7 +66,7 @@ const CreateUpdateCycleModal: React.FC = ({ isOpen, setIsOpen, data, proj }; if (!data) { await cycleService - .createCycle(activeWorkspace.slug, projectId, payload) + .createCycle(workspaceSlug as string, projectId, payload) .then((res) => { mutate(CYCLE_LIST(projectId), (prevData) => [res, ...(prevData ?? [])], false); handleClose(); @@ -74,7 +80,7 @@ const CreateUpdateCycleModal: React.FC = ({ isOpen, setIsOpen, data, proj }); } else { await cycleService - .updateCycle(activeWorkspace.slug, projectId, data.id, payload) + .updateCycle(workspaceSlug as string, projectId, data.id, payload) .then((res) => { mutate( CYCLE_LIST(projectId), diff --git a/apps/app/components/project/cycles/cycle-detail-sidebar/index.tsx b/apps/app/components/project/cycles/cycle-detail-sidebar/index.tsx index 1244117251f..af0f8cb1c80 100644 --- a/apps/app/components/project/cycles/cycle-detail-sidebar/index.tsx +++ b/apps/app/components/project/cycles/cycle-detail-sidebar/index.tsx @@ -37,16 +37,14 @@ const defaultValues: Partial = { }; const CycleDetailSidebar: React.FC = ({ cycle, cycleIssues }) => { - const { activeWorkspace, activeProject } = useUser(); - const router = useRouter(); const { - query: { workspaceSlug }, + query: { workspaceSlug, projectId }, } = router; const { setToastAlert } = useToast(); - const { reset, watch, control } = useForm({ + const { reset, control } = useForm({ defaultValues, }); @@ -60,10 +58,10 @@ const CycleDetailSidebar: React.FC = ({ cycle, cycleIssues }) => { }; const submitChanges = (data: Partial) => { - if (!activeWorkspace || !activeProject || !module) return; + if (!workspaceSlug || !projectId || !module) return; cyclesService - .patchCycle(activeWorkspace.slug, activeProject.id, cycle?.id ?? "", data) + .patchCycle(workspaceSlug as string, projectId as string, cycle?.id ?? "", data) .then((res) => { console.log(res); mutate(CYCLE_DETAIL); @@ -73,8 +71,6 @@ const CycleDetailSidebar: React.FC = ({ cycle, cycleIssues }) => { }); }; - const handleDeleteCycle = () => {}; - useEffect(() => { if (cycle) reset({ @@ -94,7 +90,7 @@ const CycleDetailSidebar: React.FC = ({ cycle, cycleIssues }) => { className="rounded-md border p-2 shadow-sm duration-300 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500" onClick={() => copyTextToClipboard( - `https://app.plane.so/${workspaceSlug}/projects/${activeProject?.id}/cycles/${cycle.id}` + `https://app.plane.so/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}` ) .then(() => { setToastAlert({ @@ -112,13 +108,6 @@ const CycleDetailSidebar: React.FC = ({ cycle, cycleIssues }) => { > - {/* */}
diff --git a/apps/app/components/project/cycles/list-view/index.tsx b/apps/app/components/project/cycles/list-view/index.tsx index bde15766ab5..5c6552c5436 100644 --- a/apps/app/components/project/cycles/list-view/index.tsx +++ b/apps/app/components/project/cycles/list-view/index.tsx @@ -1,8 +1,9 @@ -// react import React from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR from "swr"; -// headless ui + import { Disclosure, Transition } from "@headlessui/react"; // services import workspaceService from "lib/services/workspace.service"; @@ -52,17 +53,18 @@ const CyclesListView: React.FC = ({ handleDeleteIssue, setPreloadedData, }) => { - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const { data: people } = useSWR( - activeWorkspace ? WORKSPACE_MEMBERS : null, - activeWorkspace ? () => workspaceService.workspaceMembers(activeWorkspace.slug) : null + workspaceSlug ? WORKSPACE_MEMBERS : null, + workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug as string) : null ); const { data: states } = useSWR( - activeWorkspace && activeProject ? STATE_LIST(activeProject.id) : null, - activeWorkspace && activeProject - ? () => stateService.getStates(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, + workspaceSlug && projectId + ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); diff --git a/apps/app/components/project/issues/BoardView/single-board.tsx b/apps/app/components/project/issues/BoardView/single-board.tsx index 642cb3c2655..46c07468954 100644 --- a/apps/app/components/project/issues/BoardView/single-board.tsx +++ b/apps/app/components/project/issues/BoardView/single-board.tsx @@ -1,8 +1,9 @@ -// react import React, { useState } from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR from "swr"; -// react-beautiful-dnd + import { Draggable } from "react-beautiful-dnd"; import StrictModeDroppable from "components/dnd/StrictModeDroppable"; // services @@ -63,7 +64,8 @@ const SingleBoard: React.FC = ({ // Collapse/Expand const [show, setShow] = useState(true); - const { activeWorkspace } = useUser(); + const router = useRouter(); + const { workspaceSlug } = router.query; if (selectedGroup === "priority") groupTitle === "high" @@ -75,8 +77,8 @@ const SingleBoard: React.FC = ({ : (bgColor = "#ff0000"); const { data: people } = useSWR( - activeWorkspace ? WORKSPACE_MEMBERS : null, - activeWorkspace ? () => workspaceService.workspaceMembers(activeWorkspace.slug) : null + workspaceSlug ? WORKSPACE_MEMBERS : null, + workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug as string) : null ); return ( diff --git a/apps/app/components/project/issues/BoardView/state/confirm-state-delete.tsx b/apps/app/components/project/issues/BoardView/state/confirm-state-delete.tsx index e8f36fcd582..e2364edbbd5 100644 --- a/apps/app/components/project/issues/BoardView/state/confirm-state-delete.tsx +++ b/apps/app/components/project/issues/BoardView/state/confirm-state-delete.tsx @@ -1,15 +1,15 @@ import React, { useEffect, useRef, useState } from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR, { mutate } from "swr"; -// headless ui + import { Dialog, Transition } from "@headlessui/react"; // services import stateServices from "lib/services/state.service"; import issuesServices from "lib/services/issues.service"; // fetch api import { STATE_LIST, PROJECT_ISSUES_LIST } from "constants/fetch-keys"; -// hooks -import useUser from "lib/hooks/useUser"; // common import { groupBy } from "constants/common"; // icons @@ -27,17 +27,17 @@ type Props = { const ConfirmStateDeletion: React.FC = ({ isOpen, onClose, data }) => { const [isDeleteLoading, setIsDeleteLoading] = useState(false); - const [issuesWithThisStateExist, setIssuesWithThisStateExist] = useState(true); - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const { data: issues } = useSWR( - activeWorkspace && activeProject - ? PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId + ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string) : null, - activeWorkspace && activeProject - ? () => issuesServices.getIssues(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId + ? () => issuesServices.getIssues(workspaceSlug as string, projectId as string) : null ); @@ -50,9 +50,9 @@ const ConfirmStateDeletion: React.FC = ({ isOpen, onClose, data }) => { const handleDeletion = async () => { setIsDeleteLoading(true); - if (!data || !activeWorkspace || issuesWithThisStateExist) return; + if (!data || !workspaceSlug || issuesWithThisStateExist) return; await stateServices - .deleteState(activeWorkspace.slug, data.project, data.id) + .deleteState(workspaceSlug as string, data.project, data.id) .then(() => { mutate( STATE_LIST(data.project), diff --git a/apps/app/components/project/issues/BoardView/state/create-update-state-modal.tsx b/apps/app/components/project/issues/BoardView/state/create-update-state-modal.tsx index 4cd5a13677d..bbd8698eae2 100644 --- a/apps/app/components/project/issues/BoardView/state/create-update-state-modal.tsx +++ b/apps/app/components/project/issues/BoardView/state/create-update-state-modal.tsx @@ -1,11 +1,13 @@ import React, { useEffect } from "react"; -// swr + +import { useRouter } from "next/router"; + import { mutate } from "swr"; -// react hook form + import { Controller, useForm } from "react-hook-form"; -// react color + import { TwitterPicker } from "react-color"; -// headless + import { Dialog, Popover, Transition } from "@headlessui/react"; // services import stateService from "lib/services/state.service"; @@ -45,7 +47,8 @@ const CreateUpdateStateModal: React.FC = ({ isOpen, data, projectId, hand }, 500); }; - const { activeWorkspace } = useUser(); + const router = useRouter(); + const { workspaceSlug } = router.query; const { register, @@ -60,13 +63,13 @@ const CreateUpdateStateModal: React.FC = ({ isOpen, data, projectId, hand }); const onSubmit = async (formData: IState) => { - if (!activeWorkspace) return; + if (!workspaceSlug) return; const payload: IState = { ...formData, }; if (!data) { await stateService - .createState(activeWorkspace.slug, projectId, payload) + .createState(workspaceSlug as string, projectId, payload) .then((res) => { mutate(STATE_LIST(projectId), (prevData) => [...(prevData ?? []), res], false); onClose(); @@ -80,7 +83,7 @@ const CreateUpdateStateModal: React.FC = ({ isOpen, data, projectId, hand }); } else { await stateService - .updateState(activeWorkspace.slug, projectId, data.id, payload) + .updateState(workspaceSlug as string, projectId, data.id, payload) .then((res) => { mutate( STATE_LIST(projectId), @@ -185,14 +188,14 @@ const CreateUpdateStateModal: React.FC = ({ isOpen, data, projectId, hand {({ open }) => ( <> Color {watch("color") && watch("color") !== "" && ( = ({ isOpen, data, projectId, hand leaveFrom="opacity-100 translate-y-0" leaveTo="opacity-0 translate-y-1" > - + = ({ isOpen, handleClose, data }) => { const [isDeleteLoading, setIsDeleteLoading] = useState(false); - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug } = router.query; const { setToastAlert } = useToast(); @@ -39,13 +42,13 @@ const ConfirmIssueDeletion: React.FC = ({ isOpen, handleClose, data }) => const handleDeletion = async () => { setIsDeleteLoading(true); - if (!data || !activeWorkspace) return; + if (!data || !workspaceSlug) return; const projectId = data.project; await issueServices - .deleteIssue(activeWorkspace.slug, projectId, data.id) + .deleteIssue(workspaceSlug as string, projectId, data.id) .then(() => { mutate( - PROJECT_ISSUES_LIST(activeWorkspace.slug, projectId), + PROJECT_ISSUES_LIST(workspaceSlug as string, projectId), (prevData) => { return { ...(prevData as IssueResponse), @@ -103,7 +106,7 @@ const ConfirmIssueDeletion: React.FC = ({ isOpen, handleClose, data }) =>
-
+
Are you sure you want to delete {`"`} - {activeProject?.identifier}-{data?.sequence_id} - {data?.name}?{`"`} + {data?.project_detail.identifier}-{data?.sequence_id} - {data?.name}?{`"`}

diff --git a/apps/app/components/project/issues/create-update-issue-modal/select-assignee.tsx b/apps/app/components/project/issues/create-update-issue-modal/select-assignee.tsx index 1d660bf7b1e..6d4759f2cc7 100644 --- a/apps/app/components/project/issues/create-update-issue-modal/select-assignee.tsx +++ b/apps/app/components/project/issues/create-update-issue-modal/select-assignee.tsx @@ -1,12 +1,12 @@ import React from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR from "swr"; -// react hook form + import { Controller } from "react-hook-form"; // service import projectServices from "lib/services/project.service"; -// hooks -import useUser from "lib/hooks/useUser"; // fetch keys import { PROJECT_MEMBERS } from "constants/fetch-keys"; // types @@ -21,12 +21,13 @@ type Props = { }; const SelectAssignee: React.FC = ({ control }) => { - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const { data: people } = useSWR( - activeWorkspace && activeProject ? PROJECT_MEMBERS(activeProject.id) : null, - activeWorkspace && activeProject - ? () => projectServices.projectMembers(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId ? PROJECT_MEMBERS(projectId as string) : null, + workspaceSlug && projectId + ? () => projectServices.projectMembers(workspaceSlug as string, projectId as string) : null ); diff --git a/apps/app/components/project/issues/create-update-issue-modal/select-cycle.tsx b/apps/app/components/project/issues/create-update-issue-modal/select-cycle.tsx index 977a2196766..117a1753d07 100644 --- a/apps/app/components/project/issues/create-update-issue-modal/select-cycle.tsx +++ b/apps/app/components/project/issues/create-update-issue-modal/select-cycle.tsx @@ -3,8 +3,6 @@ import React from "react"; import useSWR from "swr"; // react hook form import { Controller } from "react-hook-form"; -// hooks -import useUser from "lib/hooks/useUser"; // services import cycleServices from "lib/services/cycles.service"; // constants diff --git a/apps/app/components/project/issues/create-update-issue-modal/select-labels.tsx b/apps/app/components/project/issues/create-update-issue-modal/select-labels.tsx index a4a7579aeb8..731bc59387d 100644 --- a/apps/app/components/project/issues/create-update-issue-modal/select-labels.tsx +++ b/apps/app/components/project/issues/create-update-issue-modal/select-labels.tsx @@ -1,13 +1,13 @@ import React, { useEffect, useState } from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR from "swr"; -// react hook form + import { useForm, Controller } from "react-hook-form"; import type { Control } from "react-hook-form"; // services import issuesServices from "lib/services/issues.service"; -// hooks -import useUser from "lib/hooks/useUser"; // fetching keys import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys"; // icons @@ -28,21 +28,22 @@ const defaultValues: Partial = { }; const SelectLabels: React.FC = ({ control }) => { - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const [isOpen, setIsOpen] = useState(false); const { data: issueLabels, mutate: issueLabelsMutate } = useSWR( - activeProject && activeWorkspace ? PROJECT_ISSUE_LABELS(activeProject.id) : null, - activeProject && activeWorkspace - ? () => issuesServices.getIssueLabels(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(workspaceSlug as string) : null, + workspaceSlug && projectId + ? () => issuesServices.getIssueLabels(workspaceSlug as string, projectId as string) : null ); const onSubmit = async (data: IIssueLabels) => { - if (!activeProject || !activeWorkspace || isSubmitting) return; + if (!projectId || !workspaceSlug || isSubmitting) return; await issuesServices - .createIssueLabel(activeWorkspace.slug, activeProject.id, data) + .createIssueLabel(workspaceSlug as string, projectId as string, data) .then((response) => { issueLabelsMutate((prevData) => [...(prevData ?? []), response], false); setIsOpen(false); 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 a3acb14dac2..cd1bdc1c77f 100644 --- a/apps/app/components/project/issues/issue-detail/activity/index.tsx +++ b/apps/app/components/project/issues/issue-detail/activity/index.tsx @@ -1,13 +1,14 @@ import React from "react"; -// next -import { useRouter } from "next/router"; + import Image from "next/image"; +import { useRouter } from "next/router"; + +import useSWR from "swr"; + // fetch-keys import { PROJECT_ISSUES_ACTIVITY, STATE_LIST, PROJECT_ISSUES_LIST } from "constants/fetch-keys"; // common import { addSpaceIfCamelCase, timeAgo } from "constants/common"; -// swr -import useSWR from "swr"; // services import stateService from "lib/services/state.service"; import issuesServices from "lib/services/issues.service"; @@ -38,25 +39,23 @@ const activityIcons: { const IssueActivitySection: React.FC = () => { const router = useRouter(); - const { issueId, projectId } = router.query; - - const { activeWorkspace, activeProject } = useUser(); + const { workspaceSlug, projectId, issueId } = router.query; const { data: issues } = useSWR( - activeWorkspace && activeProject - ? PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId + ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string) : null, - activeWorkspace && activeProject - ? () => issuesServices.getIssues(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId + ? () => issuesServices.getIssues(workspaceSlug as string, projectId as string) : null ); const { data: issueActivities } = useSWR( - activeWorkspace && projectId && issueId ? PROJECT_ISSUES_ACTIVITY : null, - activeWorkspace && projectId && issueId + workspaceSlug && projectId && issueId ? PROJECT_ISSUES_ACTIVITY : null, + workspaceSlug && projectId && issueId ? () => issuesServices.getIssueActivities( - activeWorkspace.slug, + workspaceSlug as string, projectId as string, issueId as string ) @@ -64,9 +63,9 @@ const IssueActivitySection: React.FC = () => { ); const { data: states } = useSWR( - activeWorkspace && activeProject ? STATE_LIST(activeProject.id) : null, - activeWorkspace && activeProject - ? () => stateService.getStates(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, + workspaceSlug && projectId + ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); diff --git a/apps/app/components/project/issues/issue-detail/add-as-sub-issue.tsx b/apps/app/components/project/issues/issue-detail/add-as-sub-issue.tsx index 66813bfb85d..737e1bd22fe 100644 --- a/apps/app/components/project/issues/issue-detail/add-as-sub-issue.tsx +++ b/apps/app/components/project/issues/issue-detail/add-as-sub-issue.tsx @@ -1,8 +1,9 @@ -// react import React, { useState } from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR, { mutate } from "swr"; -// headless ui + import { Combobox, Dialog, Transition } from "@headlessui/react"; // services import issuesServices from "lib/services/issues.service"; @@ -26,14 +27,15 @@ type Props = { const AddAsSubIssue: React.FC = ({ isOpen, setIsOpen, parent }) => { const [query, setQuery] = useState(""); - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const { data: issues } = useSWR( - activeWorkspace && activeProject - ? PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId + ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string) : null, - activeWorkspace && activeProject - ? () => issuesServices.getIssues(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId + ? () => issuesServices.getIssues(workspaceSlug as string, projectId as string) : null ); @@ -49,12 +51,12 @@ const AddAsSubIssue: React.FC = ({ isOpen, setIsOpen, parent }) => { }; const addAsSubIssue = (issueId: string) => { - if (activeWorkspace && activeProject) { + if (workspaceSlug && projectId) { issuesServices - .patchIssue(activeWorkspace.slug, activeProject.id, issueId, { parent: parent?.id }) + .patchIssue(workspaceSlug as string, projectId as string, issueId, { parent: parent?.id }) .then((res) => { mutate( - PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id), + PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string), (prevData) => ({ ...(prevData as IssueResponse), results: (prevData?.results ?? []).map((p) => diff --git a/apps/app/components/project/issues/issue-detail/comment/issue-comment-section.tsx b/apps/app/components/project/issues/issue-detail/comment/issue-comment-section.tsx index 78497b25d01..4335d0cd00c 100644 --- a/apps/app/components/project/issues/issue-detail/comment/issue-comment-section.tsx +++ b/apps/app/components/project/issues/issue-detail/comment/issue-comment-section.tsx @@ -34,16 +34,14 @@ const IssueCommentSection: React.FC = () => { const router = useRouter(); - let { issueId, projectId } = router.query; - - const { activeWorkspace } = useUser(); + let { workspaceSlug, projectId, issueId } = router.query; const { data: comments, mutate } = useSWR( - activeWorkspace && projectId && issueId ? PROJECT_ISSUES_COMMENTS(issueId as string) : null, - activeWorkspace && projectId && issueId + workspaceSlug && projectId && issueId ? PROJECT_ISSUES_COMMENTS(issueId as string) : null, + workspaceSlug && projectId && issueId ? () => issuesServices.getIssueComments( - activeWorkspace.slug, + workspaceSlug as string, projectId as string, issueId as string ) @@ -51,9 +49,9 @@ const IssueCommentSection: React.FC = () => { ); const onSubmit = async (formData: IIssueComment) => { - if (!activeWorkspace || !projectId || !issueId || isSubmitting) return; + if (!workspaceSlug || !projectId || !issueId || isSubmitting) return; await issuesServices - .createIssueComment(activeWorkspace.slug, projectId as string, issueId as string, formData) + .createIssueComment(workspaceSlug as string, projectId as string, issueId as string, formData) .then((response) => { console.log(response); mutate((prevData) => [response, ...(prevData ?? [])]); @@ -65,10 +63,10 @@ const IssueCommentSection: React.FC = () => { }; const onCommentUpdate = async (comment: IIssueComment) => { - if (!activeWorkspace || !projectId || !issueId || isSubmitting) return; + if (!workspaceSlug || !projectId || !issueId || isSubmitting) return; await issuesServices .patchIssueComment( - activeWorkspace.slug, + workspaceSlug as string, projectId as string, issueId as string, comment.id, @@ -88,9 +86,14 @@ const IssueCommentSection: React.FC = () => { }; const onCommentDelete = async (commentId: string) => { - if (!activeWorkspace || !projectId || !issueId || isSubmitting) return; + if (!workspaceSlug || !projectId || !issueId || isSubmitting) return; await issuesServices - .deleteIssueComment(activeWorkspace.slug, projectId as string, issueId as string, commentId) + .deleteIssueComment( + workspaceSlug as string, + projectId as string, + issueId as string, + commentId + ) .then((response) => { mutate((prevData) => (prevData ?? []).filter((c) => c.id !== commentId)); console.log(response); diff --git a/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/index.tsx b/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/index.tsx index efabb6888b6..f048e71d894 100644 --- a/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/index.tsx +++ b/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/index.tsx @@ -10,7 +10,6 @@ import { TwitterPicker } from "react-color"; // services import issuesServices from "lib/services/issues.service"; // hooks -import useUser from "lib/hooks/useUser"; import useToast from "lib/hooks/useToast"; // components import ConfirmIssueDeletion from "components/project/issues/confirm-issue-deletion"; @@ -39,7 +38,7 @@ import { import type { Control } from "react-hook-form"; import type { ICycle, IIssue, IIssueLabels } from "types"; // fetch-keys -import { PROJECT_ISSUE_LABELS, PROJECT_ISSUES_LIST } from "constants/fetch-keys"; +import { PROJECT_ISSUE_LABELS, PROJECT_ISSUES_LIST, PROJECT_DETAILS } from "constants/fetch-keys"; // common import { copyTextToClipboard } from "constants/common"; @@ -62,35 +61,29 @@ const IssueDetailSidebar: React.FC = ({ watch: watchIssue, }) => { const [createLabelForm, setCreateLabelForm] = useState(false); - - const { activeWorkspace, activeProject } = useUser(); + const [deleteIssueModal, setDeleteIssueModal] = useState(false); const router = useRouter(); - - const { - query: { workspaceSlug }, - } = router; + const { workspaceSlug, projectId } = router.query; const { setToastAlert } = useToast(); const { data: issues } = useSWR( - activeWorkspace && activeProject - ? PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId + ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string) : null, - activeWorkspace && activeProject - ? () => issuesServices.getIssues(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId + ? () => issuesServices.getIssues(workspaceSlug as string, projectId as string) : null ); const { data: issueLabels, mutate: issueLabelMutate } = useSWR( - activeProject && activeWorkspace ? PROJECT_ISSUE_LABELS(activeProject.id) : null, - activeProject && activeWorkspace - ? () => issuesServices.getIssueLabels(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId as string) : null, + workspaceSlug && projectId + ? () => issuesServices.getIssueLabels(workspaceSlug as string, projectId as string) : null ); - const [deleteIssueModal, setDeleteIssueModal] = useState(false); - const { register, handleSubmit, @@ -103,9 +96,9 @@ const IssueDetailSidebar: React.FC = ({ }); const handleNewLabel = (formData: any) => { - if (!activeWorkspace || !activeProject || isSubmitting) return; + if (!workspaceSlug || !projectId || isSubmitting) return; issuesServices - .createIssueLabel(activeWorkspace.slug, activeProject.id, formData) + .createIssueLabel(workspaceSlug as string, projectId as string, formData) .then((res) => { console.log(res); reset(defaultValues); @@ -116,11 +109,11 @@ const IssueDetailSidebar: React.FC = ({ }; const handleCycleChange = (cycleDetail: ICycle) => { - if (!activeWorkspace || !activeProject || !issueDetail) return; + if (!workspaceSlug || !projectId || !issueDetail) return; submitChanges({ cycle: cycleDetail.id, cycle_detail: cycleDetail }); issuesServices - .addIssueToCycle(activeWorkspace.slug, activeProject.id, cycleDetail.id, { + .addIssueToCycle(workspaceSlug as string, projectId as string, cycleDetail.id, { issues: [issueDetail.id], }) .then(() => { @@ -138,7 +131,7 @@ const IssueDetailSidebar: React.FC = ({

- {activeProject?.identifier}-{issueDetail?.sequence_id} + {issueDetail?.project_detail?.identifier}-{issueDetail?.sequence_id}

diff --git a/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/select-state.tsx b/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/select-state.tsx index 73813948013..251e10ad94e 100644 --- a/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/select-state.tsx +++ b/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/select-state.tsx @@ -1,14 +1,14 @@ import React from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR from "swr"; -// react-hook-form + import { Control, Controller } from "react-hook-form"; // services import stateService from "lib/services/state.service"; // icons import { Squares2X2Icon } from "@heroicons/react/24/outline"; -// hooks -import useUser from "lib/hooks/useUser"; // constants import { classNames } from "constants/common"; import { STATE_LIST } from "constants/fetch-keys"; @@ -23,12 +23,13 @@ type Props = { }; const SelectState: React.FC = ({ control, submitChanges }) => { - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const { data: states } = useSWR( - activeWorkspace && activeProject ? STATE_LIST(activeProject.id) : null, - activeWorkspace && activeProject - ? () => stateService.getStates(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, + workspaceSlug && projectId + ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); diff --git a/apps/app/components/project/issues/issues-list-modal.tsx b/apps/app/components/project/issues/issues-list-modal.tsx index b158aab3b6f..6dbfab48762 100644 --- a/apps/app/components/project/issues/issues-list-modal.tsx +++ b/apps/app/components/project/issues/issues-list-modal.tsx @@ -1,15 +1,14 @@ -// react import React, { useState } from "react"; -// headless ui + import { Combobox, Dialog, Transition } from "@headlessui/react"; // ui import { Button } from "ui"; // icons import { MagnifyingGlassIcon, RectangleStackIcon } from "@heroicons/react/24/outline"; +// constants +import { classNames } from "constants/common"; // types import { IIssue } from "types"; -import { classNames } from "constants/common"; -import useUser from "lib/hooks/useUser"; type Props = { isOpen: boolean; @@ -35,8 +34,6 @@ const IssuesListModal: React.FC = ({ const [query, setQuery] = useState(""); const [values, setValues] = useState([]); - const { activeProject } = useUser(); - const handleClose = () => { onClose(); setQuery(""); @@ -77,21 +74,14 @@ const IssuesListModal: React.FC = ({ {multiple ? ( <> - { - // setValues(val); - console.log(val); - }} - multiple - > + {}} multiple>
)}
-
+
@@ -172,7 +162,7 @@ const IssuesListModal: React.FC = ({ aria-hidden="true" /> setQuery(e.target.value)} displayValue={() => ""} @@ -197,26 +187,24 @@ const IssuesListModal: React.FC = ({ value={issue.id} className={({ active }) => classNames( - "flex items-center gap-2 cursor-pointer select-none rounded-md px-3 py-2", + "flex cursor-pointer select-none items-center gap-2 rounded-md px-3 py-2", active ? "bg-gray-900 bg-opacity-5 text-gray-900" : "" ) } onClick={() => handleClose()} > - {({ selected }) => ( - <> - - - {activeProject?.identifier}-{issue.sequence_id} - {" "} - {issue.name} - - )} + <> + + + {issue.project_detail?.identifier}-{issue.sequence_id} + {" "} + {issue.name} + ))} diff --git a/apps/app/components/project/issues/my-issues/ChangeStateDropdown.tsx b/apps/app/components/project/issues/my-issues/ChangeStateDropdown.tsx index 9e90c0e8da3..5eb248aee1f 100644 --- a/apps/app/components/project/issues/my-issues/ChangeStateDropdown.tsx +++ b/apps/app/components/project/issues/my-issues/ChangeStateDropdown.tsx @@ -1,6 +1,7 @@ -// react import React from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR from "swr"; // hooks import useUser from "lib/hooks/useUser"; @@ -25,11 +26,12 @@ type Props = { }; const ChangeStateDropdown: React.FC = ({ issue, updateIssues }) => { - const { activeWorkspace } = useUser(); + const router = useRouter(); + const { workspaceSlug } = router.query; const { data: states } = useSWR( - activeWorkspace ? STATE_LIST(issue.project) : null, - activeWorkspace ? () => stateServices.getStates(activeWorkspace.slug, issue.project) : null + workspaceSlug ? STATE_LIST(issue.project) : null, + workspaceSlug ? () => stateServices.getStates(workspaceSlug as string, issue.project) : null ); return ( @@ -38,8 +40,8 @@ const ChangeStateDropdown: React.FC = ({ issue, updateIssues }) => { as="div" value={issue.state} onChange={(data: string) => { - if (!activeWorkspace) return; - updateIssues(activeWorkspace.slug, issue.project, issue.id, { + if (!workspaceSlug) return; + updateIssues(workspaceSlug as string, issue.project, issue.id, { state: data, state_detail: states?.find((state) => state.id === data), }); @@ -50,7 +52,7 @@ const ChangeStateDropdown: React.FC = ({ issue, updateIssues }) => { <>
= ({ issue, updateIssues }) => { {addSpaceIfCamelCase(issue.state_detail.name)} @@ -73,7 +75,7 @@ const ChangeStateDropdown: React.FC = ({ issue, updateIssues }) => { leaveFrom="opacity-100" leaveTo="opacity-0" > - + {states?.map((state) => ( = ({ isOpen, setIsOpen, data }) => { const [isDeleteLoading, setIsDeleteLoading] = useState(false); - const { activeWorkspace } = useUser(); - const router = useRouter(); const { query: { workspaceSlug }, @@ -45,9 +41,9 @@ const ConfirmModuleDeletion: React.FC = ({ isOpen, setIsOpen, data }) => const handleDeletion = async () => { setIsDeleteLoading(true); - if (!activeWorkspace || !data) return; + if (!workspaceSlug || !data) return; await modulesService - .deleteModule(activeWorkspace.slug, data.project, data.id) + .deleteModule(workspaceSlug as string, data.project, data.id) .then(() => { mutate(MODULE_LIST(data.project)); router.push(`/${workspaceSlug}/projects/${data.project}/modules`); diff --git a/apps/app/components/project/modules/create-update-module-modal/index.tsx b/apps/app/components/project/modules/create-update-module-modal/index.tsx index 91b56fd3ae2..7fb0103ccca 100644 --- a/apps/app/components/project/modules/create-update-module-modal/index.tsx +++ b/apps/app/components/project/modules/create-update-module-modal/index.tsx @@ -1,9 +1,11 @@ import React, { useEffect } from "react"; -// swr + +import { useRouter } from "next/router"; + import { mutate } from "swr"; -// react hook form + import { useForm } from "react-hook-form"; -// headless + import { Dialog, Transition } from "@headlessui/react"; // ui import { Button, Input, TextArea, Select } from "ui"; @@ -37,15 +39,8 @@ const defaultValues: Partial = { }; const CreateUpdateModuleModal: React.FC = ({ isOpen, setIsOpen, data, projectId }) => { - const handleClose = () => { - setIsOpen(false); - const timeout = setTimeout(() => { - reset(defaultValues); - clearTimeout(timeout); - }, 500); - }; - - const { activeWorkspace } = useUser(); + const router = useRouter(); + const { workspaceSlug } = router.query; const { register, @@ -58,8 +53,17 @@ const CreateUpdateModuleModal: React.FC = ({ isOpen, setIsOpen, data, pro defaultValues, }); + useEffect(() => { + if (data) { + setIsOpen(true); + reset(data); + } else { + reset(defaultValues); + } + }, [data, setIsOpen, reset]); + const onSubmit = async (formData: IModule) => { - if (!activeWorkspace) return; + if (!workspaceSlug) return; const payload = { ...formData, start_date: formData.start_date ? renderDateFormat(formData.start_date) : null, @@ -67,7 +71,7 @@ const CreateUpdateModuleModal: React.FC = ({ isOpen, setIsOpen, data, pro }; if (!data) { await modulesService - .createModule(activeWorkspace.slug, projectId, payload) + .createModule(workspaceSlug as string, projectId, payload) .then((res) => { mutate( MODULE_LIST(projectId), @@ -85,7 +89,7 @@ const CreateUpdateModuleModal: React.FC = ({ isOpen, setIsOpen, data, pro }); } else { await modulesService - .updateModule(activeWorkspace.slug, projectId, data.id, payload) + .updateModule(workspaceSlug as string, projectId, data.id, payload) .then((res) => { mutate( MODULE_LIST(projectId), @@ -112,14 +116,13 @@ const CreateUpdateModuleModal: React.FC = ({ isOpen, setIsOpen, data, pro } }; - useEffect(() => { - if (data) { - setIsOpen(true); - reset(data); - } else { + const handleClose = () => { + setIsOpen(false); + const timeout = setTimeout(() => { reset(defaultValues); - } - }, [data, setIsOpen, reset]); + clearTimeout(timeout); + }, 500); + }; return ( @@ -203,7 +206,7 @@ const CreateUpdateModuleModal: React.FC = ({ isOpen, setIsOpen, data, pro />
-
+
diff --git a/apps/app/components/project/modules/create-update-module-modal/select-lead.tsx b/apps/app/components/project/modules/create-update-module-modal/select-lead.tsx index 2564eabbc28..7bfa815e834 100644 --- a/apps/app/components/project/modules/create-update-module-modal/select-lead.tsx +++ b/apps/app/components/project/modules/create-update-module-modal/select-lead.tsx @@ -1,14 +1,13 @@ -// react import React from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR from "swr"; -// react hook form + import { Controller } from "react-hook-form"; import type { Control } from "react-hook-form"; // service import projectServices from "lib/services/project.service"; -// hooks -import useUser from "lib/hooks/useUser"; // ui import { SearchListbox } from "ui"; // icons @@ -23,12 +22,13 @@ type Props = { }; const SelectLead: React.FC = ({ control }) => { - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const { data: people } = useSWR( - activeWorkspace && activeProject ? PROJECT_MEMBERS(activeProject.id) : null, - activeWorkspace && activeProject - ? () => projectServices.projectMembers(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId ? PROJECT_MEMBERS(projectId as string) : null, + workspaceSlug && projectId + ? () => projectServices.projectMembers(workspaceSlug as string, projectId as string) : null ); diff --git a/apps/app/components/project/modules/create-update-module-modal/select-members.tsx b/apps/app/components/project/modules/create-update-module-modal/select-members.tsx index bac370c629c..7ba0f82e7e1 100644 --- a/apps/app/components/project/modules/create-update-module-modal/select-members.tsx +++ b/apps/app/components/project/modules/create-update-module-modal/select-members.tsx @@ -1,14 +1,14 @@ -// react import React from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR from "swr"; -// react hook form + import { Controller } from "react-hook-form"; import type { Control } from "react-hook-form"; // service import projectServices from "lib/services/project.service"; -// hooks -import useUser from "lib/hooks/useUser"; + // ui import { SearchListbox } from "ui"; // icons @@ -23,12 +23,13 @@ type Props = { }; const SelectMembers: React.FC = ({ control }) => { - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const { data: people } = useSWR( - activeWorkspace && activeProject ? PROJECT_MEMBERS(activeProject.id) : null, - activeWorkspace && activeProject - ? () => projectServices.projectMembers(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId ? PROJECT_MEMBERS(projectId as string) : null, + workspaceSlug && projectId + ? () => projectServices.projectMembers(workspaceSlug as string, projectId as string) : null ); diff --git a/apps/app/components/project/modules/list-view/index.tsx b/apps/app/components/project/modules/list-view/index.tsx index 504e69db7b5..5f383416e81 100644 --- a/apps/app/components/project/modules/list-view/index.tsx +++ b/apps/app/components/project/modules/list-view/index.tsx @@ -1,14 +1,14 @@ -// react import React from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR from "swr"; // services import workspaceService from "lib/services/workspace.service"; import stateService from "lib/services/state.service"; // common import { addSpaceIfCamelCase } from "constants/common"; -// hooks -import useUser from "lib/hooks/useUser"; + // components import SingleListIssue from "components/common/list-view/single-issue"; // headless ui @@ -52,17 +52,18 @@ const ModulesListView: React.FC = ({ handleDeleteIssue, setPreloadedData, }) => { - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const { data: people } = useSWR( - activeWorkspace ? WORKSPACE_MEMBERS : null, - activeWorkspace ? () => workspaceService.workspaceMembers(activeWorkspace.slug) : null + workspaceSlug ? WORKSPACE_MEMBERS : null, + workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug as string) : null ); const { data: states } = useSWR( - activeWorkspace && activeProject ? STATE_LIST(activeProject.id) : null, - activeWorkspace && activeProject - ? () => stateService.getStates(activeWorkspace.slug, activeProject.id) + workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, + workspaceSlug && projectId + ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); diff --git a/apps/app/components/project/modules/module-detail-sidebar/index.tsx b/apps/app/components/project/modules/module-detail-sidebar/index.tsx index 519e5d6c819..cde22e8a742 100644 --- a/apps/app/components/project/modules/module-detail-sidebar/index.tsx +++ b/apps/app/components/project/modules/module-detail-sidebar/index.tsx @@ -1,16 +1,14 @@ -// react -import { useEffect, useState } from "react"; -// next +import React, { useEffect, useState } from "react"; + import Link from "next/link"; import { useRouter } from "next/router"; -// swr + import { mutate } from "swr"; -// react-hook-form + import { Controller, useForm } from "react-hook-form"; // services import modulesService from "lib/services/modules.service"; // hooks -import useUser from "lib/hooks/useUser"; import useToast from "lib/hooks/useToast"; // components import SelectMembers from "components/project/modules/module-detail-sidebar/select-members"; @@ -22,7 +20,6 @@ import { Loader } from "ui"; import { CalendarDaysIcon, ChartPieIcon, - ClipboardDocumentIcon, LinkIcon, PlusIcon, TrashIcon, @@ -55,13 +52,12 @@ const ModuleDetailSidebar: React.FC = ({ moduleIssues, handleDeleteModule, }) => { + const [moduleLinkModal, setModuleLinkModal] = useState(false); + const router = useRouter(); const { - query: { workspaceSlug }, + query: { workspaceSlug, projectId }, } = router; - const [moduleLinkModal, setModuleLinkModal] = useState(false); - - const { activeWorkspace, activeProject } = useUser(); const { setToastAlert } = useToast(); @@ -69,6 +65,14 @@ const ModuleDetailSidebar: React.FC = ({ defaultValues, }); + useEffect(() => { + if (module) + reset({ + ...module, + members_list: module.members_list ?? module.members_detail?.map((m) => m.id), + }); + }, [module, reset]); + const groupedIssues = { backlog: [], unstarted: [], @@ -79,10 +83,10 @@ const ModuleDetailSidebar: React.FC = ({ }; const submitChanges = (data: Partial) => { - if (!activeWorkspace || !activeProject || !module) return; + if (!workspaceSlug || !projectId || !module) return; modulesService - .patchModule(activeWorkspace.slug, activeProject.id, module.id, data) + .patchModule(workspaceSlug as string, projectId as string, module.id, data) .then((res) => { console.log(res); mutate(MODULE_DETAIL); @@ -92,14 +96,6 @@ const ModuleDetailSidebar: React.FC = ({ }); }; - useEffect(() => { - if (module) - reset({ - ...module, - members_list: module.members_list ?? module.members_detail?.map((m) => m.id), - }); - }, [module, reset]); - return ( <> = ({ className="rounded-md border p-2 shadow-sm duration-300 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500" onClick={() => copyTextToClipboard( - `https://app.plane.so/${workspaceSlug}/projects/${activeProject?.id}/modules/${module.id}` + `https://app.plane.so/${workspaceSlug}/projects/${projectId}/modules/${module.id}` ) .then(() => { setToastAlert({ diff --git a/apps/app/components/project/modules/module-detail-sidebar/select-members.tsx b/apps/app/components/project/modules/module-detail-sidebar/select-members.tsx index 5132ab1a660..8d261c788ee 100644 --- a/apps/app/components/project/modules/module-detail-sidebar/select-members.tsx +++ b/apps/app/components/project/modules/module-detail-sidebar/select-members.tsx @@ -1,15 +1,13 @@ -// react import React from "react"; -// next + import Image from "next/image"; -// swr +import { useRouter } from "next/router"; + import useSWR from "swr"; -// react-hook-form + import { Control, Controller } from "react-hook-form"; // services import workspaceService from "lib/services/workspace.service"; -// hooks -import useUser from "lib/hooks/useUser"; // headless ui import { Listbox, Transition } from "@headlessui/react"; // ui @@ -29,17 +27,18 @@ type Props = { }; const SelectMembers: React.FC = ({ control, submitChanges }) => { - const { activeWorkspace } = useUser(); + const router = useRouter(); + const { workspaceSlug } = router.query; const { data: people } = useSWR( - activeWorkspace ? WORKSPACE_MEMBERS(activeWorkspace.slug) : null, - activeWorkspace ? () => workspaceService.workspaceMembers(activeWorkspace.slug) : null + workspaceSlug ? WORKSPACE_MEMBERS(workspaceSlug as string) : null, + workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug as string) : null ); return ( -
+
- +

Members

@@ -58,14 +57,14 @@ const SelectMembers: React.FC = ({ control, submitChanges }) => { > {({ open }) => (
- + -
+
{value && Array.isArray(value) ? ( <> {value.length > 0 ? ( @@ -80,7 +79,7 @@ const SelectMembers: React.FC = ({ control, submitChanges }) => { }`} > {person && person.avatar && person.avatar !== "" ? ( -
+
= ({ control, submitChanges }) => {
) : (
{person?.first_name && person.first_name !== "" ? person.first_name.charAt(0) @@ -102,7 +101,7 @@ const SelectMembers: React.FC = ({ control, submitChanges }) => { ); }) ) : ( -
+
= ({ control, submitChanges }) => { leaveFrom="transform opacity-100 scale-100" leaveTo="transform opacity-0 scale-95" > - +
{people ? ( people.length > 0 ? ( @@ -138,7 +137,7 @@ const SelectMembers: React.FC = ({ control, submitChanges }) => { className={({ active, selected }) => `${ active || selected ? "bg-indigo-50" : "" - } flex items-center gap-2 text-gray-900 cursor-pointer select-none p-2 truncate` + } flex cursor-pointer select-none items-center gap-2 truncate p-2 text-gray-900` } value={option.member.id} > @@ -153,7 +152,7 @@ const SelectMembers: React.FC = ({ control, submitChanges }) => { />
) : ( -
+
{option.member.first_name && option.member.first_name !== "" ? option.member.first_name.charAt(0) : option.member.email.charAt(0)} diff --git a/apps/app/components/project/modules/module-link-modal.tsx b/apps/app/components/project/modules/module-link-modal.tsx index c38bd2642ee..fc40e8e94b8 100644 --- a/apps/app/components/project/modules/module-link-modal.tsx +++ b/apps/app/components/project/modules/module-link-modal.tsx @@ -1,10 +1,11 @@ -// react -import React, { useEffect } from "react"; -// swr +import React from "react"; + +import { useRouter } from "next/router"; + import { mutate } from "swr"; -// react hook form + import { useForm } from "react-hook-form"; -// headless + import { Dialog, Transition } from "@headlessui/react"; // services import modulesService from "lib/services/modules.service"; @@ -29,15 +30,8 @@ const defaultValues: ModuleLink = { }; const ModuleLinkModal: React.FC = ({ isOpen, module, handleClose }) => { - const { activeWorkspace, activeProject } = useUser(); - - const onClose = () => { - handleClose(); - const timeout = setTimeout(() => { - reset(defaultValues); - clearTimeout(timeout); - }, 500); - }; + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const { register, @@ -50,7 +44,7 @@ const ModuleLinkModal: React.FC = ({ isOpen, module, handleClose }) => { }); const onSubmit = async (formData: ModuleLink) => { - if (!activeWorkspace || !activeProject || !module) return; + if (!workspaceSlug || !projectId || !module) return; const previousLinks = module.link_module.map((l) => { return { title: l.title, url: l.url }; @@ -61,7 +55,7 @@ const ModuleLinkModal: React.FC = ({ isOpen, module, handleClose }) => { }; await modulesService - .patchModule(activeWorkspace.slug, activeProject.id, module.id, payload) + .patchModule(workspaceSlug as string, projectId as string, module.id, payload) .then((res) => { mutate(MODULE_DETAIL); onClose(); @@ -75,6 +69,14 @@ const ModuleLinkModal: React.FC = ({ isOpen, module, handleClose }) => { }); }; + const onClose = () => { + handleClose(); + const timeout = setTimeout(() => { + reset(defaultValues); + clearTimeout(timeout); + }, 500); + }; + return ( diff --git a/apps/app/components/project/send-project-invitation-modal.tsx b/apps/app/components/project/send-project-invitation-modal.tsx index ef77b65f90f..a4178c984f8 100644 --- a/apps/app/components/project/send-project-invitation-modal.tsx +++ b/apps/app/components/project/send-project-invitation-modal.tsx @@ -1,9 +1,11 @@ import React from "react"; -// swr + +import { useRouter } from "next/router"; + import useSWR, { mutate } from "swr"; -// react hook form + import { useForm, Controller } from "react-hook-form"; -// headless + import { Dialog, Transition, Listbox } from "@headlessui/react"; // hooks import useUser from "lib/hooks/useUser"; @@ -42,24 +44,17 @@ const defaultValues: Partial = { }; const SendProjectInvitationModal: React.FC = ({ isOpen, setIsOpen, members }) => { - const handleClose = () => { - setIsOpen(false); - const timeout = setTimeout(() => { - reset(defaultValues); - clearTimeout(timeout); - }, 500); - }; - - const { activeWorkspace, activeProject } = useUser(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; const { setToastAlert } = useToast(); const { data: people } = useSWR( - activeWorkspace ? WORKSPACE_MEMBERS(activeWorkspace.slug) : null, - activeWorkspace ? () => workspaceService.workspaceMembers(activeWorkspace.slug) : null, + workspaceSlug ? WORKSPACE_MEMBERS(workspaceSlug as string) : null, + workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug as string) : null, { onErrorRetry(err, _, __, revalidate, revalidateOpts) { - if (err?.status === 403) return; + if (err?.status === 403 || err?.status === 401) return; setTimeout(() => revalidate(revalidateOpts), 5000); }, } @@ -70,7 +65,6 @@ const SendProjectInvitationModal: React.FC = ({ isOpen, setIsOpen, member formState: { errors, isSubmitting }, handleSubmit, reset, - setError, setValue, control, } = useForm({ @@ -78,11 +72,10 @@ const SendProjectInvitationModal: React.FC = ({ isOpen, setIsOpen, member }); const onSubmit = async (formData: ProjectMember) => { - if (!activeWorkspace || !activeProject || isSubmitting) return; + if (!workspaceSlug || !projectId || isSubmitting) return; await projectService - .inviteProject(activeWorkspace.slug, activeProject.id, formData) + .inviteProject(workspaceSlug as string, projectId as string, formData) .then((response) => { - console.log(response); setIsOpen(false); mutate( PROJECT_INVITATIONS, @@ -102,6 +95,14 @@ const SendProjectInvitationModal: React.FC = ({ isOpen, setIsOpen, member }); }; + const handleClose = () => { + setIsOpen(false); + const timeout = setTimeout(() => { + reset(defaultValues); + clearTimeout(timeout); + }, 500); + }; + return ( @@ -156,12 +157,12 @@ const SendProjectInvitationModal: React.FC = ({ isOpen, setIsOpen, member > {({ open }) => ( <> - + Email
@@ -170,7 +171,7 @@ const SendProjectInvitationModal: React.FC = ({ isOpen, setIsOpen, member ? people?.find((p) => p.member.id === value)?.member.email : "Select email"} - +
))} - +
diff --git a/apps/app/pages/magic-sign-in.tsx b/apps/app/pages/magic-sign-in.tsx index 6a88e9c1826..8d978297c82 100644 --- a/apps/app/pages/magic-sign-in.tsx +++ b/apps/app/pages/magic-sign-in.tsx @@ -20,7 +20,7 @@ const MagicSignIn: NextPage = () => { const { setToastAlert } = useToast(); - const { mutateUser, mutateWorkspaces } = useUser(); + const { mutateUser } = useUser(); useEffect(() => { setIsSigningIn(true); @@ -31,7 +31,7 @@ const MagicSignIn: NextPage = () => { .then(async (res) => { setIsSigningIn(false); await mutateUser(); - await mutateWorkspaces(); + // TODO: add workspace mutations if (res.user.is_onboarded) router.push("/"); else router.push("/invitations"); }) @@ -39,7 +39,7 @@ const MagicSignIn: NextPage = () => { setErrorSignIn(err.response.data.error); setIsSigningIn(false); }); - }, [password, key, mutateUser, mutateWorkspaces, router]); + }, [password, key, mutateUser, router]); return ( { title: "Magic Sign In", }} > -
+
{isSigningIn ? ( -
+

Signing you in...

Please wait while we are preparing your take off.

) : errorSigningIn ? ( -
+

Error

{errorSigningIn}. { authenticationService .emailCode({ email: (key as string).split("_")[1] }) @@ -86,7 +86,7 @@ const MagicSignIn: NextPage = () => {

) : ( -
+

Success

Redirecting you to the app...

diff --git a/apps/app/pages/signin.tsx b/apps/app/pages/signin.tsx index e4d3afe3c54..6442845f11f 100644 --- a/apps/app/pages/signin.tsx +++ b/apps/app/pages/signin.tsx @@ -34,7 +34,7 @@ const SignIn: NextPage = () => { const [useCode, setUseCode] = useState(true); const router = useRouter(); - const { mutateUser, mutateWorkspaces, slug } = useUser(); + const { mutateUser } = useUser(); const [githubToken, setGithubToken] = useState(undefined); const [loginCallBackURL, setLoginCallBackURL] = useState(undefined); @@ -44,16 +44,17 @@ const SignIn: NextPage = () => { const onSignInSuccess = useCallback( async (res: IUser) => { await mutateUser(); - await mutateWorkspaces(); + // TODO: add mutate workspaces const nextLocation = router.asPath.split("?next=")[1]; if (nextLocation) { router.push(nextLocation as string); } else { if (!res.user.is_onboarded) router.push("/invitations"); + else router.push("/"); } }, - [mutateUser, mutateWorkspaces, router] + [mutateUser, router] ); const githubTokenMemo = React.useMemo(() => { @@ -84,7 +85,7 @@ const SignIn: NextPage = () => { console.log(err); }); } - }, [githubToken, mutateUser, mutateWorkspaces, router, onSignInSuccess]); + }, [githubToken, mutateUser, router, onSignInSuccess]); useEffect(() => { const origin = @@ -94,10 +95,6 @@ const SignIn: NextPage = () => { return () => setIsGoogleAuthenticationLoading(false); }, []); - if (slug) { - router.push(`/${slug}`); - } - return ( | null; diff --git a/apps/app/ui/search-listbox/index.tsx b/apps/app/ui/search-listbox/index.tsx index df5bbac1c09..055371d9685 100644 --- a/apps/app/ui/search-listbox/index.tsx +++ b/apps/app/ui/search-listbox/index.tsx @@ -1,13 +1,11 @@ -// react import React, { useState } from "react"; -// next + import Image from "next/image"; -// swr +import { useRouter } from "next/router"; + import useSWR from "swr"; // services import workspaceService from "lib/services/workspace.service"; -// hooks -import useUser from "lib/hooks/useUser"; // headless ui import { Transition, Combobox } from "@headlessui/react"; // types @@ -32,7 +30,8 @@ const SearchListbox: React.FC = ({ }) => { const [query, setQuery] = useState(""); - const { activeWorkspace } = useUser(); + const router = useRouter(); + const { workspaceSlug } = router.query; const filteredOptions = query === "" @@ -53,8 +52,8 @@ const SearchListbox: React.FC = ({ } const { data: people } = useSWR( - activeWorkspace ? WORKSPACE_MEMBERS(activeWorkspace.slug) : null, - activeWorkspace ? () => workspaceService.workspaceMembers(activeWorkspace.slug) : null + workspaceSlug ? WORKSPACE_MEMBERS(workspaceSlug as string) : null, + workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug as string) : null ); const userAvatar = (userId: string) => { @@ -76,7 +75,7 @@ const SearchListbox: React.FC = ({ ); } else return ( -
+
{user.member.first_name && user.member.first_name !== "" ? user.member.first_name.charAt(0) : user.member.email.charAt(0)} @@ -90,7 +89,7 @@ const SearchListbox: React.FC = ({ <> {title} @@ -117,7 +116,7 @@ const SearchListbox: React.FC = ({ leaveTo="opacity-0" > = ({ } ${optionsClassName || ""}`} > setQuery(event.target.value)} placeholder="Search" displayValue={(assigned: any) => assigned?.name} @@ -160,7 +159,7 @@ const SearchListbox: React.FC = ({ className={({ active }) => `${ active ? "bg-indigo-50" : "" - } flex items-center gap-2 cursor-pointer select-none truncate text-gray-900 p-2` + } flex cursor-pointer select-none items-center gap-2 truncate p-2 text-gray-900` } value={option.value} >