From d54b9d45f665d5f19a269919c4af5b9bd63a06e5 Mon Sep 17 00:00:00 2001 From: vamsikrishnamathala Date: Thu, 27 Mar 2025 14:43:08 +0530 Subject: [PATCH] feat: added dates display in user timezone in analytics sidebar --- .../analytics-sidebar/sidebar-header.tsx | 83 +++++++++++++------ 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/web/core/components/cycles/analytics-sidebar/sidebar-header.tsx b/web/core/components/cycles/analytics-sidebar/sidebar-header.tsx index a41be6752ca..462ad21233e 100644 --- a/web/core/components/cycles/analytics-sidebar/sidebar-header.tsx +++ b/web/core/components/cycles/analytics-sidebar/sidebar-header.tsx @@ -3,7 +3,15 @@ import React, { FC, useEffect, useState } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; -import { ArchiveIcon, ArchiveRestoreIcon, ChevronRight, EllipsisIcon, LinkIcon, Trash2 } from "lucide-react"; +import { + ArchiveIcon, + ArchiveRestoreIcon, + ArrowRight, + ChevronRight, + EllipsisIcon, + LinkIcon, + Trash2, +} from "lucide-react"; // types import { CYCLE_STATUS, CYCLE_UPDATED, EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; @@ -20,6 +28,7 @@ import { useCycle, useEventTracker, useUserPermissions } from "@/hooks/store"; import { useAppRouter } from "@/hooks/use-app-router"; // plane web constants // services +import { useTimeZoneConverter } from "@/hooks/use-timezone-converter"; import { CycleService } from "@/services/cycle.service"; // local components import { ArchiveCycleModal } from "../archived-cycles"; @@ -52,6 +61,10 @@ export const CycleSidebarHeader: FC = observer((props) => { const { updateCycleDetails, restoreCycle } = useCycle(); const { setTrackElement, captureCycleEvent } = useEventTracker(); const { t } = useTranslation(); + const { renderFormattedDateInUserTimezone, getProjectUTCOffset } = useTimeZoneConverter(projectId); + + // derived values + const projectUTCOffset = getProjectUTCOffset(); // form info const { control, reset } = useForm({ @@ -289,34 +302,50 @@ export const CycleSidebarHeader: FC = observer((props) => { control={control} name="start_date" render={({ field: { value: startDateValue, onChange: onChangeStartDate } }) => ( - ( - { - const isDateValid = await handleDateChange(val?.from, val?.to); - if (isDateValid) { - onChangeStartDate(val?.from ? renderFormattedPayloadDate(val.from) : null); - onChangeEndDate(val?.to ? renderFormattedPayloadDate(val.to) : null); +
+ ( + { + const isDateValid = await handleDateChange(val?.from, val?.to); + if (isDateValid) { + onChangeStartDate(val?.from ? renderFormattedPayloadDate(val.from) : null); + onChangeEndDate(val?.to ? renderFormattedPayloadDate(val.to) : null); + } + }} + placeholder={{ + from: t("project_cycles.start_date"), + to: t("project_cycles.end_date"), + }} + customTooltipHeading={t("project_cycles.in_your_timezone")} + customTooltipContent={ + + {renderFormattedDateInUserTimezone(cycleDetails.start_date ?? "")} + + {renderFormattedDateInUserTimezone(cycleDetails.end_date ?? "")} + } - }} - placeholder={{ - from: "Start date", - to: "End date", - }} - required={cycleDetails.status !== "draft"} - disabled={!isEditingAllowed || isArchived || isCompleted} - /> + showTooltip={!!cycleDetails.start_date && !!cycleDetails.end_date} // show tooltip only if both start and end date are present + required={cycleDetails.status !== "draft"} + disabled={!isEditingAllowed || isArchived || isCompleted} + /> + )} + /> + {projectUTCOffset && ( + + {projectUTCOffset} + )} - /> +
)} />