fix: incomplete cycle issues auth (#4299)

This commit is contained in:
Aaryan Khandelwal 2024-04-29 00:50:15 +05:30 committed by GitHub
parent 6ac3cb9b31
commit 0e3d5cc4eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 87 additions and 33 deletions

View File

@ -416,7 +416,7 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
to: "End date",
}}
required={cycleDetails.status !== "draft"}
disabled={isArchived}
disabled={!isEditingAllowed || isArchived}
/>
)}
/>

View File

@ -1,10 +1,12 @@
import { observer } from "mobx-react-lite";
import { PlusIcon } from "lucide-react";
// hooks
import { EmptyState } from "@/components/common";
import { EIssuesStoreType } from "@/constants/issue";
import { useApplication, useEventTracker } from "@/hooks/store";
// components
import { EmptyState } from "@/components/common";
// constants
import { EIssuesStoreType } from "@/constants/issue";
import { EUserProjectRoles } from "@/constants/project";
// hooks
import { useApplication, useEventTracker, useUser } from "@/hooks/store";
// assets
import emptyIssue from "public/empty-state/issue.svg";
@ -12,6 +14,11 @@ export const ProjectViewEmptyState: React.FC = observer(() => {
// store hooks
const { commandPalette: commandPaletteStore } = useApplication();
const { setTrackElement } = useEventTracker();
const {
membership: { currentProjectRole },
} = useUser();
// auth
const isCreatingIssueAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;
return (
<div className="grid h-full w-full place-items-center">
@ -19,14 +26,18 @@ export const ProjectViewEmptyState: React.FC = observer(() => {
title="View issues will appear here"
description="Issues help you track individual pieces of work. With Issues, keep track of what's going on, who is working on it, and what's done."
image={emptyIssue}
primaryButton={{
text: "New issue",
icon: <PlusIcon className="h-3 w-3" strokeWidth={2} />,
onClick: () => {
setTrackElement("View issue empty state");
commandPaletteStore.toggleCreateIssueModal(true, EIssuesStoreType.PROJECT_VIEW);
},
}}
primaryButton={
isCreatingIssueAllowed
? {
text: "New issue",
icon: <PlusIcon className="h-3 w-3" strokeWidth={2} />,
onClick: () => {
setTrackElement("View issue empty state");
commandPaletteStore.toggleCreateIssueModal(true, EIssuesStoreType.PROJECT_VIEW);
},
}
: undefined
}
/>
</div>
);

View File

@ -1,12 +1,13 @@
import React, { useCallback } from "react";
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
// hooks
// components
import { CycleIssueQuickActions } from "@/components/issues";
// constants
import { EIssuesStoreType } from "@/constants/issue";
import { useCycle, useIssues } from "@/hooks/store";
// ui
// types
import { EUserProjectRoles } from "@/constants/project";
// hooks
import { useCycle, useIssues, useUser } from "@/hooks/store";
// components
import { BaseKanBanRoot } from "../base-kanban-root";
@ -19,11 +20,18 @@ export const CycleKanBanLayout: React.FC = observer(() => {
// store
const { issues } = useIssues(EIssuesStoreType.CYCLE);
const { currentProjectCompletedCycleIds } = useCycle();
const {
membership: { currentProjectRole },
} = useUser();
const isCompletedCycle =
cycleId && currentProjectCompletedCycleIds ? currentProjectCompletedCycleIds.includes(cycleId.toString()) : false;
const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;
const canEditIssueProperties = useCallback(() => !isCompletedCycle, [isCompletedCycle]);
const canEditIssueProperties = useCallback(
() => !isCompletedCycle && isEditingAllowed,
[isCompletedCycle, isEditingAllowed]
);
const addIssuesToView = useCallback(
(issueIds: string[]) => {

View File

@ -1,13 +1,14 @@
import React, { useCallback } from "react";
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
// hooks
import { CycleIssueQuickActions } from "@/components/issues";
import { EIssuesStoreType } from "@/constants/issue";
import { useCycle, useIssues } from "@/hooks/store";
// components
// types
import { CycleIssueQuickActions } from "@/components/issues";
// constants
import { EIssuesStoreType } from "@/constants/issue";
import { EUserProjectRoles } from "@/constants/project";
// hooks
import { useCycle, useIssues, useUser } from "@/hooks/store";
// types
import { BaseListRoot } from "../base-list-root";
export interface ICycleListLayout {}
@ -17,12 +18,19 @@ export const CycleListLayout: React.FC = observer(() => {
const { workspaceSlug, projectId, cycleId } = router.query;
// store
const { issues } = useIssues(EIssuesStoreType.CYCLE);
const { currentProjectCompletedCycleIds } = useCycle();
const { currentProjectCompletedCycleIds } = useCycle(); // mobx store
const {
membership: { currentProjectRole },
} = useUser();
const isCompletedCycle =
cycleId && currentProjectCompletedCycleIds ? currentProjectCompletedCycleIds.includes(cycleId.toString()) : false;
const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;
const canEditIssueProperties = useCallback(() => !isCompletedCycle, [isCompletedCycle]);
const canEditIssueProperties = useCallback(
() => !isCompletedCycle && isEditingAllowed,
[isCompletedCycle, isEditingAllowed]
);
const addIssuesToView = useCallback(
(issueIds: string[]) => {

View File

@ -1,22 +1,33 @@
import React, { useCallback } from "react";
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
// mobx store
// constants
import { EIssuesStoreType } from "@/constants/issue";
import { useCycle } from "@/hooks/store";
import { EUserProjectRoles } from "@/constants/project";
// hooks
import { useCycle, useUser } from "@/hooks/store";
// components
import { CycleIssueQuickActions } from "../../quick-action-dropdowns";
import { BaseSpreadsheetRoot } from "../base-spreadsheet-root";
export const CycleSpreadsheetLayout: React.FC = observer(() => {
// router
const router = useRouter();
const { cycleId } = router.query;
// store hooks
const { currentProjectCompletedCycleIds } = useCycle();
const {
membership: { currentProjectRole },
} = useUser();
// auth
const isCompletedCycle =
cycleId && currentProjectCompletedCycleIds ? currentProjectCompletedCycleIds.includes(cycleId.toString()) : false;
const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;
const canEditIssueProperties = useCallback(() => !isCompletedCycle, [isCompletedCycle]);
const canEditIssueProperties = useCallback(
() => !isCompletedCycle && isEditingAllowed,
[isCompletedCycle, isEditingAllowed]
);
if (!cycleId) return null;

View File

@ -480,7 +480,7 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
from: "Start date",
to: "Target date",
}}
disabled={isArchived}
disabled={!isEditingAllowed || isArchived}
/>
);
}}
@ -510,7 +510,7 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
multiple={false}
buttonVariant="background-with-text"
placeholder="Lead"
disabled={isArchived}
disabled={!isEditingAllowed || isArchived}
/>
</div>
)}

View File

@ -4,10 +4,13 @@ import { ArchiveRestoreIcon, Clipboard, Copy, Link, Lock, LockOpen } from "lucid
import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/document-editor";
// ui
import { ArchiveIcon, CustomMenu, TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui";
// constants
import { EUserProjectRoles } from "@/constants/project";
// helpers
import { cn } from "@/helpers/common.helper";
import { copyTextToClipboard, copyUrlToClipboard } from "@/helpers/string.helper";
// hooks
import { useApplication } from "@/hooks/store";
import { useApplication, useUser } from "@/hooks/store";
// store
import { IPageStore } from "@/store/pages/page.store";
@ -38,6 +41,11 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
const {
router: { workspaceSlug, projectId },
} = useApplication();
const {
membership: { currentProjectRole },
} = useUser();
// auth
const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;
const handleArchivePage = async () =>
await archive().catch(() =>
@ -146,9 +154,17 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
full_width: !view_props?.full_width,
})
}
disabled={!isEditingAllowed}
>
Full width
<ToggleSwitch value={!!view_props?.full_width} onChange={() => {}} />
<ToggleSwitch
value={!!view_props?.full_width}
onChange={() => {}}
className={cn({
"opacity-40": !isEditingAllowed,
})}
disabled={!isEditingAllowed}
/>
</CustomMenu.MenuItem>
{MENU_ITEMS.map((item) => {
if (!item.shouldRender) return null;