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
154 lines
5.4 KiB
TypeScript
154 lines
5.4 KiB
TypeScript
/**
|
|
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
* See the LICENSE file for details.
|
|
*/
|
|
|
|
// @types/react 19 removed the global JSX namespace; it is imported from react now.
|
|
import type { JSX } from "react";
|
|
// types
|
|
import type { ICycle, IModule, IProjectView, IWorkspaceView } from "@plane/types";
|
|
import type { TContextMenuItem } from "@plane/ui";
|
|
// hooks
|
|
import { useQuickActionsFactory } from "@/components/common/quick-actions-factory";
|
|
|
|
// Types
|
|
interface UseCycleMenuItemsProps {
|
|
cycleDetails: ICycle | undefined;
|
|
isEditingAllowed: boolean;
|
|
workspaceSlug: string;
|
|
projectId: string;
|
|
cycleId: string;
|
|
handleEdit: () => void;
|
|
handleArchive: () => void;
|
|
handleRestore: () => void;
|
|
handleDelete: () => void;
|
|
handleCopyLink: () => void;
|
|
handleOpenInNewTab: () => void;
|
|
}
|
|
|
|
interface UseModuleMenuItemsProps {
|
|
moduleDetails: IModule | undefined;
|
|
isEditingAllowed: boolean;
|
|
workspaceSlug: string;
|
|
projectId: string;
|
|
moduleId: string;
|
|
handleEdit: () => void;
|
|
handleArchive: () => void;
|
|
handleRestore: () => void;
|
|
handleDelete: () => void;
|
|
handleCopyLink: () => void;
|
|
handleOpenInNewTab: () => void;
|
|
}
|
|
|
|
interface UseViewMenuItemsProps {
|
|
isOwner: boolean;
|
|
isAdmin: boolean;
|
|
workspaceSlug: string;
|
|
projectId?: string;
|
|
view: IProjectView | IWorkspaceView;
|
|
handleEdit: () => void;
|
|
handleDelete: () => void;
|
|
handleCopyLink: () => void;
|
|
handleOpenInNewTab: () => void;
|
|
}
|
|
|
|
interface UseLayoutMenuItemsProps {
|
|
workspaceSlug: string;
|
|
projectId: string;
|
|
storeType: "PROJECT" | "EPIC";
|
|
handleCopyLink: () => void;
|
|
handleOpenInNewTab: () => void;
|
|
}
|
|
|
|
type MenuResult = {
|
|
items: TContextMenuItem[];
|
|
modals: JSX.Element | null;
|
|
};
|
|
|
|
export const useCycleMenuItems = (props: UseCycleMenuItemsProps): MenuResult => {
|
|
const factory = useQuickActionsFactory();
|
|
const { cycleDetails, isEditingAllowed, ...handlers } = props;
|
|
|
|
const isArchived = !!cycleDetails?.archived_at;
|
|
const isCompleted = cycleDetails?.status?.toLowerCase() === "completed";
|
|
|
|
// Assemble final menu items - order defined here
|
|
const items = [
|
|
factory.createEditMenuItem(handlers.handleEdit, isEditingAllowed && !isCompleted && !isArchived),
|
|
factory.createOpenInNewTabMenuItem(handlers.handleOpenInNewTab),
|
|
factory.createCopyLinkMenuItem(handlers.handleCopyLink),
|
|
factory.createArchiveMenuItem(handlers.handleArchive, {
|
|
shouldRender: isEditingAllowed && !isArchived,
|
|
disabled: !isCompleted,
|
|
description: isCompleted ? undefined : "Only completed cycles can be archived",
|
|
}),
|
|
factory.createRestoreMenuItem(handlers.handleRestore, isEditingAllowed && isArchived),
|
|
factory.createDeleteMenuItem(handlers.handleDelete, isEditingAllowed && !isCompleted && !isArchived),
|
|
].filter((item) => item.shouldRender !== false);
|
|
|
|
return { items, modals: null };
|
|
};
|
|
|
|
export const useModuleMenuItems = (props: UseModuleMenuItemsProps): MenuResult => {
|
|
const factory = useQuickActionsFactory();
|
|
const { moduleDetails, isEditingAllowed, ...handlers } = props;
|
|
|
|
const isArchived = !!moduleDetails?.archived_at;
|
|
const moduleState = moduleDetails?.status?.toLocaleLowerCase();
|
|
const isInArchivableGroup = !!moduleState && ["completed", "cancelled"].includes(moduleState);
|
|
|
|
// Assemble final menu items - order defined here
|
|
const items = [
|
|
factory.createEditMenuItem(handlers.handleEdit, isEditingAllowed && !isArchived),
|
|
factory.createOpenInNewTabMenuItem(handlers.handleOpenInNewTab),
|
|
factory.createCopyLinkMenuItem(handlers.handleCopyLink),
|
|
factory.createArchiveMenuItem(handlers.handleArchive, {
|
|
shouldRender: isEditingAllowed && !isArchived,
|
|
disabled: !isInArchivableGroup,
|
|
description: isInArchivableGroup ? undefined : "Only completed or cancelled modules can be archived",
|
|
}),
|
|
factory.createRestoreMenuItem(handlers.handleRestore, isEditingAllowed && isArchived),
|
|
factory.createDeleteMenuItem(handlers.handleDelete, isEditingAllowed && !isArchived),
|
|
].filter((item) => item.shouldRender !== false);
|
|
|
|
return { items, modals: null };
|
|
};
|
|
|
|
export const useViewMenuItems = (props: UseViewMenuItemsProps): MenuResult => {
|
|
const factory = useQuickActionsFactory();
|
|
const { workspaceSlug, isOwner, isAdmin, projectId, view, ...handlers } = props;
|
|
|
|
if (!view) return { items: [], modals: null };
|
|
|
|
// Assemble final menu items - order defined here
|
|
const items = [
|
|
factory.createEditMenuItem(handlers.handleEdit, isOwner),
|
|
factory.createOpenInNewTabMenuItem(handlers.handleOpenInNewTab),
|
|
factory.createCopyLinkMenuItem(handlers.handleCopyLink),
|
|
factory.createDeleteMenuItem(handlers.handleDelete, isOwner || isAdmin),
|
|
].filter((item) => item.shouldRender !== false);
|
|
|
|
return { items, modals: null };
|
|
};
|
|
|
|
export const useLayoutMenuItems = (props: UseLayoutMenuItemsProps): MenuResult => {
|
|
const factory = useQuickActionsFactory();
|
|
const { ...handlers } = props;
|
|
|
|
// Assemble final menu items - order defined here
|
|
const items = [
|
|
factory.createOpenInNewTab(handlers.handleOpenInNewTab),
|
|
factory.createCopyLayoutLinkMenuItem(handlers.handleCopyLink),
|
|
].filter((item) => item.shouldRender !== false);
|
|
|
|
return { items, modals: null };
|
|
};
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
export const useIntakeHeaderMenuItems = (props: {
|
|
workspaceSlug: string;
|
|
projectId: string;
|
|
handleCopyLink: () => void;
|
|
}): MenuResult => ({ items: [], modals: null });
|