[WEB-2941]chore: added transfer issues button to cycles (#6296)
* chore: removed refacotr changes:w * chore: removed requirements modifications
This commit is contained in:
parent
df671d13c7
commit
a555df27e7
4 changed files with 57 additions and 14 deletions
|
|
@ -1,6 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import React, { FC, MouseEvent, useEffect, useMemo } from "react";
|
||||
import React, { FC, MouseEvent, useEffect, useMemo, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { usePathname, useSearchParams } from "next/navigation";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
|
|
@ -15,11 +15,12 @@ import {
|
|||
LayersIcon,
|
||||
TOAST_TYPE,
|
||||
Tooltip,
|
||||
TransferIcon,
|
||||
setPromiseToast,
|
||||
setToast,
|
||||
} from "@plane/ui";
|
||||
// components
|
||||
import { CycleQuickActions } from "@/components/cycles";
|
||||
import { CycleQuickActions, TransferIssuesModal } from "@/components/cycles";
|
||||
import { DateRangeDropdown } from "@/components/dropdowns";
|
||||
import { ButtonAvatars } from "@/components/dropdowns/member/avatar";
|
||||
// constants
|
||||
|
|
@ -32,6 +33,7 @@ import { generateQueryParams } from "@/helpers/router.helper";
|
|||
import { useCycle, useEventTracker, useMember, useUserPermissions } from "@/hooks/store";
|
||||
import { useAppRouter } from "@/hooks/use-app-router";
|
||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// plane web
|
||||
// plane web constants
|
||||
import { EUserPermissions, EUserPermissionsLevel } from "@/plane-web/constants/user-permissions";
|
||||
// services
|
||||
|
|
@ -55,6 +57,8 @@ const defaultValues: Partial<ICycle> = {
|
|||
|
||||
export const CycleListItemAction: FC<Props> = observer((props) => {
|
||||
const { workspaceSlug, projectId, cycleId, cycleDetails, parentRef, isActive = false } = props;
|
||||
//states
|
||||
const [transferIssuesModal, setTransferIssuesModal] = useState(false);
|
||||
// hooks
|
||||
const { isMobile } = usePlatformOS();
|
||||
// router
|
||||
|
|
@ -76,6 +80,8 @@ export const CycleListItemAction: FC<Props> = observer((props) => {
|
|||
// derived values
|
||||
const cycleStatus = cycleDetails.status ? (cycleDetails.status.toLocaleLowerCase() as TCycleGroups) : "draft";
|
||||
const showIssueCount = useMemo(() => cycleStatus === "draft" || cycleStatus === "upcoming", [cycleStatus]);
|
||||
const transferableIssuesCount = cycleDetails ? cycleDetails.total_issues - cycleDetails.completed_issues : 0;
|
||||
const showTransferIssues = transferableIssuesCount > 0 && cycleStatus === "completed";
|
||||
const isEditingAllowed = allowPermissions(
|
||||
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
|
||||
EUserPermissionsLevel.PROJECT,
|
||||
|
|
@ -218,6 +224,11 @@ export const CycleListItemAction: FC<Props> = observer((props) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<TransferIssuesModal
|
||||
handleClose={() => setTransferIssuesModal(false)}
|
||||
isOpen={transferIssuesModal}
|
||||
cycleId={cycleId.toString()}
|
||||
/>
|
||||
<button
|
||||
onClick={openCycleOverview}
|
||||
className={`z-[1] flex text-custom-primary-200 text-xs gap-1 flex-shrink-0 ${isMobile || (isActive && !searchParams.has("peekCycle")) ? "flex" : "hidden group-hover:flex"}`}
|
||||
|
|
@ -233,6 +244,18 @@ export const CycleListItemAction: FC<Props> = observer((props) => {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{showTransferIssues && (
|
||||
<div
|
||||
className="px-2 h-6 text-custom-primary-200 flex items-center gap-1 cursor-pointer"
|
||||
onClick={() => {
|
||||
setTransferIssuesModal(true);
|
||||
}}
|
||||
>
|
||||
<TransferIcon className="fill-custom-primary-200 w-4" />
|
||||
<span>Transfer {transferableIssuesCount} issues</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isActive && (
|
||||
<Controller
|
||||
control={control}
|
||||
|
|
|
|||
|
|
@ -17,42 +17,58 @@ import { useCycle, useIssues } from "@/hooks/store";
|
|||
type Props = {
|
||||
isOpen: boolean;
|
||||
handleClose: () => void;
|
||||
cycleId: string;
|
||||
};
|
||||
|
||||
export const TransferIssuesModal: React.FC<Props> = observer((props) => {
|
||||
const { isOpen, handleClose } = props;
|
||||
const { isOpen, handleClose, cycleId } = props;
|
||||
// states
|
||||
const [query, setQuery] = useState("");
|
||||
|
||||
// store hooks
|
||||
const { currentProjectIncompleteCycleIds, getCycleById } = useCycle();
|
||||
const { currentProjectIncompleteCycleIds, getCycleById, fetchCycleDetails } = useCycle();
|
||||
const {
|
||||
issues: { transferIssuesFromCycle },
|
||||
} = useIssues(EIssuesStoreType.CYCLE);
|
||||
|
||||
const { workspaceSlug, projectId, cycleId } = useParams();
|
||||
const { workspaceSlug, projectId } = useParams();
|
||||
|
||||
const transferIssue = async (payload: any) => {
|
||||
const transferIssue = async (payload: { new_cycle_id: string }) => {
|
||||
if (!workspaceSlug || !projectId || !cycleId) return;
|
||||
|
||||
// TODO: import transferIssuesFromCycle from store
|
||||
await transferIssuesFromCycle(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), payload)
|
||||
.then(() => {
|
||||
.then(async () => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Success!",
|
||||
message: "Issues have been transferred successfully",
|
||||
});
|
||||
await getCycleDetails(payload.new_cycle_id);
|
||||
})
|
||||
.catch(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "Issues cannot be transfer. Please try again.",
|
||||
message: "Unable to transfer Issues. Please try again.",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**To update issue counts in target cycle and current cycle */
|
||||
const getCycleDetails = async (newCycleId: string) => {
|
||||
const cyclesFetch = [
|
||||
fetchCycleDetails(workspaceSlug.toString(), projectId.toString(), cycleId),
|
||||
fetchCycleDetails(workspaceSlug.toString(), projectId.toString(), newCycleId),
|
||||
];
|
||||
await Promise.all(cyclesFetch).catch((error) => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error",
|
||||
message: error.error || "Unable to fetch cycle details",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const filteredOptions = currentProjectIncompleteCycleIds?.filter((optionId) => {
|
||||
const cycleDetails = getCycleById(optionId);
|
||||
|
||||
|
|
@ -96,8 +112,8 @@ export const TransferIssuesModal: React.FC<Props> = observer((props) => {
|
|||
<Dialog.Panel className="relative transform rounded-lg bg-custom-background-100 py-5 text-left shadow-custom-shadow-md transition-all sm:w-full sm:max-w-2xl">
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex items-center justify-between px-5">
|
||||
<div className="flex items-center gap-3">
|
||||
<TransferIcon className="h-4 w-4" color="#495057" />
|
||||
<div className="flex items-center gap-1">
|
||||
<TransferIcon className="w-5 fill-custom-text-100" />
|
||||
<h4 className="text-xl font-medium text-custom-text-100">Transfer Issues</h4>
|
||||
</div>
|
||||
<button onClick={handleClose}>
|
||||
|
|
@ -107,7 +123,7 @@ export const TransferIssuesModal: React.FC<Props> = observer((props) => {
|
|||
<div className="flex items-center gap-2 border-b border-custom-border-200 px-5 pb-3">
|
||||
<Search className="h-4 w-4 text-custom-text-200" />
|
||||
<input
|
||||
className="bg-custom-background-90 outline-none"
|
||||
className="outline-none text-sm"
|
||||
placeholder="Search for a cycle..."
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
value={query}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,11 @@ export const CycleLayoutRoot: React.FC = observer(() => {
|
|||
|
||||
return (
|
||||
<IssuesStoreContext.Provider value={EIssuesStoreType.CYCLE}>
|
||||
<TransferIssuesModal handleClose={() => setTransferIssuesModal(false)} isOpen={transferIssuesModal} />
|
||||
<TransferIssuesModal
|
||||
handleClose={() => setTransferIssuesModal(false)}
|
||||
cycleId={cycleId.toString()}
|
||||
isOpen={transferIssuesModal}
|
||||
/>
|
||||
<div className="relative flex h-full w-full flex-col overflow-hidden">
|
||||
{cycleStatus === "completed" && (
|
||||
<TransferIssues
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue