[WEB-2443] fix: role validation and code refactor (#5596)

* chore: delete cycle toast message updated

* fix: view page empty state

* fix: project settings automation

* fix: intake delete action

* fix: project label validation

* fix: project label validation

* fix: project state permission updated

* chore: code refactor
This commit is contained in:
Anmol Singh Bhatia 2024-09-12 20:08:13 +05:30 committed by GitHub
parent 5f1939cdeb
commit 441385fc95
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 134 additions and 77 deletions

View file

@ -28,10 +28,19 @@ interface ILabelItemBlock {
handleLabelDelete: (label: IIssueLabel) => void;
isLabelGroup?: boolean;
dragHandleRef: MutableRefObject<HTMLButtonElement | null>;
disabled?: boolean;
}
export const LabelItemBlock = (props: ILabelItemBlock) => {
const { label, isDragging, customMenuItems, handleLabelDelete, isLabelGroup, dragHandleRef } = props;
const {
label,
isDragging,
customMenuItems,
handleLabelDelete,
isLabelGroup,
dragHandleRef,
disabled = false,
} = props;
// states
const [isMenuActive, setIsMenuActive] = useState(false);
// refs
@ -42,44 +51,51 @@ export const LabelItemBlock = (props: ILabelItemBlock) => {
return (
<div className="group flex items-center">
<div className="flex items-center">
<DragHandle
className={cn("opacity-0 group-hover:opacity-100", {
"opacity-100": isDragging,
})}
ref={dragHandleRef}
/>
{!disabled && (
<DragHandle
className={cn("opacity-0 group-hover:opacity-100", {
"opacity-100": isDragging,
})}
ref={dragHandleRef}
/>
)}
<LabelName color={label.color} name={label.name} isGroup={isLabelGroup ?? false} />
</div>
<div
ref={actionSectionRef}
className={`absolute right-2.5 flex items-start gap-3.5 px-4 ${
isMenuActive || isLabelGroup
? "opacity-100"
: "opacity-0 group-hover:pointer-events-auto group-hover:opacity-100"
} ${isLabelGroup && "-top-0.5"}`}
>
<CustomMenu ellipsis menuButtonOnClick={() => setIsMenuActive(!isMenuActive)} useCaptureForOutsideClick>
{customMenuItems.map(
({ isVisible, onClick, CustomIcon, text, key }) =>
isVisible && (
<CustomMenu.MenuItem key={key} onClick={() => onClick(label)}>
<span className="flex items-center justify-start gap-2">
<CustomIcon className="h-4 w-4" />
<span>{text}</span>
</span>
</CustomMenu.MenuItem>
)
{!disabled && (
<div
ref={actionSectionRef}
className={`absolute right-2.5 flex items-start gap-3.5 px-4 ${
isMenuActive || isLabelGroup
? "opacity-100"
: "opacity-0 group-hover:pointer-events-auto group-hover:opacity-100"
} ${isLabelGroup && "-top-0.5"}`}
>
<CustomMenu ellipsis menuButtonOnClick={() => setIsMenuActive(!isMenuActive)} useCaptureForOutsideClick>
{customMenuItems.map(
({ isVisible, onClick, CustomIcon, text, key }) =>
isVisible && (
<CustomMenu.MenuItem key={key} onClick={() => onClick(label)}>
<span className="flex items-center justify-start gap-2">
<CustomIcon className="h-4 w-4" />
<span>{text}</span>
</span>
</CustomMenu.MenuItem>
)
)}
</CustomMenu>
{!isLabelGroup && (
<div className="py-0.5">
<button
className="flex h-4 w-4 items-center justify-start gap-2"
onClick={() => handleLabelDelete(label)}
>
<X className="h-4 w-4 flex-shrink-0 text-custom-sidebar-text-400" />
</button>
</div>
)}
</CustomMenu>
{!isLabelGroup && (
<div className="py-0.5">
<button className="flex h-4 w-4 items-center justify-start gap-2" onClick={() => handleLabelDelete(label)}>
<X className="h-4 w-4 flex-shrink-0 text-custom-sidebar-text-400" />
</button>
</div>
)}
</div>
</div>
)}
</div>
);
};

View file

@ -23,10 +23,20 @@ type Props = {
droppedLabelId: string | undefined,
dropAtEndOfList: boolean
) => void;
isEditable?: boolean;
};
export const ProjectSettingLabelItem: React.FC<Props> = (props) => {
const { label, setIsUpdating, handleLabelDelete, isChild, isLastChild, isParentDragging = false, onDrop } = props;
const {
label,
setIsUpdating,
handleLabelDelete,
isChild,
isLastChild,
isParentDragging = false,
onDrop,
isEditable = false,
} = props;
// states
const [isEditLabelForm, setEditLabelForm] = useState(false);
// router
@ -91,6 +101,7 @@ export const ProjectSettingLabelItem: React.FC<Props> = (props) => {
customMenuItems={customMenuItems}
handleLabelDelete={handleLabelDelete}
dragHandleRef={dragHandleRef}
disabled={!isEditable}
/>
)}
</div>

View file

@ -14,7 +14,8 @@ import {
ProjectSettingLabelItem,
} from "@/components/labels";
import { EmptyStateType } from "@/constants/empty-state";
import { useLabel } from "@/hooks/store";
import { useLabel, useUserPermissions } from "@/hooks/store";
import { EUserPermissions, EUserPermissionsLevel } from "@/plane-web/constants/user-permissions";
// components
// ui
// types
@ -31,6 +32,10 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
const { workspaceSlug, projectId } = useParams();
// store hooks
const { projectLabels, updateLabelPosition, projectLabelsTree } = useLabel();
const { allowPermissions } = useUserPermissions();
// derived values
const isEditable = allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.PROJECT);
const newLabel = () => {
setIsUpdating(false);
@ -65,9 +70,11 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
/>
<div className="flex items-center justify-between border-b border-custom-border-100 pb-3.5">
<h3 className="text-xl font-medium">Labels</h3>
<Button variant="primary" onClick={newLabel} size="sm">
Add label
</Button>
{isEditable && (
<Button variant="primary" onClick={newLabel} size="sm">
Add label
</Button>
)}
</div>
<div className="w-full py-2">
{showLabelForm && (