UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: миграция desktop header action-menu на ActionDropdown
This commit is contained in:
parent
082948a69c
commit
e880daf588
|
|
@ -15,7 +15,8 @@ import { PlusIcon } from "@plane/propel/icons";
|
||||||
import { setPromiseToast } from "@plane/propel/toast";
|
import { setPromiseToast } from "@plane/propel/toast";
|
||||||
import type { ISearchIssueResponse, TIssue } from "@plane/types";
|
import type { ISearchIssueResponse, TIssue } from "@plane/types";
|
||||||
import { EIssueLayoutTypes } from "@plane/types";
|
import { EIssueLayoutTypes } from "@plane/types";
|
||||||
import { CustomMenu } from "@plane/ui";
|
import type { TContextMenuItem } from "@plane/ui";
|
||||||
|
import { ActionDropdown } from "@plane/ui";
|
||||||
import { cn } from "@plane/utils";
|
import { cn } from "@plane/utils";
|
||||||
// components
|
// components
|
||||||
import { ExistingIssuesListModal } from "@/components/core/modals/existing-issues-list-modal";
|
import { ExistingIssuesListModal } from "@/components/core/modals/existing-issues-list-modal";
|
||||||
|
|
@ -78,6 +79,19 @@ export const CalendarQuickAddIssueActions = observer(function CalendarQuickAddIs
|
||||||
const handleExistingIssue = () => {
|
const handleExistingIssue = () => {
|
||||||
setIsExistingIssueModalOpen(true);
|
setIsExistingIssueModalOpen(true);
|
||||||
};
|
};
|
||||||
|
const actionItems: TContextMenuItem[] = [
|
||||||
|
{
|
||||||
|
key: "create-work-item",
|
||||||
|
action: handleNewIssue,
|
||||||
|
title: isEpic ? t("epic.add.label") : t("issue.add.label"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "add-existing-work-item",
|
||||||
|
action: handleExistingIssue,
|
||||||
|
title: t("issue.add.existing"),
|
||||||
|
shouldRender: !isEpic,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
if (!projectId) return null;
|
if (!projectId) return null;
|
||||||
|
|
||||||
|
|
@ -117,28 +131,24 @@ export const CalendarQuickAddIssueActions = observer(function CalendarQuickAddIs
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<CustomMenu
|
<ActionDropdown
|
||||||
|
items={actionItems}
|
||||||
placement="bottom-start"
|
placement="bottom-start"
|
||||||
menuButtonOnClick={() => setIsMenuOpen(true)}
|
|
||||||
onMenuClose={() => setIsMenuOpen(false)}
|
|
||||||
className="w-full"
|
className="w-full"
|
||||||
customButtonClassName="w-full"
|
onOpenChange={setIsMenuOpen}
|
||||||
customButton={
|
button={
|
||||||
<div className="flex w-full items-center gap-x-[6px] rounded-md px-2 py-1.5 text-tertiary hover:text-tertiary">
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex w-full items-center gap-x-[6px] rounded-md px-2 py-1.5 text-tertiary hover:text-tertiary"
|
||||||
|
>
|
||||||
<PlusIcon className="h-3.5 w-3.5 flex-shrink-0 stroke-2" />
|
<PlusIcon className="h-3.5 w-3.5 flex-shrink-0 stroke-2" />
|
||||||
<span className="flex-shrink-0 text-13 font-medium">
|
<span className="flex-shrink-0 text-13 font-medium">
|
||||||
{isEpic ? t("epic.add.label") : t("issue.add.label")}
|
{isEpic ? t("epic.add.label") : t("issue.add.label")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</button>
|
||||||
}
|
}
|
||||||
>
|
buttonAsChild
|
||||||
<CustomMenu.MenuItem onClick={handleNewIssue}>
|
/>
|
||||||
{isEpic ? t("epic.add.label") : t("issue.add.label")}
|
|
||||||
</CustomMenu.MenuItem>
|
|
||||||
{!isEpic && (
|
|
||||||
<CustomMenu.MenuItem onClick={handleExistingIssue}>{t("issue.add.existing")}</CustomMenu.MenuItem>
|
|
||||||
)}
|
|
||||||
</CustomMenu>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
isEpic={isEpic}
|
isEpic={isEpic}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ import { PlusIcon } from "@plane/propel/icons";
|
||||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||||
import type { TIssue, ISearchIssueResponse, TIssueKanbanFilters, TIssueGroupByOptions } from "@plane/types";
|
import type { TIssue, ISearchIssueResponse, TIssueKanbanFilters, TIssueGroupByOptions } from "@plane/types";
|
||||||
// ui
|
// ui
|
||||||
import { CustomMenu } from "@plane/ui";
|
import type { TContextMenuItem } from "@plane/ui";
|
||||||
|
import { ActionDropdown } from "@plane/ui";
|
||||||
// components
|
// components
|
||||||
import { ExistingIssuesListModal } from "@/components/core/modals/existing-issues-list-modal";
|
import { ExistingIssuesListModal } from "@/components/core/modals/existing-issues-list-modal";
|
||||||
import { CreateUpdateIssueModal } from "@/components/issues/issue-modal/modal";
|
import { CreateUpdateIssueModal } from "@/components/issues/issue-modal/modal";
|
||||||
|
|
@ -65,6 +66,23 @@ export const HeaderGroupByCard = observer(function HeaderGroupByCard(props: IHea
|
||||||
|
|
||||||
const renderExistingIssueModal = moduleId || cycleId;
|
const renderExistingIssueModal = moduleId || cycleId;
|
||||||
const ExistingIssuesListModalPayload = moduleId ? { module: moduleId.toString() } : { cycle: true };
|
const ExistingIssuesListModalPayload = moduleId ? { module: moduleId.toString() } : { cycle: true };
|
||||||
|
const actionItems: TContextMenuItem[] = [
|
||||||
|
{
|
||||||
|
key: "create-work-item",
|
||||||
|
action: () => {
|
||||||
|
setIsOpen(true);
|
||||||
|
},
|
||||||
|
title: "Create work item",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "add-existing-work-item",
|
||||||
|
action: () => {
|
||||||
|
setOpenExistingIssueListModal(true);
|
||||||
|
},
|
||||||
|
title: "Add an existing work item",
|
||||||
|
shouldRender: !!renderExistingIssueModal,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const handleAddIssuesToView = async (data: ISearchIssueResponse[]) => {
|
const handleAddIssuesToView = async (data: ISearchIssueResponse[]) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
@ -156,29 +174,19 @@ export const HeaderGroupByCard = observer(function HeaderGroupByCard(props: IHea
|
||||||
|
|
||||||
{!disableIssueCreation &&
|
{!disableIssueCreation &&
|
||||||
(renderExistingIssueModal ? (
|
(renderExistingIssueModal ? (
|
||||||
<CustomMenu
|
<ActionDropdown
|
||||||
customButton={
|
items={actionItems}
|
||||||
<span className="flex h-[20px] w-[20px] flex-shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-sm bg-layer-transparent transition-all hover:bg-layer-transparent-hover">
|
button={
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex h-[20px] w-[20px] flex-shrink-0 items-center justify-center overflow-hidden rounded-sm bg-layer-transparent transition-all hover:bg-layer-transparent-hover"
|
||||||
|
>
|
||||||
<PlusIcon height={14} width={14} strokeWidth={2} />
|
<PlusIcon height={14} width={14} strokeWidth={2} />
|
||||||
</span>
|
</button>
|
||||||
}
|
}
|
||||||
|
buttonAsChild
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
>
|
/>
|
||||||
<CustomMenu.MenuItem
|
|
||||||
onClick={() => {
|
|
||||||
setIsOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="flex items-center justify-start gap-2">Create work item</span>
|
|
||||||
</CustomMenu.MenuItem>
|
|
||||||
<CustomMenu.MenuItem
|
|
||||||
onClick={() => {
|
|
||||||
setOpenExistingIssueListModal(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="flex items-center justify-start gap-2">Add an existing work item</span>
|
|
||||||
</CustomMenu.MenuItem>
|
|
||||||
</CustomMenu>
|
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
className="flex h-[20px] w-[20px] flex-shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-sm bg-layer-transparent transition-all hover:bg-layer-transparent-hover"
|
className="flex h-[20px] w-[20px] flex-shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-sm bg-layer-transparent transition-all hover:bg-layer-transparent-hover"
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ import { PlusIcon } from "@plane/propel/icons";
|
||||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||||
import type { TIssue, ISearchIssueResponse, TIssueGroupByOptions } from "@plane/types";
|
import type { TIssue, ISearchIssueResponse, TIssueGroupByOptions } from "@plane/types";
|
||||||
// ui
|
// ui
|
||||||
import { CustomMenu } from "@plane/ui";
|
import type { TContextMenuItem } from "@plane/ui";
|
||||||
|
import { ActionDropdown } from "@plane/ui";
|
||||||
// components
|
// components
|
||||||
import { cn } from "@plane/utils";
|
import { cn } from "@plane/utils";
|
||||||
import { ExistingIssuesListModal } from "@/components/core/modals/existing-issues-list-modal";
|
import { ExistingIssuesListModal } from "@/components/core/modals/existing-issues-list-modal";
|
||||||
|
|
@ -67,6 +68,23 @@ export const HeaderGroupByCard = observer(function HeaderGroupByCard(props: IHea
|
||||||
const renderExistingIssueModal = moduleId || cycleId;
|
const renderExistingIssueModal = moduleId || cycleId;
|
||||||
const existingIssuesListModalPayload = moduleId ? { module: moduleId.toString() } : { cycle: true };
|
const existingIssuesListModalPayload = moduleId ? { module: moduleId.toString() } : { cycle: true };
|
||||||
const isGroupSelectionEmpty = selectionHelpers.isGroupSelected(groupID) === "empty";
|
const isGroupSelectionEmpty = selectionHelpers.isGroupSelected(groupID) === "empty";
|
||||||
|
const actionItems: TContextMenuItem[] = [
|
||||||
|
{
|
||||||
|
key: "create-work-item",
|
||||||
|
action: () => {
|
||||||
|
setIsOpen(true);
|
||||||
|
},
|
||||||
|
title: "Create work item",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "add-existing-work-item",
|
||||||
|
action: () => {
|
||||||
|
setOpenExistingIssueListModal(true);
|
||||||
|
},
|
||||||
|
title: "Add an existing work item",
|
||||||
|
shouldRender: !!renderExistingIssueModal,
|
||||||
|
},
|
||||||
|
];
|
||||||
// auth
|
// auth
|
||||||
const canSelectIssues = canEditProperties(projectId?.toString()) && !selectionHelpers.isSelectionDisabled;
|
const canSelectIssues = canEditProperties(projectId?.toString()) && !selectionHelpers.isSelectionDisabled;
|
||||||
|
|
||||||
|
|
@ -127,28 +145,18 @@ export const HeaderGroupByCard = observer(function HeaderGroupByCard(props: IHea
|
||||||
|
|
||||||
{!disableIssueCreation &&
|
{!disableIssueCreation &&
|
||||||
(renderExistingIssueModal ? (
|
(renderExistingIssueModal ? (
|
||||||
<CustomMenu
|
<ActionDropdown
|
||||||
customButton={
|
items={actionItems}
|
||||||
<span className="flex h-5 w-5 flex-shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-xs transition-all hover:bg-layer-1">
|
button={
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex h-5 w-5 flex-shrink-0 items-center justify-center overflow-hidden rounded-xs transition-all hover:bg-layer-1"
|
||||||
|
>
|
||||||
<PlusIcon className="h-3.5 w-3.5" strokeWidth={2} />
|
<PlusIcon className="h-3.5 w-3.5" strokeWidth={2} />
|
||||||
</span>
|
</button>
|
||||||
}
|
}
|
||||||
>
|
buttonAsChild
|
||||||
<CustomMenu.MenuItem
|
/>
|
||||||
onClick={() => {
|
|
||||||
setIsOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="flex items-center justify-start gap-2">Create work item</span>
|
|
||||||
</CustomMenu.MenuItem>
|
|
||||||
<CustomMenu.MenuItem
|
|
||||||
onClick={() => {
|
|
||||||
setOpenExistingIssueListModal(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="flex items-center justify-start gap-2">Add an existing work item</span>
|
|
||||||
</CustomMenu.MenuItem>
|
|
||||||
</CustomMenu>
|
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className="flex h-5 w-5 flex-shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-xs transition-all hover:bg-layer-1"
|
className="flex h-5 w-5 flex-shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-xs transition-all hover:bg-layer-1"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue