[WEB-3146] | [WEB-3147] chore: project overview permission (#2207)

* chore: project overview description edit permission updated

* chore: project overview update validation updated
This commit is contained in:
Anmol Singh Bhatia
2025-01-16 14:12:59 +05:30
committed by GitHub
parent b5fa81465d
commit f3325a99eb
5 changed files with 51 additions and 32 deletions

View File

@@ -2,9 +2,11 @@
import React, { FC } from "react";
import { observer } from "mobx-react";
import { EUserPermissionsLevel } from "@plane/constants";
// hooks
import { useProject } from "@/hooks/store";
import { useProject, useUserPermissions } from "@/hooks/store";
// types
import { EUserPermissions } from "@/plane-web/constants";
import { TProject } from "@/plane-web/types";
// local components
import { useLinks } from "./collaspible-section/links/use-links";
@@ -20,6 +22,7 @@ export const ProjectOverviewInfoSectionRoot: FC<Props> = observer((props) => {
const { workspaceSlug, projectId } = props;
// store hooks
const { getProjectById, updateProject } = useProject();
const { allowPermissions } = useUserPermissions();
// helper hooks
const { toggleLinkModal } = useLinks(workspaceSlug.toString(), projectId.toString());
@@ -31,6 +34,13 @@ export const ProjectOverviewInfoSectionRoot: FC<Props> = observer((props) => {
const handleUpdateProject = async (data: Partial<TProject>) => {
await updateProject(workspaceSlug.toString(), projectId.toString(), data);
};
const isProjectAdmin = allowPermissions(
[EUserPermissions.ADMIN],
EUserPermissionsLevel.PROJECT,
workspaceSlug.toString(),
project.id.toString()
);
return (
<>
<HeroSection project={project} workspaceSlug={workspaceSlug.toString()} />
@@ -39,6 +49,7 @@ export const ProjectOverviewInfoSectionRoot: FC<Props> = observer((props) => {
project={project}
handleProjectUpdate={handleUpdateProject}
toggleLinkModalOpen={toggleLinkModal}
disabled={!isProjectAdmin}
/>
</>
);

View File

@@ -10,9 +10,10 @@ type TProps = {
project: TProject;
handleProjectUpdate: (data: Partial<TProject>) => Promise<void>;
toggleLinkModalOpen: (value: boolean) => void;
disabled?: boolean;
};
export const DescriptionBox = (props: TProps) => {
const { workspaceSlug, project, handleProjectUpdate, toggleLinkModalOpen } = props;
const { workspaceSlug, project, handleProjectUpdate, toggleLinkModalOpen, disabled = false } = props;
const [isSubmitting, setIsSubmitting] = useState<"submitting" | "submitted" | "saved">("saved");
// hooks
@@ -27,6 +28,7 @@ export const DescriptionBox = (props: TProps) => {
handleUpdate={handleProjectUpdate}
setIsSubmitting={setIsSubmitting}
containerClassName="px-0 text-base min-h-[200px] w-full"
disabled={disabled}
/>
<div className="flex items-center justify-between w-full gap-2 pb-6 border-b border-custom-border-200">
<ProjectReaction workspaceSlug={workspaceSlug} projectId={project.id} currentUser={currentUser} />

View File

@@ -136,7 +136,7 @@ export const ProjectDescriptionInput: FC<ProjectDescriptionInputProps> = observe
) : (
<RichTextReadOnlyEditor
id={project.id}
initialValue={""}
initialValue={initialValue ?? ""}
containerClassName={containerClassName}
workspaceSlug={workspaceSlug}
projectId={project.id}

View File

@@ -1,10 +1,12 @@
import React, { useState } from "react";
import { observer } from "mobx-react";
import { MessageCircle, Rocket } from "lucide-react";
import { EUserPermissionsLevel } from "@plane/constants";
import { AtRiskIcon, OffTrackIcon, OnTrackIcon } from "@plane/ui";
import { cn } from "@plane/utils";
import { renderFormattedDate } from "@/helpers/date-time.helper";
import { useMember, useUser } from "@/hooks/store";
import { useMember, useUser, useUserPermissions } from "@/hooks/store";
import { EUserPermissions } from "@/plane-web/constants";
import { useProjectUpdates } from "@/plane-web/hooks/store/projects/use-project-updates";
import { EProjectUpdateStatus, TProjectUpdate } from "@/plane-web/types";
import { CommentList } from "./comments/comment-list";
@@ -49,6 +51,7 @@ export const UpdateBlock = observer((props: TProps) => {
const { getUserDetails } = useMember();
const { data: currentUser } = useUser();
const { getUpdateById } = useProjectUpdates();
const { allowPermissions } = useUserPermissions();
const updateData = getUpdateById(updateId);
@@ -56,6 +59,13 @@ export const UpdateBlock = observer((props: TProps) => {
const icon = conf[updateData?.status].icon;
const isProjectAdmin = allowPermissions(
[EUserPermissions.ADMIN],
EUserPermissionsLevel.PROJECT,
workspaceSlug.toString(),
projectId.toString()
);
return isEditing ? (
<NewUpdate
initialValues={updateData}
@@ -87,16 +97,17 @@ export const UpdateBlock = observer((props: TProps) => {
</div>
</div>
{/* quick actions */}
<UpdateQuickActions
isCreator={updateData.created_by === currentUser?.id}
updateId={updateData.id}
operations={{
remove: handleUpdateOperations.remove,
update: () => {
setIsEditing(true);
},
}}
/>
{isProjectAdmin && (
<UpdateQuickActions
updateId={updateData.id}
operations={{
remove: handleUpdateOperations.remove,
update: () => {
setIsEditing(true);
},
}}
/>
)}
</div>
{/* Update */}

View File

@@ -5,7 +5,6 @@ import { cn } from "@plane/utils";
import { ProjectUpdateDeleteModal } from "./delete-update-modal";
type TProps = {
isCreator: boolean;
updateId: string;
operations: {
update: () => void;
@@ -13,7 +12,7 @@ type TProps = {
};
};
export const UpdateQuickActions = (props: TProps) => {
const { isCreator, operations, updateId } = props;
const { operations, updateId } = props;
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [isMenuActive, setIsMenuActive] = useState(false);
const actionSectionRef = useRef(null);
@@ -41,23 +40,19 @@ export const UpdateQuickActions = (props: TProps) => {
customButtonClassName="grid place-items-center"
placement="bottom-start"
>
{isCreator && (
<CustomMenu.MenuItem onClick={() => operations.update()}>
<button className="flex items-center justify-start gap-2">
<Pencil className="h-3.5 w-3.5 stroke-[1.5]" />
<span>Edit</span>
</button>
</CustomMenu.MenuItem>
)}
<CustomMenu.MenuItem onClick={() => operations.update()}>
<button className="flex items-center justify-start gap-2">
<Pencil className="h-3.5 w-3.5 stroke-[1.5]" />
<span>Edit</span>
</button>
</CustomMenu.MenuItem>
{isCreator && (
<CustomMenu.MenuItem onClick={() => setIsDeleteModalOpen(true)}>
<button className="flex items-center justify-start gap-2">
<Trash2 className="h-3.5 w-3.5 stroke-[1.5]" />
<span>Delete</span>
</button>
</CustomMenu.MenuItem>
)}
<CustomMenu.MenuItem onClick={() => setIsDeleteModalOpen(true)}>
<button className="flex items-center justify-start gap-2">
<Trash2 className="h-3.5 w-3.5 stroke-[1.5]" />
<span>Delete</span>
</button>
</CustomMenu.MenuItem>
</CustomMenu>
</>
);