diff --git a/web/components/automation/auto-archive-automation.tsx b/web/components/automation/auto-archive-automation.tsx index 1083073da..dff5450dd 100644 --- a/web/components/automation/auto-archive-automation.tsx +++ b/web/components/automation/auto-archive-automation.tsx @@ -11,6 +11,7 @@ import { ArchiveRestore } from "lucide-react"; import { PROJECT_AUTOMATION_MONTHS } from "constants/project"; // types import { IProject } from "types"; +import { EUserWorkspaceRoles } from "constants/workspace"; type Props = { handleChange: (formData: Partial) => Promise; @@ -28,6 +29,8 @@ export const AutoArchiveAutomation: React.FC = observer((props) => { const projectDetails = projectStore.currentProjectDetails; const userRole = userStore.currentProjectRole; + const isAdmin = userRole === EUserWorkspaceRoles.ADMIN; + return ( <> = observer((props) => { projectDetails?.archive_in === 0 ? handleChange({ archive_in: 1 }) : handleChange({ archive_in: 0 }) } size="sm" - disabled={userRole !== 20} + disabled={!isAdmin} /> @@ -74,7 +77,7 @@ export const AutoArchiveAutomation: React.FC = observer((props) => { }} input width="w-full" - disabled={userRole !== 20} + disabled={!isAdmin} > <> {PROJECT_AUTOMATION_MONTHS.map((month) => ( diff --git a/web/components/automation/auto-close-automation.tsx b/web/components/automation/auto-close-automation.tsx index 1f0ef1c31..30b1bdc0f 100644 --- a/web/components/automation/auto-close-automation.tsx +++ b/web/components/automation/auto-close-automation.tsx @@ -11,6 +11,7 @@ import { ArchiveX } from "lucide-react"; import { IProject } from "types"; // fetch keys import { PROJECT_AUTOMATION_MONTHS } from "constants/project"; +import { EUserWorkspaceRoles } from "constants/workspace"; type Props = { handleChange: (formData: Partial) => Promise; @@ -53,6 +54,8 @@ export const AutoCloseAutomation: React.FC = observer((props) => { default_state: defaultState, }; + const isAdmin = userRole === EUserWorkspaceRoles.ADMIN; + return ( <> = observer((props) => { : handleChange({ close_in: 0, default_state: null }) } size="sm" - disabled={userRole !== 20} + disabled={!isAdmin} /> @@ -102,7 +105,7 @@ export const AutoCloseAutomation: React.FC = observer((props) => { }} input width="w-full" - disabled={userRole !== 20} + disabled={!isAdmin} > <> {PROJECT_AUTOMATION_MONTHS.map((month) => ( diff --git a/web/components/cycles/transfer-issues-modal.tsx b/web/components/cycles/transfer-issues-modal.tsx index bcbd8efef..55555e221 100644 --- a/web/components/cycles/transfer-issues-modal.tsx +++ b/web/components/cycles/transfer-issues-modal.tsx @@ -2,10 +2,12 @@ import React, { useState } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; import { Dialog, Transition } from "@headlessui/react"; +import { observer } from "mobx-react-lite"; // services import { CycleService } from "services/cycle.service"; // hooks import useToast from "hooks/use-toast"; +import { useMobxStore } from "lib/mobx/store-provider"; //icons import { ContrastIcon, TransferIcon } from "@plane/ui"; import { AlertCircle, Search, X } from "lucide-react"; @@ -23,17 +25,19 @@ type Props = { const cycleService = new CycleService(); -export const TransferIssuesModal: React.FC = ({ isOpen, handleClose }) => { +export const TransferIssuesModal: React.FC = observer(({ isOpen, handleClose }) => { const [query, setQuery] = useState(""); + const { cycleIssues: cycleIssueStore } = useMobxStore(); + const router = useRouter(); const { workspaceSlug, projectId, cycleId } = router.query; const { setToastAlert } = useToast(); const transferIssue = async (payload: any) => { - await cycleService - .transferIssues(workspaceSlug as string, projectId as string, cycleId as string, payload) + await cycleIssueStore + .transferIssuesFromCycle(workspaceSlug as string, projectId as string, cycleId as string, payload) .then(() => { setToastAlert({ type: "success", @@ -159,4 +163,4 @@ export const TransferIssuesModal: React.FC = ({ isOpen, handleClose }) => ); -}; +}); diff --git a/web/components/inbox/actions-header.tsx b/web/components/inbox/actions-header.tsx index be077df5c..83cdf1446 100644 --- a/web/components/inbox/actions-header.tsx +++ b/web/components/inbox/actions-header.tsx @@ -22,6 +22,7 @@ import { Button } from "@plane/ui"; import { CheckCircle2, ChevronDown, ChevronUp, Clock, FileStack, Inbox, Trash2, XCircle } from "lucide-react"; // types import type { TInboxStatus } from "types"; +import { EUserWorkspaceRoles } from "constants/workspace"; export const InboxActionsHeader = observer(() => { const [date, setDate] = useState(new Date()); @@ -71,7 +72,7 @@ export const InboxActionsHeader = observer(() => { }, [issue]); const issueStatus = issue?.issue_inbox[0].status; - const isAllowed = userRole === 15 || userRole === 20; + const isAllowed = !!userRole && userRole >= EUserWorkspaceRoles.MEMBER; const today = new Date(); const tomorrow = new Date(today); diff --git a/web/components/inbox/main-content.tsx b/web/components/inbox/main-content.tsx index 7356e9e7b..293930ffb 100644 --- a/web/components/inbox/main-content.tsx +++ b/web/components/inbox/main-content.tsx @@ -18,6 +18,7 @@ import { Loader, StateGroupIcon } from "@plane/ui"; import { renderShortDateWithYearFormat } from "helpers/date-time.helper"; // types import { IInboxIssue, IIssue } from "types"; +import { EUserWorkspaceRoles } from "constants/workspace"; const defaultValues: Partial = { name: "", @@ -167,6 +168,8 @@ export const InboxMainContent: React.FC = observer(() => { ); + const isAllowed = !!userRole && userRole >= EUserWorkspaceRoles.MEMBER; + return ( <> {issueDetails ? ( @@ -273,7 +276,7 @@ export const InboxMainContent: React.FC = observer(() => { description_html: issueDetails.description_html, }} handleFormSubmit={submitChanges} - isAllowed={userRole === 15 || userRole === 20 || user?.id === issueDetails.created_by} + isAllowed={isAllowed || user?.id === issueDetails.created_by} /> diff --git a/web/components/issues/issue-layouts/gantt/base-gantt-root.tsx b/web/components/issues/issue-layouts/gantt/base-gantt-root.tsx index b2a75e2d3..bf7ed2b42 100644 --- a/web/components/issues/issue-layouts/gantt/base-gantt-root.tsx +++ b/web/components/issues/issue-layouts/gantt/base-gantt-root.tsx @@ -25,6 +25,7 @@ import { IViewIssuesStore, } from "store/issues"; import { TUnGroupedIssues } from "store/issues/types"; +import { EUserWorkspaceRoles } from "constants/workspace"; interface IBaseGanttRoot { issueFiltersStore: @@ -69,7 +70,7 @@ export const BaseGanttRoot: React.FC = observer((props: IBaseGan ); }; - const isAllowed = currentProjectRole && currentProjectRole >= 15; + const isAllowed = !!currentProjectRole && currentProjectRole >= EUserWorkspaceRoles.MEMBER; return ( <> diff --git a/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx b/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx index e63b6e745..66d33ad16 100644 --- a/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx +++ b/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx @@ -31,6 +31,7 @@ import { KanBan } from "./default"; import { KanBanSwimLanes } from "./swimlanes"; import { EProjectStore } from "store/command-palette.store"; import { IssuePeekOverview } from "components/issues"; +import { EUserWorkspaceRoles } from "constants/workspace"; export interface IBaseKanBanLayout { issueStore: @@ -93,7 +94,7 @@ export const BaseKanBanRoot: React.FC = observer((props: IBas } = useMobxStore(); const { currentProjectRole } = userStore; - const isEditingAllowed = [15, 20].includes(currentProjectRole || 0); + const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserWorkspaceRoles.MEMBER; const issues = issueStore?.getIssues || {}; const issueIds = issueStore?.getIssuesIds || []; diff --git a/web/components/issues/issue-layouts/list/base-list-root.tsx b/web/components/issues/issue-layouts/list/base-list-root.tsx index 0b20a0ffe..6789ea63c 100644 --- a/web/components/issues/issue-layouts/list/base-list-root.tsx +++ b/web/components/issues/issue-layouts/list/base-list-root.tsx @@ -25,6 +25,7 @@ import { IIssueResponse } from "store/issues/types"; import { EProjectStore } from "store/command-palette.store"; import { IssuePeekOverview } from "components/issues"; import { useRouter } from "next/router"; +import { EUserWorkspaceRoles } from "constants/workspace"; enum EIssueActions { UPDATE = "update", @@ -83,7 +84,7 @@ export const BaseListRoot = observer((props: IBaseListRoot) => { } = useMobxStore(); const { currentProjectRole } = userStore; - const isEditingAllowed = [15, 20].includes(currentProjectRole || 0); + const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserWorkspaceRoles.MEMBER; const issueIds = issueStore?.getIssuesIds || []; const issues = issueStore?.getIssues; diff --git a/web/components/issues/issue-layouts/spreadsheet/base-spreadsheet-root.tsx b/web/components/issues/issue-layouts/spreadsheet/base-spreadsheet-root.tsx index db0aa37e1..e0b4c8cb5 100644 --- a/web/components/issues/issue-layouts/spreadsheet/base-spreadsheet-root.tsx +++ b/web/components/issues/issue-layouts/spreadsheet/base-spreadsheet-root.tsx @@ -18,6 +18,7 @@ import { observer } from "mobx-react-lite"; import { EFilterType, TUnGroupedIssues } from "store/issues/types"; import { EIssueActions } from "../types"; import { IQuickActionProps } from "../list/list-view-types"; +import { EUserWorkspaceRoles } from "constants/workspace"; interface IBaseSpreadsheetRoot { issueFiltersStore: @@ -49,7 +50,7 @@ export const BaseSpreadsheetRoot = observer((props: IBaseSpreadsheetRoot) => { } = useMobxStore(); const { currentProjectRole } = userStore; - const isEditingAllowed = [15, 20].includes(currentProjectRole || 0); + const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserWorkspaceRoles.MEMBER; const issuesResponse = issueStore.getIssues; const issueIds = (issueStore.getIssuesIds ?? []) as TUnGroupedIssues; diff --git a/web/components/issues/issue-peek-overview/issue-detail.tsx b/web/components/issues/issue-peek-overview/issue-detail.tsx index 4941c3e43..084fde367 100644 --- a/web/components/issues/issue-peek-overview/issue-detail.tsx +++ b/web/components/issues/issue-peek-overview/issue-detail.tsx @@ -15,6 +15,8 @@ import { IIssue } from "types"; // services import { FileService } from "services/file.service"; +import { EUserWorkspaceRoles } from "constants/workspace"; + const fileService = new FileService(); interface IPeekOverviewIssueDetails { @@ -35,7 +37,7 @@ export const PeekOverviewIssueDetails: FC = (props) = projectIssues: { isSubmitting, setIsSubmitting }, } = useMobxStore(); const { currentProjectRole } = userStore; - const isAllowed = [15, 20].includes(currentProjectRole || 0); + const isAllowed = !!currentProjectRole && currentProjectRole >= EUserWorkspaceRoles.MEMBER; // states const [characterLimit, setCharacterLimit] = useState(false); diff --git a/web/components/issues/issue-peek-overview/root.tsx b/web/components/issues/issue-peek-overview/root.tsx index 5e2e0e3cc..09a5202b5 100644 --- a/web/components/issues/issue-peek-overview/root.tsx +++ b/web/components/issues/issue-peek-overview/root.tsx @@ -12,6 +12,7 @@ import { IssueView } from "./view"; import { copyUrlToClipboard } from "helpers/string.helper"; // types import { IIssue } from "types"; +import { EUserWorkspaceRoles } from "constants/workspace"; interface IIssuePeekOverview { workspaceSlug: string; @@ -118,7 +119,7 @@ export const IssuePeekOverview: FC = observer((props) => { } }; - const userRole = userStore.currentProjectRole ?? 5; + const userRole = userStore.currentProjectRole ?? EUserWorkspaceRoles.GUEST; return ( diff --git a/web/components/issues/main-content.tsx b/web/components/issues/main-content.tsx index 50cabf882..35ebccb51 100644 --- a/web/components/issues/main-content.tsx +++ b/web/components/issues/main-content.tsx @@ -28,6 +28,7 @@ import { MinusCircle, RefreshCw } from "lucide-react"; import { IIssue, IIssueComment } from "types"; // fetch-keys import { PROJECT_ISSUES_ACTIVITY, SUB_ISSUES } from "constants/fetch-keys"; +import { EUserWorkspaceRoles } from "constants/workspace"; type Props = { issueDetails: IIssue; @@ -123,6 +124,8 @@ export const IssueMainContent: React.FC = observer((props) => { } }, [isSubmitting, setShowAlert]); + const isAllowed = !!userRole && userRole >= EUserWorkspaceRoles.MEMBER; + return ( <>
@@ -215,7 +218,7 @@ export const IssueMainContent: React.FC = observer((props) => { workspaceSlug={workspaceSlug as string} issue={issueDetails} handleFormSubmit={submitChanges} - isAllowed={userRole === 20 || userRole === 15 || !uneditable} + isAllowed={isAllowed || !uneditable} /> diff --git a/web/components/issues/sidebar.tsx b/web/components/issues/sidebar.tsx index a1a78c7dd..6aaaf1dc2 100644 --- a/web/components/issues/sidebar.tsx +++ b/web/components/issues/sidebar.tsx @@ -40,6 +40,7 @@ import { copyTextToClipboard } from "helpers/string.helper"; import type { IIssue, IIssueLink, linkDetails } from "types"; // fetch-keys import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; +import { EUserWorkspaceRoles } from "constants/workspace"; type Props = { control: any; @@ -248,7 +249,7 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { setLinkModal(true); }; - const isNotAllowed = userRole === 5 || userRole === 10; + const isAllowed = !!userRole && userRole >= EUserWorkspaceRoles.MEMBER; const currentIssueState = projectId ? states[projectId.toString()]?.find((s) => s.id === issueDetail?.state) @@ -314,7 +315,7 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { )} - {!isNotAllowed && (fieldsToShow.includes("all") || fieldsToShow.includes("delete")) && ( + {isAllowed && (fieldsToShow.includes("all") || fieldsToShow.includes("delete")) && (
@@ -605,7 +606,7 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { @@ -624,7 +625,7 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { issueDetails={issueDetail} labelList={issueDetail?.labels ?? []} submitChanges={submitChanges} - isNotAllowed={isNotAllowed} + isNotAllowed={!isAllowed} uneditable={uneditable ?? false} /> @@ -634,7 +635,7 @@ export const IssueDetailsSidebar: React.FC = observer((props) => {

Links

- {!isNotAllowed && ( + {isAllowed && (