From 856802807b446c5617b306f9f38c3a54bb7758f8 Mon Sep 17 00:00:00 2001 From: Jayash Tripathy <76092296+JayashTripathy@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:10:50 +0530 Subject: [PATCH 1/2] fix: work item peek infinite loop (#7284) * fix: removed t function from dependency array which was causing infinite loop * fix: add eslint disable comment for exhaustive-deps warning in IssuePeekOverview --- web/core/components/issues/peek-overview/root.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/core/components/issues/peek-overview/root.tsx b/web/core/components/issues/peek-overview/root.tsx index 4b8448645c..062eaaa755 100644 --- a/web/core/components/issues/peek-overview/root.tsx +++ b/web/core/components/issues/peek-overview/root.tsx @@ -26,7 +26,6 @@ import { useEventTracker, useIssueDetail, useIssues, useUserPermissions } from " import { useIssueStoreType } from "@/hooks/use-issue-layout-store"; import { useWorkItemProperties } from "@/plane-web/hooks/use-issue-properties"; - export const IssuePeekOverview: FC = observer((props) => { const { embedIssue = false, @@ -335,6 +334,7 @@ export const IssuePeekOverview: FC = observer((props) => } }, }), + // eslint-disable-next-line react-hooks/exhaustive-deps [fetchIssue, is_draft, issues, fetchActivities, captureIssueEvent, pathname, removeRoutePeekId, restoreIssue] ); From 73d848696aec164896ff09c347a77f96e173e129 Mon Sep 17 00:00:00 2001 From: Vamsi Krishna <46787868+vamsikrishnamathala@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:10:06 +0530 Subject: [PATCH 2/2] [WEB-4365] fix: dates display properties toggle #7262 --- .../sub-issues/issues-list/properties.tsx | 78 +++++++++++++++++-- .../properties/all-properties.tsx | 60 +++++++++++++- 2 files changed, 131 insertions(+), 7 deletions(-) diff --git a/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx b/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx index 96ed4a2a94..92a8bc0d6a 100644 --- a/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx +++ b/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx @@ -1,12 +1,21 @@ // plane imports -import { SyntheticEvent } from "react"; +import { SyntheticEvent, useMemo } from "react"; import { observer } from "mobx-react"; +import { CalendarCheck2, CalendarClock } from "lucide-react"; +import { useTranslation } from "@plane/i18n"; import { IIssueDisplayProperties, TIssue } from "@plane/types"; -import { getDate, renderFormattedPayloadDate } from "@plane/utils"; +import { getDate, renderFormattedPayloadDate, shouldHighlightIssueDueDate } from "@plane/utils"; // components -import { PriorityDropdown, MemberDropdown, StateDropdown, DateRangeDropdown } from "@/components/dropdowns"; +import { + PriorityDropdown, + MemberDropdown, + StateDropdown, + DateRangeDropdown, + DateDropdown, +} from "@/components/dropdowns"; // hooks import { WithDisplayPropertiesHOC } from "@/components/issues/issue-layouts/properties/with-display-properties-HOC"; +import { useProjectState } from "@/hooks/store/use-project-state"; type Props = { workspaceSlug: string; @@ -27,6 +36,8 @@ type Props = { export const SubIssuesListItemProperties: React.FC = observer((props) => { const { workspaceSlug, parentIssueId, issueId, disabled, updateSubIssue, displayProperties, issue } = props; + const { t } = useTranslation(); + const { getStateById } = useProjectState(); const handleEventPropagation = (e: SyntheticEvent) => { e.stopPropagation(); @@ -49,10 +60,22 @@ export const SubIssuesListItemProperties: React.FC = observer((props) => } }; + //derived values + const stateDetails = useMemo(() => getStateById(issue.state_id), [getStateById, issue.state_id]); + const shouldHighlight = useMemo( + () => shouldHighlightIssueDueDate(issue.target_date, stateDetails?.group), + [issue.target_date, stateDetails?.group] + ); + // date range is enabled only when both dates are available and both dates are enabled + const isDateRangeEnabled: boolean = Boolean( + issue.start_date && issue.target_date && displayProperties?.start_date && displayProperties?.due_date + ); + if (!displayProperties) return <>; const maxDate = getDate(issue.target_date); - maxDate?.setDate(maxDate.getDate()); + const minDate = getDate(issue.start_date); + return (
@@ -104,7 +127,7 @@ export const SubIssuesListItemProperties: React.FC = observer((props) => !!(properties.start_date || properties.due_date)} + shouldRenderProperty={() => isDateRangeEnabled} >
= observer((props) => isClearable mergeDates buttonVariant={issue.start_date || issue.target_date ? "border-with-text" : "border-without-text"} + buttonClassName={shouldHighlight ? "text-red-500" : ""} disabled={!disabled} showTooltip customTooltipHeading="Date Range" @@ -130,6 +154,50 @@ export const SubIssuesListItemProperties: React.FC = observer((props) =>
+ {/* start date */} + !isDateRangeEnabled} + > +
+ } + buttonVariant={issue.start_date ? "border-with-text" : "border-without-text"} + optionsClassName="z-30" + disabled={!disabled} + showTooltip + /> +
+
+ + {/* target/due date */} + !isDateRangeEnabled} + > +
+ } + buttonVariant={issue.target_date ? "border-with-text" : "border-without-text"} + buttonClassName={shouldHighlight ? "text-red-500" : ""} + clearIconClassName="text-custom-text-100" + optionsClassName="z-30" + disabled={!disabled} + showTooltip + /> +
+
+
= observer((props) => { if (!displayProperties || !issue.project_id) return null; + // date range is enabled only when both dates are available and both dates are enabled + const isDateRangeEnabled: boolean = Boolean( + issue.start_date && issue.target_date && displayProperties.start_date && displayProperties.due_date + ); + const defaultLabelOptions = issue?.label_ids?.map((id) => labelMap[id]) || []; + const minDate = getDate(issue.start_date); + const maxDate = getDate(issue.target_date); + const handleEventPropagation = (e: SyntheticEvent) => { e.stopPropagation(); e.preventDefault(); @@ -306,7 +315,7 @@ export const IssueProperties: React.FC = observer((props) => { !!(properties.start_date || properties.due_date)} + shouldRenderProperty={() => isDateRangeEnabled} >
= observer((props) => { mergeDates buttonVariant={issue.start_date || issue.target_date ? "border-with-text" : "border-without-text"} buttonClassName={shouldHighlightIssueDueDate(issue.target_date, stateDetails?.group) ? "text-red-500" : ""} + clearIconClassName="!text-custom-text-100" disabled={isReadOnly} renderByDefault={isMobile} showTooltip @@ -334,6 +344,52 @@ export const IssueProperties: React.FC = observer((props) => {
+ {/* start date */} + !isDateRangeEnabled} + > +
+ } + buttonVariant={issue.start_date ? "border-with-text" : "border-without-text"} + optionsClassName="z-10" + disabled={isReadOnly} + renderByDefault={isMobile} + showTooltip + /> +
+
+ + {/* target/due date */} + !isDateRangeEnabled} + > +
+ } + buttonVariant={issue.target_date ? "border-with-text" : "border-without-text"} + buttonClassName={shouldHighlightIssueDueDate(issue.target_date, stateDetails?.group) ? "text-red-500" : ""} + clearIconClassName="!text-custom-text-100" + optionsClassName="z-10" + disabled={isReadOnly} + renderByDefault={isMobile} + showTooltip + /> +
+
+ {/* assignee */}