mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
73eed69aa6
* fix: handled undefined issue_id in list layout * dev: issue detail store and optimization * dev: issue filter and list operations * fix: typo on labels update * dev: Handled all issues in the list layout in project issues * dev: handled kanban and auick add issue in swimlanes * chore: fixed peekoverview in kanban * chore: fixed peekoverview in calendar * chore: fixed peekoverview in gantt * chore: updated quick add in the gantt chart * chore: handled issue detail properties and resolved build issues --------- Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
83 lines
2.6 KiB
TypeScript
83 lines
2.6 KiB
TypeScript
import React, { useState } from "react";
|
|
import { observer } from "mobx-react-lite";
|
|
import { X } from "lucide-react";
|
|
// hooks
|
|
import { useIssueDetail, useProject } from "hooks/store";
|
|
import { Spinner } from "@plane/ui";
|
|
// components
|
|
import { ParentIssuesListModal } from "components/issues";
|
|
import { TIssueOperations } from "./root";
|
|
|
|
type TIssueParentSelect = {
|
|
workspaceSlug: string;
|
|
projectId: string;
|
|
issueId: string;
|
|
issueOperations: TIssueOperations;
|
|
|
|
disabled?: boolean;
|
|
};
|
|
|
|
export const IssueParentSelect: React.FC<TIssueParentSelect> = observer(
|
|
({ workspaceSlug, projectId, issueId, issueOperations, disabled = false }) => {
|
|
// hooks
|
|
const { getProjectById } = useProject();
|
|
const {
|
|
issue: { getIssueById },
|
|
} = useIssueDetail();
|
|
// state
|
|
const { isParentIssueModalOpen, toggleParentIssueModal } = useIssueDetail();
|
|
const [updating, setUpdating] = useState(false);
|
|
|
|
const issue = getIssueById(issueId);
|
|
|
|
const parentIssue = issue && issue.parent_id ? getIssueById(issue.parent_id) : undefined;
|
|
const parentIssueProjectDetails =
|
|
parentIssue && parentIssue.project_id ? getProjectById(parentIssue.project_id) : undefined;
|
|
|
|
const handleParentIssue = async (_issueId: string | null = null) => {
|
|
setUpdating(true);
|
|
await issueOperations.update(workspaceSlug, projectId, issueId, { parent_id: _issueId }).finally(() => {
|
|
toggleParentIssueModal(false);
|
|
setUpdating(false);
|
|
});
|
|
};
|
|
|
|
if (!issue) return <></>;
|
|
|
|
return (
|
|
<div className="relative flex items-center gap-2">
|
|
<ParentIssuesListModal
|
|
projectId={projectId}
|
|
issueId={issueId}
|
|
isOpen={isParentIssueModalOpen}
|
|
handleClose={() => toggleParentIssueModal(false)}
|
|
onChange={(issue: any) => handleParentIssue(issue?.id)}
|
|
/>
|
|
|
|
<button
|
|
className={`flex items-center gap-2 rounded bg-custom-background-80 px-2.5 py-0.5 text-xs w-max max-w-max" ${
|
|
disabled ? "cursor-not-allowed" : "cursor-pointer "
|
|
}`}
|
|
disabled={disabled}
|
|
>
|
|
<div onClick={() => toggleParentIssueModal(true)}>
|
|
{parentIssue ? (
|
|
`${parentIssueProjectDetails?.identifier}-${parentIssue.sequence_id}`
|
|
) : (
|
|
<span className="text-custom-text-200">Select issue</span>
|
|
)}
|
|
</div>
|
|
|
|
{parentIssue && (
|
|
<div onClick={() => handleParentIssue(null)}>
|
|
<X className="h-2.5 w-2.5" />
|
|
</div>
|
|
)}
|
|
</button>
|
|
|
|
{updating && <Spinner className="h-4 w-4" />}
|
|
</div>
|
|
);
|
|
}
|
|
);
|