Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WEB-1076] fix: authorization bugs across the platform #4299

Merged
merged 2 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion web/components/cycles/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
to: "End date",
}}
required={cycleDetails.status !== "draft"}
disabled={isArchived}
disabled={!isEditingAllowed || isArchived}
/>
)}
/>
Expand Down
33 changes: 22 additions & 11 deletions web/components/issues/issue-layouts/empty-states/project-view.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,43 @@
import { observer } from "mobx-react-lite";
import { PlusIcon } from "lucide-react";
// hooks
// components
import { EmptyState } from "@/components/common";
// constants
import { EIssuesStoreType } from "@/constants/issue";
import { useApplication, useEventTracker } from "@/hooks/store";
// components
import { EUserProjectRoles } from "@/constants/project";
// hooks
import { useApplication, useEventTracker, useUser } from "@/hooks/store";
// assets
import emptyIssue from "public/empty-state/issue.svg";

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">
<EmptyState
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>
);
Expand Down
18 changes: 13 additions & 5 deletions web/components/issues/issue-layouts/kanban/roots/cycle-root.tsx
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -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[]) => {
Expand Down
20 changes: 14 additions & 6 deletions web/components/issues/issue-layouts/list/roots/cycle-root.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
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";
// components
import { EUserProjectRoles } from "@/constants/project";
// hooks
import { useCycle, useIssues, useUser } from "@/hooks/store";
// types
// constants
import { BaseListRoot } from "../base-list-root";

export interface ICycleListLayout {}
Expand All @@ -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[]) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
4 changes: 2 additions & 2 deletions web/components/modules/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
from: "Start date",
to: "Target date",
}}
disabled={isArchived}
disabled={!isEditingAllowed || isArchived}
/>
);
}}
Expand Down Expand Up @@ -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>
)}
Expand Down
20 changes: 18 additions & 2 deletions web/components/pages/editor/header/options-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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(() =>
Expand Down Expand Up @@ -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;
Expand Down
Loading