mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
feat: completed cycle validation , fix: quick action and kanban fix (#505)
* feat: completed cycle card validation * fix: unique key to hidden group * feat: completed cycle sidebar validation * fix: remove console log from progress chart hover * feat: kanban and list view completed cycle validation * feat: quick action validation * refactor: code refactor * fix: sidebar draft cycle status
This commit is contained in:
parent
5191fc5f7c
commit
b6a3615f66
@ -18,6 +18,7 @@ type Props = {
|
|||||||
handleDeleteIssue: (issue: IIssue) => void;
|
handleDeleteIssue: (issue: IIssue) => void;
|
||||||
handleTrashBox: (isDragging: boolean) => void;
|
handleTrashBox: (isDragging: boolean) => void;
|
||||||
removeIssue: ((bridgeId: string) => void) | null;
|
removeIssue: ((bridgeId: string) => void) | null;
|
||||||
|
isCompleted?: boolean;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ export const AllBoards: React.FC<Props> = ({
|
|||||||
handleDeleteIssue,
|
handleDeleteIssue,
|
||||||
handleTrashBox,
|
handleTrashBox,
|
||||||
removeIssue,
|
removeIssue,
|
||||||
|
isCompleted = false,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
@ -62,6 +64,7 @@ export const AllBoards: React.FC<Props> = ({
|
|||||||
openIssuesListModal={openIssuesListModal ?? null}
|
openIssuesListModal={openIssuesListModal ?? null}
|
||||||
handleTrashBox={handleTrashBox}
|
handleTrashBox={handleTrashBox}
|
||||||
removeIssue={removeIssue}
|
removeIssue={removeIssue}
|
||||||
|
isCompleted={isCompleted}
|
||||||
userAuth={userAuth}
|
userAuth={userAuth}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -15,6 +15,7 @@ type Props = {
|
|||||||
addIssueToState: () => void;
|
addIssueToState: () => void;
|
||||||
isCollapsed: boolean;
|
isCollapsed: boolean;
|
||||||
setIsCollapsed: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsCollapsed: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
isCompleted?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BoardHeader: React.FC<Props> = ({
|
export const BoardHeader: React.FC<Props> = ({
|
||||||
@ -23,6 +24,7 @@ export const BoardHeader: React.FC<Props> = ({
|
|||||||
addIssueToState,
|
addIssueToState,
|
||||||
isCollapsed,
|
isCollapsed,
|
||||||
setIsCollapsed,
|
setIsCollapsed,
|
||||||
|
isCompleted = false,
|
||||||
}) => {
|
}) => {
|
||||||
const { groupedByIssues, groupByProperty: selectedGroup } = useIssuesView();
|
const { groupedByIssues, groupByProperty: selectedGroup } = useIssuesView();
|
||||||
|
|
||||||
@ -81,13 +83,15 @@ export const BoardHeader: React.FC<Props> = ({
|
|||||||
<ArrowsPointingOutIcon className="h-4 w-4" />
|
<ArrowsPointingOutIcon className="h-4 w-4" />
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
<button
|
{!isCompleted && (
|
||||||
type="button"
|
<button
|
||||||
className="grid h-7 w-7 place-items-center rounded p-1 text-gray-700 outline-none duration-300 hover:bg-gray-100"
|
type="button"
|
||||||
onClick={addIssueToState}
|
className="grid h-7 w-7 place-items-center rounded p-1 text-gray-700 outline-none duration-300 hover:bg-gray-100"
|
||||||
>
|
onClick={addIssueToState}
|
||||||
<PlusIcon className="h-4 w-4" />
|
>
|
||||||
</button>
|
<PlusIcon className="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -30,6 +30,7 @@ type Props = {
|
|||||||
openIssuesListModal?: (() => void) | null;
|
openIssuesListModal?: (() => void) | null;
|
||||||
handleTrashBox: (isDragging: boolean) => void;
|
handleTrashBox: (isDragging: boolean) => void;
|
||||||
removeIssue: ((bridgeId: string) => void) | null;
|
removeIssue: ((bridgeId: string) => void) | null;
|
||||||
|
isCompleted?: boolean;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ export const SingleBoard: React.FC<Props> = ({
|
|||||||
openIssuesListModal,
|
openIssuesListModal,
|
||||||
handleTrashBox,
|
handleTrashBox,
|
||||||
removeIssue,
|
removeIssue,
|
||||||
|
isCompleted = false,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
// collapse/expand
|
// collapse/expand
|
||||||
@ -56,7 +58,7 @@ export const SingleBoard: React.FC<Props> = ({
|
|||||||
|
|
||||||
const [properties] = useIssuesProperties(workspaceSlug as string, projectId as string);
|
const [properties] = useIssuesProperties(workspaceSlug as string, projectId as string);
|
||||||
|
|
||||||
const isNotAllowed = userAuth.isGuest || userAuth.isViewer;
|
const isNotAllowed = userAuth.isGuest || userAuth.isViewer || isCompleted;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentState?.group === "completed" || currentState?.group === "cancelled")
|
if (currentState?.group === "completed" || currentState?.group === "cancelled")
|
||||||
@ -72,6 +74,7 @@ export const SingleBoard: React.FC<Props> = ({
|
|||||||
groupTitle={groupTitle}
|
groupTitle={groupTitle}
|
||||||
isCollapsed={isCollapsed}
|
isCollapsed={isCollapsed}
|
||||||
setIsCollapsed={setIsCollapsed}
|
setIsCollapsed={setIsCollapsed}
|
||||||
|
isCompleted={isCompleted}
|
||||||
/>
|
/>
|
||||||
{isCollapsed && (
|
{isCollapsed && (
|
||||||
<StrictModeDroppable key={groupTitle} droppableId={groupTitle}>
|
<StrictModeDroppable key={groupTitle} droppableId={groupTitle}>
|
||||||
@ -125,6 +128,7 @@ export const SingleBoard: React.FC<Props> = ({
|
|||||||
removeIssue={() => {
|
removeIssue={() => {
|
||||||
if (removeIssue && issue.bridge_id) removeIssue(issue.bridge_id);
|
if (removeIssue && issue.bridge_id) removeIssue(issue.bridge_id);
|
||||||
}}
|
}}
|
||||||
|
isCompleted={isCompleted}
|
||||||
userAuth={userAuth}
|
userAuth={userAuth}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -147,26 +151,30 @@ export const SingleBoard: React.FC<Props> = ({
|
|||||||
Add Issue
|
Add Issue
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<CustomMenu
|
!isCompleted && (
|
||||||
customButton={
|
<CustomMenu
|
||||||
<button
|
customButton={
|
||||||
type="button"
|
<button
|
||||||
className="flex items-center gap-2 font-medium text-theme outline-none"
|
type="button"
|
||||||
>
|
className="flex items-center gap-2 font-medium text-theme outline-none"
|
||||||
<PlusIcon className="h-4 w-4" />
|
>
|
||||||
Add Issue
|
<PlusIcon className="h-4 w-4" />
|
||||||
</button>
|
Add Issue
|
||||||
}
|
</button>
|
||||||
optionsPosition="left"
|
}
|
||||||
noBorder
|
optionsPosition="left"
|
||||||
>
|
noBorder
|
||||||
<CustomMenu.MenuItem onClick={addIssueToState}>Create new</CustomMenu.MenuItem>
|
>
|
||||||
{openIssuesListModal && (
|
<CustomMenu.MenuItem onClick={addIssueToState}>
|
||||||
<CustomMenu.MenuItem onClick={openIssuesListModal}>
|
Create new
|
||||||
Add an existing issue
|
|
||||||
</CustomMenu.MenuItem>
|
</CustomMenu.MenuItem>
|
||||||
)}
|
{openIssuesListModal && (
|
||||||
</CustomMenu>
|
<CustomMenu.MenuItem onClick={openIssuesListModal}>
|
||||||
|
Add an existing issue
|
||||||
|
</CustomMenu.MenuItem>
|
||||||
|
)}
|
||||||
|
</CustomMenu>
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -59,6 +59,7 @@ type Props = {
|
|||||||
removeIssue?: (() => void) | null;
|
removeIssue?: (() => void) | null;
|
||||||
handleDeleteIssue: (issue: IIssue) => void;
|
handleDeleteIssue: (issue: IIssue) => void;
|
||||||
handleTrashBox: (isDragging: boolean) => void;
|
handleTrashBox: (isDragging: boolean) => void;
|
||||||
|
isCompleted?: boolean;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,6 +77,7 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
groupTitle,
|
groupTitle,
|
||||||
handleDeleteIssue,
|
handleDeleteIssue,
|
||||||
handleTrashBox,
|
handleTrashBox,
|
||||||
|
isCompleted = false,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
// context menu
|
// context menu
|
||||||
@ -177,7 +179,7 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
if (snapshot.isDragging) handleTrashBox(snapshot.isDragging);
|
if (snapshot.isDragging) handleTrashBox(snapshot.isDragging);
|
||||||
}, [snapshot, handleTrashBox]);
|
}, [snapshot, handleTrashBox]);
|
||||||
|
|
||||||
const isNotAllowed = userAuth.isGuest || userAuth.isViewer;
|
const isNotAllowed = userAuth.isGuest || userAuth.isViewer || isCompleted;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -187,15 +189,19 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
isOpen={contextMenu}
|
isOpen={contextMenu}
|
||||||
setIsOpen={setContextMenu}
|
setIsOpen={setContextMenu}
|
||||||
>
|
>
|
||||||
<ContextMenu.Item Icon={PencilIcon} onClick={editIssue}>
|
{!isNotAllowed &&(
|
||||||
Edit issue
|
<>
|
||||||
</ContextMenu.Item>
|
<ContextMenu.Item Icon={PencilIcon} onClick={editIssue}>
|
||||||
<ContextMenu.Item Icon={ClipboardDocumentCheckIcon} onClick={makeIssueCopy}>
|
Edit issue
|
||||||
Make a copy...
|
</ContextMenu.Item>
|
||||||
</ContextMenu.Item>
|
<ContextMenu.Item Icon={ClipboardDocumentCheckIcon} onClick={makeIssueCopy}>
|
||||||
<ContextMenu.Item Icon={TrashIcon} onClick={() => handleDeleteIssue(issue)}>
|
Make a copy...
|
||||||
Delete issue
|
</ContextMenu.Item>
|
||||||
</ContextMenu.Item>
|
<ContextMenu.Item Icon={TrashIcon} onClick={() => handleDeleteIssue(issue)}>
|
||||||
|
Delete issue
|
||||||
|
</ContextMenu.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<ContextMenu.Item Icon={LinkIcon} onClick={handleCopyText}>
|
<ContextMenu.Item Icon={LinkIcon} onClick={handleCopyText}>
|
||||||
Copy issue link
|
Copy issue link
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
|
@ -55,10 +55,16 @@ import { getStateGroupIcon } from "components/icons";
|
|||||||
type Props = {
|
type Props = {
|
||||||
type?: "issue" | "cycle" | "module";
|
type?: "issue" | "cycle" | "module";
|
||||||
openIssuesListModal?: () => void;
|
openIssuesListModal?: () => void;
|
||||||
|
isCompleted?: boolean;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IssuesView: React.FC<Props> = ({ type = "issue", openIssuesListModal, userAuth }) => {
|
export const IssuesView: React.FC<Props> = ({
|
||||||
|
type = "issue",
|
||||||
|
openIssuesListModal,
|
||||||
|
isCompleted = false,
|
||||||
|
userAuth,
|
||||||
|
}) => {
|
||||||
// create issue modal
|
// create issue modal
|
||||||
const [createIssueModal, setCreateIssueModal] = useState(false);
|
const [createIssueModal, setCreateIssueModal] = useState(false);
|
||||||
const [createViewModal, setCreateViewModal] = useState<any>(null);
|
const [createViewModal, setCreateViewModal] = useState<any>(null);
|
||||||
@ -592,6 +598,7 @@ export const IssuesView: React.FC<Props> = ({ type = "issue", openIssuesListModa
|
|||||||
? removeIssueFromModule
|
? removeIssueFromModule
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
isCompleted={isCompleted}
|
||||||
userAuth={userAuth}
|
userAuth={userAuth}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@ -611,6 +618,7 @@ export const IssuesView: React.FC<Props> = ({ type = "issue", openIssuesListModa
|
|||||||
? removeIssueFromModule
|
? removeIssueFromModule
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
isCompleted={isCompleted}
|
||||||
userAuth={userAuth}
|
userAuth={userAuth}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -15,6 +15,7 @@ type Props = {
|
|||||||
handleDeleteIssue: (issue: IIssue) => void;
|
handleDeleteIssue: (issue: IIssue) => void;
|
||||||
openIssuesListModal?: (() => void) | null;
|
openIssuesListModal?: (() => void) | null;
|
||||||
removeIssue: ((bridgeId: string) => void) | null;
|
removeIssue: ((bridgeId: string) => void) | null;
|
||||||
|
isCompleted?: boolean;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ export const AllLists: React.FC<Props> = ({
|
|||||||
handleEditIssue,
|
handleEditIssue,
|
||||||
handleDeleteIssue,
|
handleDeleteIssue,
|
||||||
removeIssue,
|
removeIssue,
|
||||||
|
isCompleted = false,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
const { groupedByIssues, groupByProperty: selectedGroup, showEmptyGroups } = useIssuesView();
|
const { groupedByIssues, groupByProperty: selectedGroup, showEmptyGroups } = useIssuesView();
|
||||||
@ -55,6 +57,7 @@ export const AllLists: React.FC<Props> = ({
|
|||||||
handleDeleteIssue={handleDeleteIssue}
|
handleDeleteIssue={handleDeleteIssue}
|
||||||
openIssuesListModal={type !== "issue" ? openIssuesListModal : null}
|
openIssuesListModal={type !== "issue" ? openIssuesListModal : null}
|
||||||
removeIssue={removeIssue}
|
removeIssue={removeIssue}
|
||||||
|
isCompleted={isCompleted}
|
||||||
userAuth={userAuth}
|
userAuth={userAuth}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -49,6 +49,7 @@ type Props = {
|
|||||||
makeIssueCopy: () => void;
|
makeIssueCopy: () => void;
|
||||||
removeIssue?: (() => void) | null;
|
removeIssue?: (() => void) | null;
|
||||||
handleDeleteIssue: (issue: IIssue) => void;
|
handleDeleteIssue: (issue: IIssue) => void;
|
||||||
|
isCompleted?: boolean;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
removeIssue,
|
removeIssue,
|
||||||
groupTitle,
|
groupTitle,
|
||||||
handleDeleteIssue,
|
handleDeleteIssue,
|
||||||
|
isCompleted = false,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
// context menu
|
// context menu
|
||||||
@ -145,7 +147,7 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const isNotAllowed = userAuth.isGuest || userAuth.isViewer;
|
const isNotAllowed = userAuth.isGuest || userAuth.isViewer || isCompleted;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -155,15 +157,19 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
isOpen={contextMenu}
|
isOpen={contextMenu}
|
||||||
setIsOpen={setContextMenu}
|
setIsOpen={setContextMenu}
|
||||||
>
|
>
|
||||||
<ContextMenu.Item Icon={PencilIcon} onClick={editIssue}>
|
{!isNotAllowed && (
|
||||||
Edit issue
|
<>
|
||||||
</ContextMenu.Item>
|
<ContextMenu.Item Icon={PencilIcon} onClick={editIssue}>
|
||||||
<ContextMenu.Item Icon={ClipboardDocumentCheckIcon} onClick={makeIssueCopy}>
|
Edit issue
|
||||||
Make a copy...
|
</ContextMenu.Item>
|
||||||
</ContextMenu.Item>
|
<ContextMenu.Item Icon={ClipboardDocumentCheckIcon} onClick={makeIssueCopy}>
|
||||||
<ContextMenu.Item Icon={TrashIcon} onClick={() => handleDeleteIssue(issue)}>
|
Make a copy...
|
||||||
Delete issue
|
</ContextMenu.Item>
|
||||||
</ContextMenu.Item>
|
<ContextMenu.Item Icon={TrashIcon} onClick={() => handleDeleteIssue(issue)}>
|
||||||
|
Delete issue
|
||||||
|
</ContextMenu.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<ContextMenu.Item Icon={LinkIcon} onClick={handleCopyText}>
|
<ContextMenu.Item Icon={LinkIcon} onClick={handleCopyText}>
|
||||||
Copy issue link
|
Copy issue link
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
|
@ -30,6 +30,7 @@ type Props = {
|
|||||||
handleDeleteIssue: (issue: IIssue) => void;
|
handleDeleteIssue: (issue: IIssue) => void;
|
||||||
openIssuesListModal?: (() => void) | null;
|
openIssuesListModal?: (() => void) | null;
|
||||||
removeIssue: ((bridgeId: string) => void) | null;
|
removeIssue: ((bridgeId: string) => void) | null;
|
||||||
|
isCompleted?: boolean;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ export const SingleList: React.FC<Props> = ({
|
|||||||
handleDeleteIssue,
|
handleDeleteIssue,
|
||||||
openIssuesListModal,
|
openIssuesListModal,
|
||||||
removeIssue,
|
removeIssue,
|
||||||
|
isCompleted = false,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -93,9 +95,11 @@ export const SingleList: React.FC<Props> = ({
|
|||||||
>
|
>
|
||||||
<PlusIcon className="h-4 w-4" />
|
<PlusIcon className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
|
) : isCompleted ? (
|
||||||
|
""
|
||||||
) : (
|
) : (
|
||||||
<CustomMenu
|
<CustomMenu
|
||||||
label={
|
customButton={
|
||||||
<span className="flex items-center">
|
<span className="flex items-center">
|
||||||
<PlusIcon className="h-4 w-4" />
|
<PlusIcon className="h-4 w-4" />
|
||||||
</span>
|
</span>
|
||||||
@ -138,6 +142,7 @@ export const SingleList: React.FC<Props> = ({
|
|||||||
removeIssue={() => {
|
removeIssue={() => {
|
||||||
if (removeIssue !== null && issue.bridge_id) removeIssue(issue.bridge_id);
|
if (removeIssue !== null && issue.bridge_id) removeIssue(issue.bridge_id);
|
||||||
}}
|
}}
|
||||||
|
isCompleted={isCompleted}
|
||||||
userAuth={userAuth}
|
userAuth={userAuth}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
@ -39,7 +39,6 @@ const ProgressChart: React.FC<Props> = ({ issues, start, end }) => {
|
|||||||
|
|
||||||
const CustomTooltip = ({ active, payload }: TooltipProps<ValueType, NameType>) => {
|
const CustomTooltip = ({ active, payload }: TooltipProps<ValueType, NameType>) => {
|
||||||
if (active && payload && payload.length) {
|
if (active && payload && payload.length) {
|
||||||
console.log(payload[0].payload.currentDate);
|
|
||||||
return (
|
return (
|
||||||
<div className="rounded-sm bg-gray-300 p-1 text-xs text-gray-800">
|
<div className="rounded-sm bg-gray-300 p-1 text-xs text-gray-800">
|
||||||
<p>{payload[0].payload.currentDate}</p>
|
<p>{payload[0].payload.currentDate}</p>
|
||||||
|
@ -70,6 +70,7 @@ export const CompletedCyclesList: React.FC<CompletedCyclesListProps> = ({
|
|||||||
cycle={cycle}
|
cycle={cycle}
|
||||||
handleDeleteCycle={() => handleDeleteCycle(cycle)}
|
handleDeleteCycle={() => handleDeleteCycle(cycle)}
|
||||||
handleEditCycle={() => handleEditCycle(cycle)}
|
handleEditCycle={() => handleEditCycle(cycle)}
|
||||||
|
isCompleted
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,9 +45,15 @@ type Props = {
|
|||||||
cycle: ICycle | undefined;
|
cycle: ICycle | undefined;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
cycleStatus: string;
|
cycleStatus: string;
|
||||||
|
isCompleted: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CycleDetailsSidebar: React.FC<Props> = ({ cycle, isOpen, cycleStatus }) => {
|
export const CycleDetailsSidebar: React.FC<Props> = ({
|
||||||
|
cycle,
|
||||||
|
isOpen,
|
||||||
|
cycleStatus,
|
||||||
|
isCompleted,
|
||||||
|
}) => {
|
||||||
const [cycleDeleteModal, setCycleDeleteModal] = useState(false);
|
const [cycleDeleteModal, setCycleDeleteModal] = useState(false);
|
||||||
const [startDateRange, setStartDateRange] = useState<Date | null>(new Date());
|
const [startDateRange, setStartDateRange] = useState<Date | null>(new Date());
|
||||||
const [endDateRange, setEndDateRange] = useState<Date | null>(null);
|
const [endDateRange, setEndDateRange] = useState<Date | null>(null);
|
||||||
@ -164,6 +170,7 @@ export const CycleDetailsSidebar: React.FC<Props> = ({ cycle, isOpen, cycleStatu
|
|||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<Popover.Button
|
<Popover.Button
|
||||||
|
disabled={isCompleted ?? false}
|
||||||
className={`group flex h-full items-center gap-1 rounded border-[0.5px] border-gray-200 bg-gray-100 px-2.5 py-1.5 text-gray-800 ${
|
className={`group flex h-full items-center gap-1 rounded border-[0.5px] border-gray-200 bg-gray-100 px-2.5 py-1.5 text-gray-800 ${
|
||||||
open ? "bg-gray-100" : ""
|
open ? "bg-gray-100" : ""
|
||||||
}`}
|
}`}
|
||||||
@ -209,6 +216,7 @@ export const CycleDetailsSidebar: React.FC<Props> = ({ cycle, isOpen, cycleStatu
|
|||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<Popover.Button
|
<Popover.Button
|
||||||
|
disabled={isCompleted ?? false}
|
||||||
className={`group flex items-center gap-1 rounded border-[0.5px] border-gray-200 bg-gray-100 px-2.5 py-1.5 text-gray-800 ${
|
className={`group flex items-center gap-1 rounded border-[0.5px] border-gray-200 bg-gray-100 px-2.5 py-1.5 text-gray-800 ${
|
||||||
open ? "bg-gray-100" : ""
|
open ? "bg-gray-100" : ""
|
||||||
}`}
|
}`}
|
||||||
@ -262,12 +270,14 @@ export const CycleDetailsSidebar: React.FC<Props> = ({ cycle, isOpen, cycleStatu
|
|||||||
<span>Copy Link</span>
|
<span>Copy Link</span>
|
||||||
</span>
|
</span>
|
||||||
</CustomMenu.MenuItem>
|
</CustomMenu.MenuItem>
|
||||||
<CustomMenu.MenuItem onClick={() => setCycleDeleteModal(true)}>
|
{!isCompleted && (
|
||||||
<span className="flex items-center justify-start gap-2 text-gray-800">
|
<CustomMenu.MenuItem onClick={() => setCycleDeleteModal(true)}>
|
||||||
<TrashIcon className="h-4 w-4" />
|
<span className="flex items-center justify-start gap-2 text-gray-800">
|
||||||
<span>Delete</span>
|
<TrashIcon className="h-4 w-4" />
|
||||||
</span>
|
<span>Delete</span>
|
||||||
</CustomMenu.MenuItem>
|
</span>
|
||||||
|
</CustomMenu.MenuItem>
|
||||||
|
)}
|
||||||
</CustomMenu>
|
</CustomMenu>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ type TSingleStatProps = {
|
|||||||
cycle: ICycle;
|
cycle: ICycle;
|
||||||
handleEditCycle: () => void;
|
handleEditCycle: () => void;
|
||||||
handleDeleteCycle: () => void;
|
handleDeleteCycle: () => void;
|
||||||
|
isCompleted?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const stateGroups = [
|
const stateGroups = [
|
||||||
@ -77,6 +78,7 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
|
|||||||
cycle,
|
cycle,
|
||||||
handleEditCycle,
|
handleEditCycle,
|
||||||
handleDeleteCycle,
|
handleDeleteCycle,
|
||||||
|
isCompleted = false,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
@ -293,22 +295,26 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
|
|||||||
<span className="text-gray-900">{cycle.owned_by.first_name}</span>
|
<span className="text-gray-900">{cycle.owned_by.first_name}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<button
|
{!isCompleted && (
|
||||||
onClick={handleEditCycle}
|
<button
|
||||||
className="flex cursor-pointer items-center rounded p-1 duration-300 hover:bg-gray-100"
|
onClick={handleEditCycle}
|
||||||
>
|
className="flex cursor-pointer items-center rounded p-1 duration-300 hover:bg-gray-100"
|
||||||
<span>
|
>
|
||||||
<PencilIcon className="h-4 w-4" />
|
<span>
|
||||||
</span>
|
<PencilIcon className="h-4 w-4" />
|
||||||
</button>
|
</span>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
<CustomMenu width="auto" verticalEllipsis>
|
<CustomMenu width="auto" verticalEllipsis>
|
||||||
<CustomMenu.MenuItem onClick={handleDeleteCycle}>
|
{!isCompleted && (
|
||||||
<span className="flex items-center justify-start gap-2 text-gray-800">
|
<CustomMenu.MenuItem onClick={handleDeleteCycle}>
|
||||||
<TrashIcon className="h-4 w-4" />
|
<span className="flex items-center justify-start gap-2 text-gray-800">
|
||||||
<span>Delete Cycle</span>
|
<TrashIcon className="h-4 w-4" />
|
||||||
</span>
|
<span>Delete Cycle</span>
|
||||||
</CustomMenu.MenuItem>
|
</span>
|
||||||
|
</CustomMenu.MenuItem>
|
||||||
|
)}
|
||||||
<CustomMenu.MenuItem onClick={handleCopyText}>
|
<CustomMenu.MenuItem onClick={handleCopyText}>
|
||||||
<span className="flex items-center justify-start gap-2 text-gray-800">
|
<span className="flex items-center justify-start gap-2 text-gray-800">
|
||||||
<DocumentDuplicateIcon className="h-4 w-4" />
|
<DocumentDuplicateIcon className="h-4 w-4" />
|
||||||
|
@ -73,7 +73,7 @@ const SingleCycle: React.FC<UserAuth> = (props) => {
|
|||||||
const cycleStatus =
|
const cycleStatus =
|
||||||
cycleDetails?.start_date && cycleDetails?.end_date
|
cycleDetails?.start_date && cycleDetails?.end_date
|
||||||
? getDateRangeStatus(cycleDetails?.start_date, cycleDetails?.end_date)
|
? getDateRangeStatus(cycleDetails?.start_date, cycleDetails?.end_date)
|
||||||
: "";
|
: "draft";
|
||||||
|
|
||||||
const { data: issues } = useSWR(
|
const { data: issues } = useSWR(
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
@ -159,9 +159,9 @@ const SingleCycle: React.FC<UserAuth> = (props) => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className={`h-full ${cycleSidebar ? "mr-[24rem]" : ""} duration-300`}>
|
<div className={`h-full ${cycleSidebar ? "mr-[24rem]" : ""} duration-300`}>
|
||||||
<IssuesView type="cycle" userAuth={props} openIssuesListModal={openIssuesListModal} />
|
<IssuesView type="cycle" userAuth={props} openIssuesListModal={openIssuesListModal} isCompleted={cycleStatus === "completed" ?? false} />
|
||||||
</div>
|
</div>
|
||||||
<CycleDetailsSidebar cycleStatus={cycleStatus} cycle={cycleDetails} isOpen={cycleSidebar} />
|
<CycleDetailsSidebar cycleStatus={cycleStatus} cycle={cycleDetails} isOpen={cycleSidebar} isCompleted={cycleStatus === "completed" ?? false} />
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
</IssueViewContextProvider>
|
</IssueViewContextProvider>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user