From 2cb708c63ba8668796c3c55d4da3f62893aeb1df Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Sun, 29 Jan 2023 12:25:20 +0530 Subject: [PATCH] fix: minor ui fixes (#203) * feat: added user auth * fix: minor ui fixes * refactor: removed unnecessary functions * fix: build errors --- .../common/board-view/single-issue.tsx | 5 + .../common/existing-issues-list-modal.tsx | 7 + .../common/list-view/single-issue.tsx | 9 +- apps/app/components/issues/modal.tsx | 2 +- .../project/cycles/confirm-cycle-deletion.tsx | 20 ++- .../cycles/create-update-cycle-modal.tsx | 30 ++-- .../BoardView/state/confirm-state-delete.tsx | 20 ++- .../state/create-update-state-inline.tsx | 40 +++-- .../project/issues/confirm-issue-deletion.tsx | 11 +- .../issues/issue-detail/add-as-sub-issue.tsx | 25 +-- .../modules/confirm-module-deletion.tsx | 22 ++- .../create-update-module-modal/index.tsx | 25 ++- .../app/components/rich-text-editor/index.tsx | 2 +- apps/app/constants/fetch-keys.ts | 2 +- apps/app/hooks/use-issue-properties.tsx | 4 +- apps/app/hooks/use-local-storage.tsx | 39 ----- apps/app/hooks/use-my-issues-filter.tsx | 2 +- .../[workspaceSlug]/me/workspace-invites.tsx | 156 ------------------ .../projects/[projectId]/issues/[issueId].tsx | 105 ++++++------ .../projects/[projectId]/settings/states.tsx | 28 ++-- apps/app/services/workspace.service.ts | 11 -- apps/app/types/issues.d.ts | 62 +++---- 22 files changed, 255 insertions(+), 372 deletions(-) delete mode 100644 apps/app/hooks/use-local-storage.tsx delete mode 100644 apps/app/pages/[workspaceSlug]/me/workspace-invites.tsx diff --git a/apps/app/components/common/board-view/single-issue.tsx b/apps/app/components/common/board-view/single-issue.tsx index 445982035..7dd333e3f 100644 --- a/apps/app/components/common/board-view/single-issue.tsx +++ b/apps/app/components/common/board-view/single-issue.tsx @@ -249,6 +249,11 @@ const SingleBoardIssue: React.FC = ({ )} )} + {/* {properties.cycle && !typeId && ( +
+ {issue.issue_cycle ? issue.issue_cycle.cycle_detail.name : "None"} +
+ )} */} {properties.due_date && (
= ({ type: "error", message: "Please select atleast one issue", }); + return; } await handleOnSubmit(data); handleClose(); + + setToastAlert({ + title: "Success", + type: "success", + message: `Issue${data.issues.length > 1 ? "s" : ""} added successfully`, + }); }; const filteredIssues: IIssue[] = diff --git a/apps/app/components/common/list-view/single-issue.tsx b/apps/app/components/common/list-view/single-issue.tsx index 99b30d149..3f144568a 100644 --- a/apps/app/components/common/list-view/single-issue.tsx +++ b/apps/app/components/common/list-view/single-issue.tsx @@ -234,9 +234,14 @@ const SingleListIssue: React.FC = ({ ))} )} + {/* {properties.cycle && !typeId && ( +
+ {issue.issue_cycle ? issue.issue_cycle.cycle_detail.name : "None"} +
+ )} */} {properties.due_date && (
= ({
)} {properties.sub_issue_count && ( -
+
{issue.sub_issues_count} {issue.sub_issues_count === 1 ? "sub-issue" : "sub-issues"}
)} diff --git a/apps/app/components/issues/modal.tsx b/apps/app/components/issues/modal.tsx index 8a32f4cbb..3f7555435 100644 --- a/apps/app/components/issues/modal.tsx +++ b/apps/app/components/issues/modal.tsx @@ -144,7 +144,7 @@ export const CreateUpdateIssueModal: React.FC = ({ setToastAlert({ title: "Success", type: "success", - message: `Issue ${data ? "updated" : "created"} successfully`, + message: "Issue created successfully", }); if (payload.assignees_list?.some((assignee) => assignee === user?.id)) mutate(USER_ISSUE); diff --git a/apps/app/components/project/cycles/confirm-cycle-deletion.tsx b/apps/app/components/project/cycles/confirm-cycle-deletion.tsx index 977dc8ac0..ab35d343b 100644 --- a/apps/app/components/project/cycles/confirm-cycle-deletion.tsx +++ b/apps/app/components/project/cycles/confirm-cycle-deletion.tsx @@ -5,12 +5,14 @@ import { useRouter } from "next/router"; import { mutate } from "swr"; // headless ui import { Dialog, Transition } from "@headlessui/react"; -import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; // services import cycleService from "services/cycles.service"; +// hooks +import useToast from "hooks/use-toast"; // ui import { Button } from "components/ui"; // icons +import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; // types import type { ICycle } from "types"; type TConfirmCycleDeletionProps = { @@ -21,15 +23,19 @@ type TConfirmCycleDeletionProps = { // fetch-keys import { CYCLE_LIST } from "constants/fetch-keys"; -const ConfirmCycleDeletion: React.FC = (props) => { - const { isOpen, setIsOpen, data } = props; - +const ConfirmCycleDeletion: React.FC = ({ + isOpen, + setIsOpen, + data, +}) => { const cancelButtonRef = useRef(null); const [isDeleteLoading, setIsDeleteLoading] = useState(false); const router = useRouter(); const { workspaceSlug } = router.query; + const { setToastAlert } = useToast(); + useEffect(() => { data && setIsOpen(true); }, [data, setIsOpen]); @@ -51,6 +57,12 @@ const ConfirmCycleDeletion: React.FC = (props) => { false ); handleClose(); + + setToastAlert({ + title: "Success", + type: "success", + message: "Cycle deleted successfully", + }); }) .catch((error) => { console.log(error); 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 7d36bf6ca..9695adea1 100644 --- a/apps/app/components/project/cycles/create-update-cycle-modal.tsx +++ b/apps/app/components/project/cycles/create-update-cycle-modal.tsx @@ -9,6 +9,8 @@ import { Controller, useForm } from "react-hook-form"; import { Dialog, Transition } from "@headlessui/react"; // services import cycleService from "services/cycles.service"; +// hooks +import useToast from "hooks/use-toast"; // ui import { Button, Input, TextArea, CustomSelect } from "components/ui"; // common @@ -37,6 +39,8 @@ const CreateUpdateCycleModal: React.FC = ({ isOpen, setIsOpen, data, proj const router = useRouter(); const { workspaceSlug } = router.query; + const { setToastAlert } = useToast(); + const { register, formState: { errors, isSubmitting }, @@ -69,7 +73,13 @@ const CreateUpdateCycleModal: React.FC = ({ isOpen, setIsOpen, data, proj .createCycle(workspaceSlug as string, projectId, payload) .then((res) => { mutate(CYCLE_LIST(projectId), (prevData) => [res, ...(prevData ?? [])], false); + handleClose(); + setToastAlert({ + title: "Success", + type: "success", + message: "Cycle created successfully", + }); }) .catch((err) => { Object.keys(err).map((key) => { @@ -82,20 +92,14 @@ const CreateUpdateCycleModal: React.FC = ({ isOpen, setIsOpen, data, proj await cycleService .updateCycle(workspaceSlug as string, projectId, data.id, payload) .then((res) => { - mutate( - CYCLE_LIST(projectId), - (prevData) => { - const newData = prevData?.map((item) => { - if (item.id === res.id) return res; - - return item; - }); - - return newData; - }, - false - ); + mutate(CYCLE_LIST(projectId)); handleClose(); + + setToastAlert({ + title: "Success", + type: "success", + message: "Cycle updated successfully", + }); }) .catch((err) => { Object.keys(err).map((key) => { 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 3cf8e4075..ecf3e7874 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 @@ -8,16 +8,18 @@ import useSWR, { mutate } from "swr"; import { Dialog, Transition } from "@headlessui/react"; // icons import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; -// types -import type { IState } from "types"; // services import stateServices from "services/state.service"; import issuesServices from "services/issues.service"; +// hooks +import useToast from "hooks/use-toast"; // ui import { Button } from "components/ui"; // helpers import { groupBy } from "helpers/array.helper"; -// fetch api +// types +import type { IState } from "types"; +// fetch-keys import { STATE_LIST, PROJECT_ISSUES_LIST } from "constants/fetch-keys"; type Props = { @@ -33,6 +35,8 @@ const ConfirmStateDeletion: React.FC = ({ isOpen, onClose, data }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; + const { setToastAlert } = useToast(); + const { data: issues } = useSWR( workspaceSlug && projectId ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string) @@ -61,6 +65,12 @@ const ConfirmStateDeletion: React.FC = ({ isOpen, onClose, data }) => { false ); handleClose(); + + setToastAlert({ + title: "Success", + type: "success", + message: "State deleted successfully", + }); }) .catch((error) => { console.log(error); @@ -78,7 +88,7 @@ const ConfirmStateDeletion: React.FC = ({ isOpen, onClose, data }) => { @@ -94,7 +104,7 @@ const ConfirmStateDeletion: React.FC = ({ isOpen, onClose, data }) => {
-
+
= ({ onClose, selectedGroup, }) => { + const { setToastAlert } = useToast(); + const { register, handleSubmit, @@ -81,6 +87,12 @@ export const CreateUpdateStateInline: React.FC = ({ .then((res) => { mutate(STATE_LIST(projectId), (prevData) => [...(prevData ?? []), res]); handleClose(); + + setToastAlert({ + title: "Success", + type: "success", + message: "State created successfully", + }); }) .catch((err) => { Object.keys(err).map((key) => { @@ -95,16 +107,14 @@ export const CreateUpdateStateInline: React.FC = ({ ...payload, }) .then((res) => { - mutate(STATE_LIST(projectId), (prevData) => { - const newData = prevData?.map((item) => { - if (item.id === res.id) { - return res; - } - return item; - }); - return newData; - }); + mutate(STATE_LIST(projectId)); handleClose(); + + setToastAlert({ + title: "Success", + type: "success", + message: "State updated successfully", + }); }) .catch((err) => { Object.keys(err).map((key) => { diff --git a/apps/app/components/project/issues/confirm-issue-deletion.tsx b/apps/app/components/project/issues/confirm-issue-deletion.tsx index a9f689543..38d2258ce 100644 --- a/apps/app/components/project/issues/confirm-issue-deletion.tsx +++ b/apps/app/components/project/issues/confirm-issue-deletion.tsx @@ -3,20 +3,21 @@ import React, { useEffect, useRef, useState } from "react"; import { useRouter } from "next/router"; import { mutate } from "swr"; + // headless ui import { Dialog, Transition } from "@headlessui/react"; -// fetching keys -import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; -import type { CycleIssueResponse, IIssue, IssueResponse, ModuleIssueResponse } from "types"; -import { CYCLE_ISSUES, PROJECT_ISSUES_LIST, MODULE_ISSUES } from "constants/fetch-keys"; // services import issueServices from "services/issues.service"; // hooks import useToast from "hooks/use-toast"; // icons +import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; // ui import { Button } from "components/ui"; // types +import type { CycleIssueResponse, IIssue, IssueResponse, ModuleIssueResponse } from "types"; +// fetch-keys +import { CYCLE_ISSUES, PROJECT_ISSUES_LIST, MODULE_ISSUES } from "constants/fetch-keys"; type Props = { isOpen: boolean; @@ -79,12 +80,12 @@ const ConfirmIssueDeletion: React.FC = (props) => { ); } + handleClose(); setToastAlert({ title: "Success", type: "success", message: "Issue deleted successfully", }); - handleClose(); }) .catch((error) => { console.log(error); 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 5958068b5..46dc55594 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 @@ -11,7 +11,7 @@ import { RectangleStackIcon, MagnifyingGlassIcon } from "@heroicons/react/24/out // services import issuesServices from "services/issues.service"; // types -import { IIssue, IssueResponse } from "types"; +import { IIssue } from "types"; // constants import { PROJECT_ISSUES_LIST, SUB_ISSUES } from "constants/fetch-keys"; @@ -48,16 +48,16 @@ const AddAsSubIssue: React.FC = ({ isOpen, setIsOpen, parent }) => { }; const addAsSubIssue = (issueId: string) => { - if (workspaceSlug && projectId) { - issuesServices - .patchIssue(workspaceSlug as string, projectId as string, issueId, { parent: parent?.id }) - .then((res) => { - mutate(SUB_ISSUES(parent?.id ?? "")); - }) - .catch((e) => { - console.log(e); - }); - } + if (!workspaceSlug || !projectId) return; + + issuesServices + .patchIssue(workspaceSlug as string, projectId as string, issueId, { parent: parent?.id }) + .then((res) => { + mutate(SUB_ISSUES(parent?.id ?? "")); + }) + .catch((e) => { + console.log(e); + }); }; return ( @@ -140,6 +140,9 @@ const AddAsSubIssue: React.FC = ({ isOpen, setIsOpen, parent }) => { backgroundColor: issue.state_detail.color, }} /> + + {issue.project_detail.identifier}-{issue.sequence_id} + {issue.name} ); diff --git a/apps/app/components/project/modules/confirm-module-deletion.tsx b/apps/app/components/project/modules/confirm-module-deletion.tsx index 2a83633de..df3f32fea 100644 --- a/apps/app/components/project/modules/confirm-module-deletion.tsx +++ b/apps/app/components/project/modules/confirm-module-deletion.tsx @@ -1,19 +1,21 @@ -// react import React, { useEffect, useRef, useState } from "react"; -// next + import { useRouter } from "next/router"; -// swr + import { mutate } from "swr"; -// services + // headless ui import { Dialog, Transition } from "@headlessui/react"; +// services +import modulesService from "services/modules.service"; +// hooks +import useToast from "hooks/use-toast"; // ui +import { Button } from "components/ui"; // icons import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; // types import type { IModule } from "types"; -import { Button } from "components/ui"; -import modulesService from "services/modules.service"; // fetch-keys import { MODULE_LIST } from "constants/fetch-keys"; @@ -31,6 +33,8 @@ const ConfirmModuleDeletion: React.FC = ({ isOpen, setIsOpen, data }) => query: { workspaceSlug }, } = router; + const { setToastAlert } = useToast(); + const cancelButtonRef = useRef(null); const handleClose = () => { @@ -48,6 +52,12 @@ const ConfirmModuleDeletion: React.FC = ({ isOpen, setIsOpen, data }) => mutate(MODULE_LIST(data.project)); router.push(`/${workspaceSlug}/projects/${data.project}/modules`); handleClose(); + + setToastAlert({ + title: "Success", + type: "success", + message: "Module deleted successfully", + }); }) .catch((error) => { console.log(error); 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 e5e3668f1..bb9b78d9f 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 @@ -4,11 +4,10 @@ import { useRouter } from "next/router"; import { mutate } from "swr"; +// react-hook-form import { useForm } from "react-hook-form"; - +// headless ui import { Dialog, Transition } from "@headlessui/react"; -// types -import type { IModule } from "types"; // components import SelectLead from "components/project/modules/create-update-module-modal/select-lead"; import SelectMembers from "components/project/modules/create-update-module-modal/select-members"; @@ -17,9 +16,13 @@ import SelectStatus from "components/project/modules/create-update-module-modal/ import { Button, Input, TextArea } from "components/ui"; // services import modulesService from "services/modules.service"; +// hooks +import useToast from "hooks/use-toast"; // helpers import { renderDateFormat } from "helpers/date-time.helper"; -// fetch keys +// types +import type { IModule } from "types"; +// fetch-keys import { MODULE_LIST } from "constants/fetch-keys"; type Props = { @@ -41,6 +44,8 @@ const CreateUpdateModuleModal: React.FC = ({ isOpen, setIsOpen, data, pro const router = useRouter(); const { workspaceSlug } = router.query; + const { setToastAlert } = useToast(); + const { register, formState: { errors, isSubmitting }, @@ -65,6 +70,12 @@ const CreateUpdateModuleModal: React.FC = ({ isOpen, setIsOpen, data, pro .then(() => { mutate(MODULE_LIST(projectId)); handleClose(); + + setToastAlert({ + title: "Success", + type: "success", + message: "Module created successfully", + }); }) .catch((err) => { Object.keys(err).map((key) => { @@ -91,6 +102,12 @@ const CreateUpdateModuleModal: React.FC = ({ isOpen, setIsOpen, data, pro false ); handleClose(); + + setToastAlert({ + title: "Success", + type: "success", + message: "Module updated successfully", + }); }) .catch((err) => { Object.keys(err).map((key) => { diff --git a/apps/app/components/rich-text-editor/index.tsx b/apps/app/components/rich-text-editor/index.tsx index daf9e8f05..cb3796c83 100644 --- a/apps/app/components/rich-text-editor/index.tsx +++ b/apps/app/components/rich-text-editor/index.tsx @@ -91,7 +91,7 @@ const RemirrorRichTextEditor: FC = (props) => { () => new Promise(async (resolve, reject) => { const imageUrl = await fileService - .uploadFile(workspaceSlug as string, formData) // TODO: verify why workspaceSlug is required for uploading a file + .uploadFile(workspaceSlug as string, formData) .then((response) => response.asset); resolve({ diff --git a/apps/app/constants/fetch-keys.ts b/apps/app/constants/fetch-keys.ts index dcac1e08e..37466673e 100644 --- a/apps/app/constants/fetch-keys.ts +++ b/apps/app/constants/fetch-keys.ts @@ -23,7 +23,7 @@ export const PROJECT_ISSUES_DETAILS = (issueId: string) => `PROJECT_ISSUES_DETAI export const PROJECT_ISSUES_PROPERTIES = (projectId: string) => `PROJECT_ISSUES_PROPERTIES_${projectId}`; export const PROJECT_ISSUES_COMMENTS = (issueId: string) => `PROJECT_ISSUES_COMMENTS_${issueId}`; -export const PROJECT_ISSUES_ACTIVITY = "PROJECT_ISSUES_ACTIVITY"; +export const PROJECT_ISSUES_ACTIVITY = (issueId: string) => `PROJECT_ISSUES_ACTIVITY_${issueId}`; export const PROJECT_ISSUE_BY_STATE = (projectId: string) => `PROJECT_ISSUE_BY_STATE_${projectId}`; export const PROJECT_ISSUE_LABELS = (projectId: string) => `PROJECT_ISSUE_LABELS_${projectId}`; diff --git a/apps/app/hooks/use-issue-properties.tsx b/apps/app/hooks/use-issue-properties.tsx index 526fd554d..ea6c9f96b 100644 --- a/apps/app/hooks/use-issue-properties.tsx +++ b/apps/app/hooks/use-issue-properties.tsx @@ -13,7 +13,7 @@ const initialValues: Properties = { assignee: true, priority: false, due_date: false, - cycle: false, + // cycle: false, sub_issue_count: false, }; @@ -86,7 +86,7 @@ const useIssuesProperties = (workspaceSlug?: string, projectId?: string) => { assignee: properties.assignee, priority: properties.priority, due_date: properties.due_date, - cycle: properties.cycle, + // cycle: properties.cycle, sub_issue_count: properties.sub_issue_count, }; diff --git a/apps/app/hooks/use-local-storage.tsx b/apps/app/hooks/use-local-storage.tsx deleted file mode 100644 index 1cdba2364..000000000 --- a/apps/app/hooks/use-local-storage.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { useState, useEffect, useCallback } from "react"; - -// TODO: No Use of this -const useLocalStorage = ( - key: string, - initialValue?: T extends Function ? never : T | (() => T) -) => { - const [value, setValue] = useState(""); - - useEffect(() => { - const data = window.localStorage.getItem(key); - if (data !== null && data !== "undefined") setValue(JSON.parse(data)); - else setValue(typeof initialValue === "function" ? initialValue() : initialValue); - }, [key, initialValue]); - - const updateState = useCallback( - (value: T) => { - if (!value) window.localStorage.removeItem(key); - else window.localStorage.setItem(key, JSON.stringify(value)); - setValue(value); - window.dispatchEvent(new Event(`local-storage-change-${key}`)); - }, - [key] - ); - - const reHydrateState = useCallback(() => { - const data = window.localStorage.getItem(key); - if (data !== null) setValue(JSON.parse(data)); - }, [key]); - - useEffect(() => { - window.addEventListener(`local-storage-change-${key}`, reHydrateState); - return () => window.removeEventListener(`local-storage-change-${key}`, reHydrateState); - }, [reHydrateState, key]); - - return [value, updateState]; -}; - -export default useLocalStorage; diff --git a/apps/app/hooks/use-my-issues-filter.tsx b/apps/app/hooks/use-my-issues-filter.tsx index 1f9c3b28a..583f58ed2 100644 --- a/apps/app/hooks/use-my-issues-filter.tsx +++ b/apps/app/hooks/use-my-issues-filter.tsx @@ -21,7 +21,7 @@ const initialValues: Properties = { assignee: true, priority: false, due_date: false, - cycle: false, + // cycle: false, sub_issue_count: false, }; diff --git a/apps/app/pages/[workspaceSlug]/me/workspace-invites.tsx b/apps/app/pages/[workspaceSlug]/me/workspace-invites.tsx deleted file mode 100644 index 2f68f62d0..000000000 --- a/apps/app/pages/[workspaceSlug]/me/workspace-invites.tsx +++ /dev/null @@ -1,156 +0,0 @@ -// FIXME: remove this page - -import React, { useState } from "react"; -// next -import Link from "next/link"; -import { useRouter } from "next/router"; -import useSWR from "swr"; -import type { NextPage } from "next"; -// services -import workspaceService from "services/workspace.service"; -// hoc -// import withAuthWrapper from "lib/hoc/withAuthWrapper"; -// layouts -import AppLayout from "layouts/app-layout"; -// ui -import { Button } from "components/ui"; -// swr -import { USER_WORKSPACES } from "constants/fetch-keys"; - -const MyWorkspacesInvites: NextPage = () => { - const router = useRouter(); - - const [invitationsRespond, setInvitationsRespond] = useState([]); - - const { data: workspaces } = useSWR(USER_WORKSPACES, () => workspaceService.userWorkspaces(), { - shouldRetryOnError: false, - }); - - const { data: workspaceInvitations, mutate: mutateInvitations } = useSWR( - "WORKSPACE_INVITATIONS", - () => workspaceService.userWorkspaceInvitations() - ); - - const handleInvitation = (workspace_invitation: any, action: string) => { - if (action === "accepted") { - setInvitationsRespond((prevData: any) => [...prevData, workspace_invitation.workspace.id]); - } else if (action === "withdraw") { - setInvitationsRespond((prevData: any) => - prevData.filter((item: string) => item !== workspace_invitation.workspace.id) - ); - } - }; - - const submitInvitations = () => { - workspaceService - .joinWorkspaces({ workspace_ids: invitationsRespond }) - .then(async (res) => { - console.log(res); - await mutateInvitations(); - - router.push("/"); - }) - .catch((err: any) => console.log(err)); - }; - - return ( - -
-
- {(workspaceInvitations as any)?.length > 0 ? ( - <> -
-
-
-

Workspace Invitations

-
- {workspaceInvitations?.map((item: any) => ( -
-
- - handleInvitation( - item, - item.accepted - ? "withdraw" - : invitationsRespond.includes(item.workspace.id) - ? "withdraw" - : "accepted" - ) - } - type="checkbox" - className="h-4 w-4 rounded border-gray-300 text-theme focus:ring-indigo-500" - /> -
-
- -
- {invitationsRespond.includes(item.workspace.id) ? ( -
-

Accepted

- -
- ) : ( - - )} -
-
-
- ))} -
-
-
-
-
- - - - - -
- - ) : ( -
- No Invitaions Found -

- - Click Here - - - to redirect home -

-
- )} -
-
-
- ); -}; - -export default MyWorkspacesInvites; diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx index 67a71353d..1d9b890c6 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx @@ -1,12 +1,14 @@ import React, { useCallback, useEffect, useState } from "react"; + import Link from "next/link"; import { useRouter } from "next/router"; + import useSWR, { mutate } from "swr"; + +// react-hook-form import { useForm } from "react-hook-form"; -import { ChevronLeftIcon, ChevronRightIcon, PlusIcon } from "@heroicons/react/24/outline"; // services import issuesService from "services/issues.service"; -import projectService from "services/project.service"; // lib import { requiredAuth } from "lib/auth"; // layouts @@ -25,12 +27,13 @@ import { // ui import { Loader, HeaderButton, CustomMenu } from "components/ui"; import { Breadcrumbs } from "components/breadcrumbs"; +// icons +import { ChevronLeftIcon, ChevronRightIcon, PlusIcon } from "@heroicons/react/24/outline"; // types import { IIssue } from "types"; import type { NextPage, NextPageContext } from "next"; // fetch-keys import { - PROJECT_DETAILS, PROJECT_ISSUES_LIST, PROJECT_ISSUES_ACTIVITY, ISSUE_DETAILS, @@ -52,8 +55,6 @@ const defaultValues = { }; const IssueDetailsPage: NextPage = () => { - const router = useRouter(); - const { workspaceSlug, projectId, issueId } = router.query; // states const [isOpen, setIsOpen] = useState(false); const [isAddAsSubIssueOpen, setIsAddAsSubIssueOpen] = useState(false); @@ -61,15 +62,14 @@ const IssueDetailsPage: NextPage = () => { (Partial & { actionType: "createIssue" | "edit" | "delete" }) | undefined >(undefined); + const router = useRouter(); + const { workspaceSlug, projectId, issueId } = router.query; + const { data: issueDetails, mutate: mutateIssueDetails } = useSWR( - issueId && workspaceSlug && projectId ? ISSUE_DETAILS(issueId as string) : null, - issueId && workspaceSlug && projectId + workspaceSlug && projectId && issueId ? ISSUE_DETAILS(issueId as string) : null, + workspaceSlug && projectId && issueId ? () => - issuesService.retrieve( - workspaceSlug?.toString(), - projectId?.toString(), - issueId?.toString() - ) + issuesService.retrieve(workspaceSlug as string, projectId as string, issueId as string) : null ); @@ -81,13 +81,6 @@ const IssueDetailsPage: NextPage = () => { : null ); - const { data: activeProject } = useSWR( - workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null, - workspaceSlug && projectId - ? () => projectService.getProject(workspaceSlug as string, projectId as string) - : null - ); - const { data: issues } = useSWR( workspaceSlug && projectId ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string) @@ -98,7 +91,7 @@ const IssueDetailsPage: NextPage = () => { ); const { data: issueActivities, mutate: mutateIssueActivities } = useSWR( - workspaceSlug && projectId && issueId ? PROJECT_ISSUES_ACTIVITY : null, + workspaceSlug && projectId && issueId ? PROJECT_ISSUES_ACTIVITY(issueId as string) : null, workspaceSlug && projectId && issueId ? () => issuesService.getIssueActivities( @@ -141,7 +134,16 @@ const IssueDetailsPage: NextPage = () => { const submitChanges = useCallback( (formData: Partial) => { - if (!workspaceSlug || !activeProject || !issueId) return; + if (!workspaceSlug || !projectId || !issueId) return; + + mutate( + ISSUE_DETAILS(issueId as string), + (prevData: IIssue) => ({ + ...prevData, + ...formData, + }), + false + ); const payload = { ...formData }; issuesService @@ -154,21 +156,21 @@ const IssueDetailsPage: NextPage = () => { console.error(e); }); }, - [activeProject, workspaceSlug, issueId, projectId, mutateIssueDetails, mutateIssueActivities] + [workspaceSlug, issueId, projectId, mutateIssueDetails, mutateIssueActivities] ); const handleSubIssueRemove = (issueId: string) => { - if (workspaceSlug && activeProject) { - issuesService - .patchIssue(workspaceSlug as string, activeProject.id, issueId, { parent: null }) - .then((res) => { - mutate(SUB_ISSUES(issueDetails?.id ?? "")); - mutateIssueActivities(); - }) - .catch((e) => { - console.error(e); - }); - } + if (!workspaceSlug || !projectId) return; + + issuesService + .patchIssue(workspaceSlug as string, projectId as string, issueId, { parent: null }) + .then((res) => { + mutate(SUB_ISSUES(issueDetails?.id ?? "")); + mutateIssueActivities(); + }) + .catch((e) => { + console.error(e); + }); }; /** @@ -177,14 +179,14 @@ const IssueDetailsPage: NextPage = () => { */ const handleDescriptionFormSubmit = useCallback( (values: IssueDescriptionFormValues) => { - if (workspaceSlug && projectId && issueId) { - issuesService - .updateIssue(workspaceSlug?.toString(), projectId.toString(), issueId.toString(), values) - .then((res) => { - console.log(res); - mutateIssueActivities(); - }); - } + if (!workspaceSlug || !projectId || !issueId) return; + + issuesService + .updateIssue(workspaceSlug as string, projectId as string, issueId as string, values) + .then((res) => { + console.log(res); + mutateIssueActivities(); + }); }, [workspaceSlug, projectId, issueId, mutateIssueActivities] ); @@ -196,11 +198,11 @@ const IssueDetailsPage: NextPage = () => { breadcrumbs={ @@ -249,14 +251,16 @@ const IssueDetailsPage: NextPage = () => { parent={issueDetails} /> )} - {issueDetails && activeProject ? ( + {issueDetails && projectId ? (
- {/* TODO add flex-grow, if needed */} = (props) => {
+ {key === activeGroup && ( + { + setActiveGroup(null); + setSelectedState(null); + }} + workspaceSlug={workspaceSlug as string} + data={null} + selectedGroup={key as keyof StateGroup} + /> + )} {groupedStates[key]?.map((state) => state.id !== selectedState ? (
= (props) => {
) )} - {key === activeGroup && ( - { - setActiveGroup(null); - setSelectedState(null); - }} - workspaceSlug={workspaceSlug as string} - data={null} - selectedGroup={key as keyof StateGroup} - /> - )}
)) diff --git a/apps/app/services/workspace.service.ts b/apps/app/services/workspace.service.ts index d00f5324d..034104242 100644 --- a/apps/app/services/workspace.service.ts +++ b/apps/app/services/workspace.service.ts @@ -154,17 +154,6 @@ class WorkspaceService extends APIService { }); } - async updateWorkspaceInvitation( - workspaceSlug: string, - invitationId: string - ): Promise { - return this.put(`/api/workspaces/${workspaceSlug}/invitations/${invitationId}/`) - .then((response) => response?.data) - .catch((error) => { - throw error?.response?.data; - }); - } - async deleteWorkspaceInvitations(workspaceSlug: string, invitationId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/invitations/${invitationId}/`) .then((response) => response?.data) diff --git a/apps/app/types/issues.d.ts b/apps/app/types/issues.d.ts index 4523ac48d..c2703d566 100644 --- a/apps/app/types/issues.d.ts +++ b/apps/app/types/issues.d.ts @@ -51,48 +51,48 @@ export interface IIssueCycle { } export interface IIssue { - id: string; - state_detail: IState; - label_details: any[]; + assignees: any[] | null; assignee_details: IUser[]; assignees_list: string[]; + attachments: any[]; blocked_by_issue_details: any[]; + blocked_issue_details: any[]; blocked_issues: BlockeIssue[]; - blocker_issues: BlockeIssue[]; - blockers_list: string[]; blocked_list: string[]; + blocker_issues: BlockeIssue[]; + blockers: any[]; + blockers_list: string[]; blocks_list: string[]; bridge: string; created_at: Date; - updated_at: Date; - name: string; - issue_cycle: IIssueCycle | null; - issue_module: IIssueModule | null; - description: any; - description_html: any; - priority: string | null; - start_date: string | null; - target_date: string | null; - sequence_id: number; - attachments: any[]; created_by: string; - updated_by: string; - project: string; - project_detail: IProject; - workspace: string; - parent: string | null; - parent_detail: IProject | null; - state: string; - assignees: any[] | null; - labels: any[]; - labels_list: string[]; - blockers: any[]; - blocked_issue_details: any[]; - sprints: string | null; - module: string | null; cycle: string | null; cycle_detail: ICycle | null; + description: any; + description_html: any; + id: string; + issue_cycle: IIssueCycle | null; + issue_module: IIssueModule | null; + label_details: any[]; + module: string | null; + name: string; + parent: string | null; + parent_detail: IProject | null; + priority: string | null; + project: string; + project_detail: IProject; + sequence_id: number; + sprints: string | null; + start_date: string | null; + state: string; + state_detail: IState; sub_issues_count: number; + target_date: string | null; + updated_at: Date; + updated_by: string; + workspace: string; + labels: any[]; + labels_list: string[]; } export interface BlockeIssue { @@ -151,7 +151,7 @@ export type Properties = { assignee: boolean; priority: boolean; due_date: boolean; - cycle: boolean; + // cycle: boolean; sub_issue_count: boolean; };