Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 16s
CodeQL / Analyze (python) (push) Failing after 3s
i18n sync check / check:sync (push) Failing after 3s
React Doctor / react-doctor (push) Failing after 16s
Branch Build CE / Build-Push Admin Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Admin Manifest (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Web Manifest (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Proxy Manifest (push) Has been cancelled
Branch Build CE / Merge Space Manifest (push) Has been cancelled
Branch Build CE / Prepare AIO Assets (push) Has been cancelled
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Live Collaboration Manifest (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge API Server Manifest (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge AIO Manifest (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
121 lines
3.7 KiB
TypeScript
121 lines
3.7 KiB
TypeScript
/**
|
|
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
* See the LICENSE file for details.
|
|
*/
|
|
|
|
import { useState, useRef } from "react";
|
|
import { useNavigate } from "react-router";
|
|
import {
|
|
ArchiveOutline,
|
|
LinkOutline,
|
|
LogOutOutline,
|
|
MoreHorizontalOutline,
|
|
SettingsOutline,
|
|
ShareAltOutline,
|
|
} from "@makeplane/propel/icons";
|
|
// plane imports
|
|
import { useTranslation } from "@plane/i18n";
|
|
import { CustomMenu } from "@plane/ui";
|
|
|
|
type Props = {
|
|
workspaceSlug: string;
|
|
project: {
|
|
id: string;
|
|
};
|
|
isAdmin: boolean;
|
|
isAuthorized: boolean;
|
|
onCopyText: () => void;
|
|
onLeaveProject: () => void;
|
|
onPublishModal: () => void;
|
|
};
|
|
|
|
export function ProjectActionsMenu({
|
|
workspaceSlug,
|
|
project,
|
|
isAdmin,
|
|
isAuthorized,
|
|
onCopyText,
|
|
onLeaveProject,
|
|
onPublishModal,
|
|
}: Props) {
|
|
// states
|
|
const [isMenuActive, setIsMenuActive] = useState(false);
|
|
// translation
|
|
const { t } = useTranslation();
|
|
// refs
|
|
const actionSectionRef = useRef<HTMLDivElement | null>(null);
|
|
// router
|
|
const navigate = useNavigate();
|
|
|
|
return (
|
|
<CustomMenu
|
|
customButton={
|
|
<span
|
|
ref={actionSectionRef}
|
|
className="grid place-items-center rounded-sm p-0.5 text-placeholder hover:bg-layer-1"
|
|
onClick={() => setIsMenuActive(!isMenuActive)}
|
|
>
|
|
<MoreHorizontalOutline className="size-4" />
|
|
</span>
|
|
}
|
|
className="flex-shrink-0"
|
|
customButtonClassName="grid place-items-center"
|
|
placement="bottom-start"
|
|
ariaLabel={t("aria_labels.projects_sidebar.toggle_quick_actions_menu")}
|
|
useCaptureForOutsideClick
|
|
closeOnSelect
|
|
onMenuClose={() => setIsMenuActive(false)}
|
|
>
|
|
{/* Publish project settings */}
|
|
{isAdmin && (
|
|
<CustomMenu.MenuItem onClick={onPublishModal}>
|
|
<div className="relative flex flex-shrink-0 items-center justify-start gap-2">
|
|
<div className="flex h-4 w-4 cursor-pointer items-center justify-center rounded-sm text-secondary transition-all duration-300 hover:bg-layer-1">
|
|
<ShareAltOutline className="h-3.5 w-3.5 stroke-[1.5]" />
|
|
</div>
|
|
<div>{t("publish_project")}</div>
|
|
</div>
|
|
</CustomMenu.MenuItem>
|
|
)}
|
|
<CustomMenu.MenuItem onClick={onCopyText}>
|
|
<span className="flex items-center justify-start gap-2">
|
|
<LinkOutline className="h-3.5 w-3.5 stroke-[1.5]" />
|
|
<span>{t("copy_link")}</span>
|
|
</span>
|
|
</CustomMenu.MenuItem>
|
|
{isAuthorized && (
|
|
<CustomMenu.MenuItem
|
|
onClick={() => {
|
|
navigate(`/${workspaceSlug}/projects/${project?.id}/archives/issues`);
|
|
}}
|
|
>
|
|
<div className="flex cursor-pointer items-center justify-start gap-2">
|
|
<ArchiveOutline className="h-3.5 w-3.5 stroke-[1.5]" />
|
|
<span>{t("archives")}</span>
|
|
</div>
|
|
</CustomMenu.MenuItem>
|
|
)}
|
|
<CustomMenu.MenuItem
|
|
onClick={() => {
|
|
navigate(`/${workspaceSlug}/settings/projects/${project?.id}`);
|
|
}}
|
|
>
|
|
<div className="flex cursor-pointer items-center justify-start gap-2">
|
|
<SettingsOutline className="h-3.5 w-3.5 stroke-[1.5]" />
|
|
<span>{t("settings")}</span>
|
|
</div>
|
|
</CustomMenu.MenuItem>
|
|
{/* Leave project */}
|
|
{!isAuthorized && (
|
|
<CustomMenu.MenuItem onClick={onLeaveProject}>
|
|
<div className="flex items-center justify-start gap-2">
|
|
<LogOutOutline className="h-3.5 w-3.5 stroke-[1.5]" />
|
|
<span>{t("leave_project")}</span>
|
|
</div>
|
|
</CustomMenu.MenuItem>
|
|
)}
|
|
</CustomMenu>
|
|
);
|
|
}
|