import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; import { CalendarCheck2, CalendarClock, Layers, Link, Paperclip } from "lucide-react"; // hooks import { useEventTracker, useEstimate, useLabel, useApplication } from "hooks/store"; // components import { IssuePropertyLabels } from "../properties/labels"; import { Tooltip } from "@plane/ui"; import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC"; import { DateDropdown, EstimateDropdown, PriorityDropdown, ProjectMemberDropdown, StateDropdown, } from "components/dropdowns"; // helpers import { renderFormattedPayloadDate } from "helpers/date-time.helper"; // types import { TIssue, IIssueDisplayProperties, TIssuePriorities } from "@plane/types"; // constants import { ISSUE_UPDATED } from "constants/event-tracker"; export interface IIssueProperties { issue: TIssue; handleIssues: (issue: TIssue) => Promise; displayProperties: IIssueDisplayProperties | undefined; isReadOnly: boolean; className: string; activeLayout: string; } export const IssueProperties: React.FC = observer((props) => { const { issue, handleIssues, displayProperties, activeLayout, isReadOnly, className } = props; // store hooks const { labelMap } = useLabel(); const { captureIssueEvent } = useEventTracker(); const { router: { workspaceSlug }, } = useApplication(); // router const router = useRouter(); const { areEstimatesEnabledForCurrentProject } = useEstimate(); const currentLayout = `${activeLayout} layout`; const handleState = (stateId: string) => { handleIssues({ ...issue, state_id: stateId }).then(() => { captureIssueEvent({ eventName: ISSUE_UPDATED, payload: { ...issue, state: "SUCCESS", element: currentLayout }, path: router.asPath, updates: { changed_property: "state", change_details: stateId, }, }); }); }; const handlePriority = (value: TIssuePriorities) => { handleIssues({ ...issue, priority: value }).then(() => { captureIssueEvent({ eventName: ISSUE_UPDATED, payload: { ...issue, state: "SUCCESS", element: currentLayout }, path: router.asPath, updates: { changed_property: "priority", change_details: value, }, }); }); }; const handleLabel = (ids: string[]) => { handleIssues({ ...issue, label_ids: ids }).then(() => { captureIssueEvent({ eventName: ISSUE_UPDATED, payload: { ...issue, state: "SUCCESS", element: currentLayout }, path: router.asPath, updates: { changed_property: "labels", change_details: ids, }, }); }); }; const handleAssignee = (ids: string[]) => { handleIssues({ ...issue, assignee_ids: ids }).then(() => { captureIssueEvent({ eventName: ISSUE_UPDATED, payload: { ...issue, state: "SUCCESS", element: currentLayout }, path: router.asPath, updates: { changed_property: "assignees", change_details: ids, }, }); }); }; const handleStartDate = (date: Date | null) => { handleIssues({ ...issue, start_date: date ? renderFormattedPayloadDate(date) : null }).then(() => { captureIssueEvent({ eventName: ISSUE_UPDATED, payload: { ...issue, state: "SUCCESS", element: currentLayout }, path: router.asPath, updates: { changed_property: "start_date", change_details: date ? renderFormattedPayloadDate(date) : null, }, }); }); }; const handleTargetDate = (date: Date | null) => { handleIssues({ ...issue, target_date: date ? renderFormattedPayloadDate(date) : null }).then(() => { captureIssueEvent({ eventName: ISSUE_UPDATED, payload: { ...issue, state: "SUCCESS", element: currentLayout }, path: router.asPath, updates: { changed_property: "target_date", change_details: date ? renderFormattedPayloadDate(date) : null, }, }); }); }; const handleEstimate = (value: number | null) => { handleIssues({ ...issue, estimate_point: value }).then(() => { captureIssueEvent({ eventName: ISSUE_UPDATED, payload: { ...issue, state: "SUCCESS", element: currentLayout }, path: router.asPath, updates: { changed_property: "estimate_point", change_details: value, }, }); }); }; const redirectToIssueDetail = () => { router.push({ pathname: `/${workspaceSlug}/projects/${issue.project_id}/${issue.archived_at ? "archived-issues" : "issues"}/${ issue.id }`, hash: "sub-issues", }); }; if (!displayProperties) return null; const defaultLabelOptions = issue?.label_ids?.map((id) => labelMap[id]) || []; const minDate = issue.start_date ? new Date(issue.start_date) : null; minDate?.setDate(minDate.getDate()); const maxDate = issue.target_date ? new Date(issue.target_date) : null; maxDate?.setDate(maxDate.getDate()); return (
{/* basic properties */} {/* state */}
{/* priority */}
{/* label */} {/* start date */}
} maxDate={maxDate ?? undefined} placeholder="Start date" buttonVariant={issue.start_date ? "border-with-text" : "border-without-text"} disabled={isReadOnly} showTooltip />
{/* target/due date */}
} minDate={minDate ?? undefined} placeholder="Due date" buttonVariant={issue.target_date ? "border-with-text" : "border-without-text"} disabled={isReadOnly} showTooltip />
{/* assignee */}
0 ? "transparent-without-text" : "border-without-text"} buttonClassName={issue.assignee_ids?.length > 0 ? "hover:bg-transparent px-0" : ""} />
{/* estimates */} {areEstimatesEnabledForCurrentProject && (
)} {/* extra render properties */} {/* sub-issues */}
{issue.sub_issues_count}
{/* attachments */}
{issue.attachment_count}
{/* link */}
{issue.link_count}
); });