From 9fdc56db0fc6c91211f20299844d2f291a0b07e5 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Mon, 15 May 2023 11:35:19 +0530 Subject: [PATCH] chore: user cannot update their own role (#1041) --- .../projects/[projectId]/settings/control.tsx | 6 ++-- .../[projectId]/settings/estimates.tsx | 4 +-- .../[projectId]/settings/features.tsx | 5 +-- .../projects/[projectId]/settings/index.tsx | 2 +- .../[projectId]/settings/integrations.tsx | 2 +- .../projects/[projectId]/settings/labels.tsx | 4 +-- .../projects/[projectId]/settings/members.tsx | 20 ++++++----- .../projects/[projectId]/settings/states.tsx | 4 +-- .../[workspaceSlug]/settings/billing.tsx | 2 +- .../settings/import-export.tsx | 2 +- .../pages/[workspaceSlug]/settings/index.tsx | 2 +- .../[workspaceSlug]/settings/integrations.tsx | 2 +- .../[workspaceSlug]/settings/members.tsx | 36 +++++++++++-------- apps/app/types/projects.d.ts | 1 + apps/app/types/workspace.d.ts | 2 +- 15 files changed, 55 insertions(+), 39 deletions(-) diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/control.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/control.tsx index 8cf0403ed..fc699aeab 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/control.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/control.tsx @@ -5,6 +5,7 @@ import Image from "next/image"; import useSWR, { mutate } from "swr"; +// react-hook-form import { Controller, useForm } from "react-hook-form"; // layouts import { ProjectAuthorizationWrapper } from "layouts/auth-layout"; @@ -12,6 +13,8 @@ import { ProjectAuthorizationWrapper } from "layouts/auth-layout"; import projectService from "services/project.service"; // hooks import useToast from "hooks/use-toast"; +// components +import { SettingsHeader } from "components/project"; // ui import { CustomSelect, Loader, SecondaryButton } from "components/ui"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; @@ -20,7 +23,6 @@ import { IProject, IWorkspace } from "types"; import type { NextPage } from "next"; // fetch-keys import { PROJECTS_LIST, PROJECT_DETAILS, PROJECT_MEMBERS } from "constants/fetch-keys"; -import { SettingsHeader } from "components/project"; const defaultValues: Partial = { project_lead: null, @@ -104,7 +106,7 @@ const ControlSettings: NextPage = () => { } > -
+
diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx index f4192528c..4051d09bf 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx @@ -13,6 +13,7 @@ import useProjectDetails from "hooks/use-project-details"; import { ProjectAuthorizationWrapper } from "layouts/auth-layout"; // components import { CreateUpdateEstimateModal, SingleEstimate } from "components/estimates"; +import { SettingsHeader } from "components/project"; //hooks import useToast from "hooks/use-toast"; // ui @@ -27,7 +28,6 @@ import { IEstimate, IProject } from "types"; import type { NextPage } from "next"; // fetch-keys import { ESTIMATES_LIST, PROJECT_DETAILS } from "constants/fetch-keys"; -import { SettingsHeader } from "components/project"; const EstimatesSettings: NextPage = () => { const [estimateFormOpen, setEstimateFormOpen] = useState(false); @@ -118,7 +118,7 @@ const EstimatesSettings: NextPage = () => { } > -
+

Estimates

diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/features.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/features.tsx index 2c8390a97..ee7a91fe9 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/features.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/features.tsx @@ -11,6 +11,8 @@ import trackEventServices, { MiscellaneousEventType } from "services/track-event import { ProjectAuthorizationWrapper } from "layouts/auth-layout"; // hooks import useToast from "hooks/use-toast"; +// components +import { SettingsHeader } from "components/project"; // ui import { SecondaryButton, ToggleSwitch } from "components/ui"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; @@ -22,7 +24,6 @@ import { IFavoriteProject, IProject } from "types"; import type { NextPage } from "next"; // fetch-keys import { FAVORITE_PROJECTS_LIST, PROJECTS_LIST, PROJECT_DETAILS } from "constants/fetch-keys"; -import { SettingsHeader } from "components/project"; const featuresList = [ { @@ -163,7 +164,7 @@ const FeaturesSettings: NextPage = () => { } > -
+

Features

diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx index 5535aa99a..4cd1bc42e 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx @@ -151,7 +151,7 @@ const GeneralSettings: NextPage = () => { router.push(`/${workspaceSlug}/projects`); }} /> - +
diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx index 5f5077a0e..53540e87a 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx @@ -54,7 +54,7 @@ const ProjectIntegrations: NextPage = () => { } > -
+
{workspaceIntegrations ? ( workspaceIntegrations.length > 0 ? ( diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx index ef88e4912..b0c98c9dc 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx @@ -16,6 +16,7 @@ import { SingleLabel, SingleLabelGroup, } from "components/labels"; +import { SettingsHeader } from "components/project"; // ui import { Loader, PrimaryButton } from "components/ui"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; @@ -26,7 +27,6 @@ import { IIssueLabels } from "types"; import type { NextPage } from "next"; // fetch-keys import { PROJECT_DETAILS, PROJECT_ISSUE_LABELS } from "constants/fetch-keys"; -import { SettingsHeader } from "components/project"; const LabelsSettings: NextPage = () => { // create/edit label form @@ -102,7 +102,7 @@ const LabelsSettings: NextPage = () => { } > -
+
diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/members.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/members.tsx index 88d03e538..6f1ecb38e 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/members.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/members.tsx @@ -11,11 +11,13 @@ import workspaceService from "services/workspace.service"; // hooks import useToast from "hooks/use-toast"; import useProjectDetails from "hooks/use-project-details"; +import useUser from "hooks/use-user"; // layouts import { ProjectAuthorizationWrapper } from "layouts/auth-layout"; // components import ConfirmProjectMemberRemove from "components/project/confirm-project-member-remove"; import SendProjectInvitationModal from "components/project/send-project-invitation-modal"; +import { SettingsHeader } from "components/project"; // ui import { CustomMenu, CustomSelect, Loader } from "components/ui"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; @@ -27,7 +29,6 @@ import type { NextPage } from "next"; import { PROJECT_INVITATIONS, PROJECT_MEMBERS, WORKSPACE_DETAILS } from "constants/fetch-keys"; // constants import { ROLE } from "constants/workspace"; -import { SettingsHeader } from "components/project"; const MembersSettings: NextPage = () => { const [inviteModal, setInviteModal] = useState(false); @@ -36,17 +37,17 @@ const MembersSettings: NextPage = () => { const { setToastAlert } = useToast(); - const { - query: { workspaceSlug, projectId }, - } = useRouter(); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; + + const { user } = useUser(); + const { projectDetails } = useProjectDetails(); const { data: activeWorkspace } = useSWR( workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null, () => (workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null) ); - const { projectDetails } = useProjectDetails(); - const { data: projectMembers, mutate: mutateMembers } = useSWR( workspaceSlug && projectId ? PROJECT_MEMBERS(projectId as string) : null, workspaceSlug && projectId @@ -62,8 +63,9 @@ const MembersSettings: NextPage = () => { ); const members = [ - ...(projectMembers?.map((item: any) => ({ + ...(projectMembers?.map((item) => ({ id: item.id, + memberId: item.member?.id, avatar: item.member?.avatar, first_name: item.member?.first_name, last_name: item.member?.last_name, @@ -74,6 +76,7 @@ const MembersSettings: NextPage = () => { })) || []), ...(projectInvitations?.map((item: any) => ({ id: item.id, + memberId: item.id, avatar: item.avatar ?? "", first_name: item.first_name ?? item.email, last_name: item.last_name ?? "", @@ -142,7 +145,7 @@ const MembersSettings: NextPage = () => { } > -
+
@@ -231,6 +234,7 @@ const MembersSettings: NextPage = () => { }); }} position="right" + disabled={member.memberId === user?.id} > {Object.keys(ROLE).map((key) => ( diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx index 39d83616d..77e821835 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx @@ -17,6 +17,7 @@ import { SingleState, StateGroup, } from "components/states"; +import { SettingsHeader } from "components/project"; // ui import { Loader } from "components/ui"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; @@ -28,7 +29,6 @@ import { getStatesList, orderStateGroups } from "helpers/state.helper"; import type { NextPage } from "next"; // fetch-keys import { STATES_LIST } from "constants/fetch-keys"; -import { SettingsHeader } from "components/project"; const StatesSettings: NextPage = () => { const [activeGroup, setActiveGroup] = useState(null); @@ -67,7 +67,7 @@ const StatesSettings: NextPage = () => { } > -
+
diff --git a/apps/app/pages/[workspaceSlug]/settings/billing.tsx b/apps/app/pages/[workspaceSlug]/settings/billing.tsx index 0e5cc69f4..02b23cce5 100644 --- a/apps/app/pages/[workspaceSlug]/settings/billing.tsx +++ b/apps/app/pages/[workspaceSlug]/settings/billing.tsx @@ -39,7 +39,7 @@ const BillingSettings: NextPage = () => { } > -
+
diff --git a/apps/app/pages/[workspaceSlug]/settings/import-export.tsx b/apps/app/pages/[workspaceSlug]/settings/import-export.tsx index 821ceee7a..c5473b30a 100644 --- a/apps/app/pages/[workspaceSlug]/settings/import-export.tsx +++ b/apps/app/pages/[workspaceSlug]/settings/import-export.tsx @@ -23,7 +23,7 @@ const ImportExport: NextPage = () => { } > -
+
diff --git a/apps/app/pages/[workspaceSlug]/settings/index.tsx b/apps/app/pages/[workspaceSlug]/settings/index.tsx index 045e9a893..1edd5ace9 100644 --- a/apps/app/pages/[workspaceSlug]/settings/index.tsx +++ b/apps/app/pages/[workspaceSlug]/settings/index.tsx @@ -173,7 +173,7 @@ const WorkspaceSettings: NextPage = () => { }} data={activeWorkspace ?? null} /> -
+
{activeWorkspace ? (
diff --git a/apps/app/pages/[workspaceSlug]/settings/integrations.tsx b/apps/app/pages/[workspaceSlug]/settings/integrations.tsx index de3aa1533..3a613e9bc 100644 --- a/apps/app/pages/[workspaceSlug]/settings/integrations.tsx +++ b/apps/app/pages/[workspaceSlug]/settings/integrations.tsx @@ -47,7 +47,7 @@ const WorkspaceIntegrations: NextPage = () => { } > -
+
diff --git a/apps/app/pages/[workspaceSlug]/settings/members.tsx b/apps/app/pages/[workspaceSlug]/settings/members.tsx index 05ae6249d..c703139b8 100644 --- a/apps/app/pages/[workspaceSlug]/settings/members.tsx +++ b/apps/app/pages/[workspaceSlug]/settings/members.tsx @@ -5,10 +5,11 @@ import { useRouter } from "next/router"; import useSWR from "swr"; -// hooks -import useToast from "hooks/use-toast"; // services import workspaceService from "services/workspace.service"; +// hooks +import useToast from "hooks/use-toast"; +import useUser from "hooks/use-user"; // layouts import { WorkspaceAuthorizationLayout } from "layouts/auth-layout"; import { SettingsHeader } from "components/workspace"; @@ -37,24 +38,27 @@ const MembersSettings: NextPage = () => { const { setToastAlert } = useToast(); + const { user } = useUser(); + const { data: activeWorkspace } = useSWR( - workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null, - () => (workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null) + workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug.toString()) : null, + () => (workspaceSlug ? workspaceService.getWorkspace(workspaceSlug.toString()) : null) ); - const { data: workspaceMembers, mutate: mutateMembers } = useSWR( - workspaceSlug ? WORKSPACE_MEMBERS(workspaceSlug as string) : null, - workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug as string) : null + const { data: workspaceMembers, mutate: mutateMembers } = useSWR( + workspaceSlug ? WORKSPACE_MEMBERS(workspaceSlug.toString()) : null, + workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug.toString()) : null ); - const { data: workspaceInvitations, mutate: mutateInvitations } = useSWR( + const { data: workspaceInvitations, mutate: mutateInvitations } = useSWR( workspaceSlug ? WORKSPACE_INVITATIONS : null, - workspaceSlug ? () => workspaceService.workspaceInvitations(workspaceSlug as string) : null + workspaceSlug ? () => workspaceService.workspaceInvitations(workspaceSlug.toString()) : null ); const members = [ ...(workspaceMembers?.map((item) => ({ id: item.id, + memberId: item.member?.id, avatar: item.member?.avatar, first_name: item.member?.first_name, last_name: item.member?.last_name, @@ -65,9 +69,10 @@ const MembersSettings: NextPage = () => { })) || []), ...(workspaceInvitations?.map((item) => ({ id: item.id, - avatar: item.avatar ?? "", - first_name: item.first_name ?? item.email, - last_name: item.last_name ?? "", + memberId: item.id, + avatar: "", + first_name: item.email, + last_name: "", email: item.email, role: item.role, status: item.accepted, @@ -138,7 +143,7 @@ const MembersSettings: NextPage = () => { } > -
+
@@ -197,8 +202,10 @@ const MembersSettings: NextPage = () => { label={ROLE[member.role as keyof typeof ROLE]} value={member.role} onChange={(value: any) => { + if (!workspaceSlug) return; + workspaceService - .updateWorkspaceMember(activeWorkspace?.slug as string, member.id, { + .updateWorkspaceMember(workspaceSlug?.toString(), member.id, { role: value, }) .then(() => { @@ -224,6 +231,7 @@ const MembersSettings: NextPage = () => { }); }} position="right" + disabled={member.memberId === user?.id} > {Object.keys(ROLE).map((key) => ( diff --git a/apps/app/types/projects.d.ts b/apps/app/types/projects.d.ts index 3fbf37678..e3d04e642 100644 --- a/apps/app/types/projects.d.ts +++ b/apps/app/types/projects.d.ts @@ -60,6 +60,7 @@ type ProjectViewTheme = { }; export interface IProjectMember { + id: string; member: IUserLite; project: IProject; workspace: IWorkspace; diff --git a/apps/app/types/workspace.d.ts b/apps/app/types/workspace.d.ts index 91948af46..fbb54d759 100644 --- a/apps/app/types/workspace.d.ts +++ b/apps/app/types/workspace.d.ts @@ -23,9 +23,9 @@ export interface IWorkspaceLite { } export interface IWorkspaceMemberInvitation { + accepted: boolean; readonly id: string; email: string; - accepted: boolean; token: string; message: string; responded_at: Date;