From 80a4a5dd626254c7818598b666354dd97712bc60 Mon Sep 17 00:00:00 2001 From: rahulramesha Date: Fri, 15 Mar 2024 16:07:20 +0530 Subject: [PATCH] fix date time misalignment --- .../src/ui/components/editor-header.tsx | 2 +- .../src/ui/components/info-popover.tsx | 4 +- .../core/filters/date-filter-modal.tsx | 62 +++++++++++-------- .../core/sidebar/progress-chart.tsx | 8 +-- web/components/cycles/active-cycle/root.tsx | 11 +++- .../cycles/board/cycles-board-card.tsx | 6 +- web/components/cycles/form.tsx | 6 +- .../cycles/gantt-chart/cycles-list-layout.tsx | 5 +- .../cycles/list/cycles-list-item.tsx | 6 +- web/components/cycles/sidebar.tsx | 13 ++-- .../widgets/issue-panels/issue-list-item.tsx | 14 ++--- web/components/dropdowns/date.tsx | 6 +- web/components/exporter/single-export.tsx | 17 ++--- web/components/gantt-chart/types/index.ts | 4 +- web/components/inbox/inbox-issue-actions.tsx | 28 +++++---- .../issues/issue-detail/inbox/sidebar.tsx | 4 +- .../issues/issue-detail/sidebar.tsx | 6 +- .../calendar/dropdowns/months-dropdown.tsx | 8 ++- .../properties/all-properties.tsx | 6 +- .../spreadsheet/columns/due-date-column.tsx | 4 +- .../spreadsheet/columns/start-date-column.tsx | 4 +- web/components/issues/issue-modal/form.tsx | 6 +- .../issues/peek-overview/properties.tsx | 6 +- web/components/modules/form.tsx | 6 +- .../gantt-chart/modules-list-layout.tsx | 5 +- web/components/modules/module-card-item.tsx | 10 +-- web/components/modules/module-list-item.tsx | 6 +- web/components/modules/sidebar.tsx | 52 +++++++++------- .../notifications/notification-card.tsx | 2 +- .../select-snooze-till-modal.tsx | 4 +- web/contexts/user-notification-context.tsx | 4 +- web/helpers/cycle.helper.ts | 9 +-- web/helpers/date-time.helper.ts | 56 +++++++++++------ web/helpers/filter.helper.ts | 8 ++- web/helpers/issue.helper.ts | 9 ++- web/helpers/module.helper.ts | 10 +-- .../projects/[projectId]/pages/[pageId].tsx | 3 +- web/store/cycle.store.ts | 13 ++-- web/store/project-page.store.ts | 20 +++--- 39 files changed, 258 insertions(+), 195 deletions(-) diff --git a/packages/editor/document-editor/src/ui/components/editor-header.tsx b/packages/editor/document-editor/src/ui/components/editor-header.tsx index a322ddddc..aaa4c7be3 100644 --- a/packages/editor/document-editor/src/ui/components/editor-header.tsx +++ b/packages/editor/document-editor/src/ui/components/editor-header.tsx @@ -72,7 +72,7 @@ export const EditorHeader = (props: IEditorHeader) => { Icon={Archive} backgroundColor="bg-blue-500/20" textColor="text-blue-500" - label={`Archived at ${new Date(archivedAt).toLocaleString()}`} + label={`Archived at ${archivedAt.toLocaleString()}`} /> )} diff --git a/packages/editor/document-editor/src/ui/components/info-popover.tsx b/packages/editor/document-editor/src/ui/components/info-popover.tsx index f78dd3473..9a17a9376 100644 --- a/packages/editor/document-editor/src/ui/components/info-popover.tsx +++ b/packages/editor/document-editor/src/ui/components/info-popover.tsx @@ -52,14 +52,14 @@ export const InfoPopover: React.FC = (props) => {
Last updated on
- {renderDate(new Date(documentDetails.last_updated_at))} + {renderDate(documentDetails.last_updated_at)}
Created on
- {renderDate(new Date(documentDetails.created_on))} + {renderDate(documentDetails.created_on)}
diff --git a/web/components/core/filters/date-filter-modal.tsx b/web/components/core/filters/date-filter-modal.tsx index d1eedc749..95fb0759e 100644 --- a/web/components/core/filters/date-filter-modal.tsx +++ b/web/components/core/filters/date-filter-modal.tsx @@ -7,7 +7,7 @@ import { X } from "lucide-react"; // ui import { Button } from "@plane/ui"; // helpers -import { renderFormattedPayloadDate, renderFormattedDate } from "helpers/date-time.helper"; +import { renderFormattedPayloadDate, renderFormattedDate, getDate } from "helpers/date-time.helper"; import { DateFilterSelect } from "./date-filter-select"; type Props = { @@ -44,10 +44,10 @@ export const DateFilterModal: React.FC = ({ title, handleClose, isOpen, o handleClose(); }; - const date1 = watch("date1"); - const date2 = watch("date2"); + const date1 = getDate(watch("date1")); + const date2 = getDate(watch("date1")); - const isInvalid = watch("filterType") === "range" ? new Date(date1) > new Date(date2) : false; + const isInvalid = watch("filterType") === "range" && date1 && date2 ? date1 > date2 : false; return ( @@ -90,37 +90,45 @@ export const DateFilterModal: React.FC = ({ title, handleClose, isOpen, o ( - { - if (!date) return; - onChange(date); - }} - mode="single" - disabled={[{ after: new Date(watch("date2")) }]} - className="border border-custom-border-200 p-3 rounded-md" - /> - )} - /> - {watch("filterType") === "range" && ( - ( + render={({ field: { value, onChange } }) => { + const dateValue = getDate(value); + const date2Value = getDate(watch("date2")); + return ( { if (!date) return; onChange(date); }} mode="single" - disabled={[{ before: new Date(watch("date1")) }]} + disabled={date2Value ? [{ after: date2Value }] : undefined} className="border border-custom-border-200 p-3 rounded-md" /> - )} + ); + }} + /> + {watch("filterType") === "range" && ( + { + const dateValue = getDate(value); + const date1Value = getDate(watch("date1")); + return ( + { + if (!date) return; + onChange(date); + }} + mode="single" + disabled={date1Value ? [{ before: date1Value }] : undefined} + className="border border-custom-border-200 p-3 rounded-md" + /> + ); + }} /> )} diff --git a/web/components/core/sidebar/progress-chart.tsx b/web/components/core/sidebar/progress-chart.tsx index ca21756fc..b0ff4ba73 100644 --- a/web/components/core/sidebar/progress-chart.tsx +++ b/web/components/core/sidebar/progress-chart.tsx @@ -3,7 +3,7 @@ import { eachDayOfInterval, isValid } from "date-fns"; // ui import { LineGraph } from "components/ui"; // helpers -import { renderFormattedDateWithoutYear } from "helpers/date-time.helper"; +import { getDate, renderFormattedDateWithoutYear } from "helpers/date-time.helper"; //types import { TCompletionChartDistribution } from "@plane/types"; @@ -47,11 +47,11 @@ const ProgressChart: React.FC = ({ distribution, startDate, endDate, tota })); const generateXAxisTickValues = () => { - const start = new Date(startDate); - const end = new Date(endDate); + const start = getDate(startDate); + const end = getDate(endDate); let dates: Date[] = []; - if (isValid(start) && isValid(end)) { + if (start && end && isValid(start) && isValid(end)) { dates = eachDayOfInterval({ start, end }); } diff --git a/web/components/cycles/active-cycle/root.tsx b/web/components/cycles/active-cycle/root.tsx index dd5d65f7e..7d824d96e 100644 --- a/web/components/cycles/active-cycle/root.tsx +++ b/web/components/cycles/active-cycle/root.tsx @@ -28,7 +28,12 @@ import { EmptyState } from "components/empty-state"; // icons import { ArrowRight, CalendarCheck, CalendarDays, Star, Target } from "lucide-react"; // helpers -import { renderFormattedDate, findHowManyDaysLeft, renderFormattedDateWithoutYear } from "helpers/date-time.helper"; +import { + renderFormattedDate, + findHowManyDaysLeft, + renderFormattedDateWithoutYear, + getDate, +} from "helpers/date-time.helper"; import { truncateText } from "helpers/string.helper"; import { cn } from "helpers/common.helper"; // types @@ -124,8 +129,8 @@ export const ActiveCycleRoot: React.FC = observer((props) = ); } - const endDate = new Date(activeCycle.end_date ?? ""); - const startDate = new Date(activeCycle.start_date ?? ""); + const endDate = getDate(activeCycle.end_date); + const startDate = getDate(activeCycle.start_date); const daysLeft = findHowManyDaysLeft(activeCycle.end_date) ?? 0; const cycleStatus = activeCycle.status.toLowerCase() as TCycleGroups; diff --git a/web/components/cycles/board/cycles-board-card.tsx b/web/components/cycles/board/cycles-board-card.tsx index c8ac630e7..6f9db3066 100644 --- a/web/components/cycles/board/cycles-board-card.tsx +++ b/web/components/cycles/board/cycles-board-card.tsx @@ -14,7 +14,7 @@ import { CycleQuickActions } from "components/cycles"; import { CYCLE_STATUS } from "constants/cycle"; import { CYCLE_FAVORITED, CYCLE_UNFAVORITED } from "constants/event-tracker"; import { EUserWorkspaceRoles } from "constants/workspace"; -import { findHowManyDaysLeft, renderFormattedDate } from "helpers/date-time.helper"; +import { findHowManyDaysLeft, getDate, renderFormattedDate } from "helpers/date-time.helper"; // constants import { useEventTracker, useCycle, useUser, useMember } from "hooks/store"; //.types @@ -45,8 +45,8 @@ export const CyclesBoardCard: FC = observer((props) => { if (!cycleDetails) return null; const cycleStatus = cycleDetails.status.toLocaleLowerCase(); - const endDate = new Date(cycleDetails.end_date ?? ""); - const startDate = new Date(cycleDetails.start_date ?? ""); + const endDate = getDate(cycleDetails.end_date); + const startDate = getDate(cycleDetails.start_date); const isDateValid = cycleDetails.start_date || cycleDetails.end_date; const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserWorkspaceRoles.MEMBER; diff --git a/web/components/cycles/form.tsx b/web/components/cycles/form.tsx index 4e2f55ef9..c711a9a41 100644 --- a/web/components/cycles/form.tsx +++ b/web/components/cycles/form.tsx @@ -5,7 +5,7 @@ import { Button, Input, TextArea } from "@plane/ui"; import { DateRangeDropdown, ProjectDropdown } from "components/dropdowns"; // ui // helpers -import { renderFormattedPayloadDate } from "helpers/date-time.helper"; +import { getDate, renderFormattedPayloadDate } from "helpers/date-time.helper"; // types import { ICycle } from "@plane/types"; @@ -135,8 +135,8 @@ export const CycleForm: React.FC = (props) => { className="h-7" minDate={new Date()} value={{ - from: startDateValue ? new Date(startDateValue) : undefined, - to: endDateValue ? new Date(endDateValue) : undefined, + from: startDateValue ? getDate(startDateValue) : undefined, + to: endDateValue ? getDate(endDateValue) : undefined, }} onSelect={(val) => { onChangeStartDate(val?.from ? renderFormattedPayloadDate(val.from) : null); diff --git a/web/components/cycles/gantt-chart/cycles-list-layout.tsx b/web/components/cycles/gantt-chart/cycles-list-layout.tsx index 094fbea7b..6c439331d 100644 --- a/web/components/cycles/gantt-chart/cycles-list-layout.tsx +++ b/web/components/cycles/gantt-chart/cycles-list-layout.tsx @@ -8,6 +8,7 @@ import { useCycle } from "hooks/store"; // components // types import { ICycle } from "@plane/types"; +import { getDate } from "helpers/date-time.helper"; // constants type Props = { @@ -41,8 +42,8 @@ export const CyclesListGanttChartView: FC = observer((props) => { data: block, id: block?.id ?? "", sort_order: block?.sort_order ?? 0, - start_date: new Date(block?.start_date ?? ""), - target_date: new Date(block?.end_date ?? ""), + start_date: getDate(block?.start_date), + target_date: getDate(block?.end_date), })); return structuredBlocks; diff --git a/web/components/cycles/list/cycles-list-item.tsx b/web/components/cycles/list/cycles-list-item.tsx index 8a5cee535..d01a1974a 100644 --- a/web/components/cycles/list/cycles-list-item.tsx +++ b/web/components/cycles/list/cycles-list-item.tsx @@ -9,7 +9,7 @@ import { Tooltip, CircularProgressIndicator, CycleGroupIcon, AvatarGroup, Avatar import { CycleQuickActions } from "components/cycles"; import { CYCLE_STATUS } from "constants/cycle"; import { CYCLE_FAVORITED, CYCLE_UNFAVORITED } from "constants/event-tracker"; -import { findHowManyDaysLeft, renderFormattedDate } from "helpers/date-time.helper"; +import { findHowManyDaysLeft, getDate, renderFormattedDate } from "helpers/date-time.helper"; import { useEventTracker, useCycle, useUser, useMember } from "hooks/store"; // components // ui @@ -119,8 +119,8 @@ export const CyclesListItem: FC = observer((props) => { // TODO: change this logic once backend fix the response const cycleStatus = cycleDetails.status ? (cycleDetails.status.toLocaleLowerCase() as TCycleGroups) : "draft"; const isCompleted = cycleStatus === "completed"; - const endDate = new Date(cycleDetails.end_date ?? ""); - const startDate = new Date(cycleDetails.start_date ?? ""); + const endDate = getDate(cycleDetails.end_date); + const startDate = getDate(cycleDetails.start_date); const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER; diff --git a/web/components/cycles/sidebar.tsx b/web/components/cycles/sidebar.tsx index bdbe206fc..80f3f2f36 100644 --- a/web/components/cycles/sidebar.tsx +++ b/web/components/cycles/sidebar.tsx @@ -18,7 +18,7 @@ import { CYCLE_STATUS } from "constants/cycle"; import { CYCLE_UPDATED } from "constants/event-tracker"; import { EUserWorkspaceRoles } from "constants/workspace"; // helpers -import { findHowManyDaysLeft, renderFormattedPayloadDate } from "helpers/date-time.helper"; +import { findHowManyDaysLeft, getDate, renderFormattedPayloadDate } from "helpers/date-time.helper"; import { copyUrlToClipboard } from "helpers/string.helper"; // hooks import { useEventTracker, useCycle, useUser, useMember } from "hooks/store"; @@ -182,8 +182,11 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { const cycleStatus = cycleDetails?.status.toLocaleLowerCase(); const isCompleted = cycleStatus === "completed"; - const isStartValid = new Date(`${cycleDetails?.start_date}`) <= new Date(); - const isEndValid = new Date(`${cycleDetails?.end_date}`) >= new Date(`${cycleDetails?.start_date}`); + const startDate = getDate(cycleDetails?.start_date); + const endDate = getDate(cycleDetails?.end_date); + + const isStartValid = startDate && startDate <= new Date(); + const isEndValid = endDate && startDate && endDate >= startDate; const progressPercentage = cycleDetails ? isCompleted && cycleDetails?.progress_snapshot @@ -313,8 +316,8 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { buttonVariant="background-with-text" minDate={new Date()} value={{ - from: startDateValue ? new Date(startDateValue) : undefined, - to: endDateValue ? new Date(endDateValue) : undefined, + from: startDateValue ? getDate(startDateValue) : undefined, + to: endDateValue ? getDate(endDateValue) : undefined, }} onSelect={(val) => { onChangeStartDate(val?.from ? renderFormattedPayloadDate(val.from) : null); diff --git a/web/components/dashboard/widgets/issue-panels/issue-list-item.tsx b/web/components/dashboard/widgets/issue-panels/issue-list-item.tsx index a5279f715..0e30f820b 100644 --- a/web/components/dashboard/widgets/issue-panels/issue-list-item.tsx +++ b/web/components/dashboard/widgets/issue-panels/issue-list-item.tsx @@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite"; // ui import { Avatar, AvatarGroup, ControlLink, PriorityIcon } from "@plane/ui"; // helpers -import { findTotalDaysInRange, renderFormattedDate } from "helpers/date-time.helper"; +import { findTotalDaysInRange, getDate, renderFormattedDate } from "helpers/date-time.helper"; import { useIssueDetail, useMember, useProject } from "hooks/store"; // types import { TIssue, TWidgetIssue } from "@plane/types"; @@ -34,6 +34,8 @@ export const AssignedUpcomingIssueListItem: React.FC = obser const blockedByIssueProjectDetails = blockedByIssues.length === 1 ? getProjectById(blockedByIssues[0]?.project_id ?? "") : null; + const targetDate = getDate(issueDetails.target_date); + return ( = obser
{issueDetails.name}
- {issueDetails.target_date - ? isToday(new Date(issueDetails.target_date)) - ? "Today" - : renderFormattedDate(issueDetails.target_date) - : "-"} + {targetDate ? (isToday(targetDate) ? "Today" : renderFormattedDate(targetDate)) : "-"}
{blockedByIssues.length > 0 @@ -83,7 +81,7 @@ export const AssignedOverdueIssueListItem: React.FC = observ const blockedByIssueProjectDetails = blockedByIssues.length === 1 ? getProjectById(blockedByIssues[0]?.project_id ?? "") : null; - const dueBy = findTotalDaysInRange(new Date(issueDetails.target_date ?? ""), new Date(), false) ?? 0; + const dueBy = findTotalDaysInRange(getDate(issueDetails.target_date), new Date(), false) ?? 0; return ( = observe const projectDetails = getProjectById(issue.project_id); - const dueBy = findTotalDaysInRange(new Date(issue.target_date ?? ""), new Date(), false) ?? 0; + const dueBy = findTotalDaysInRange(getDate(issue.target_date), new Date(), false) ?? 0; return ( = (props) => { {...attributes.popper} > { dropdownOnChange(date ?? null); }} diff --git a/web/components/exporter/single-export.tsx b/web/components/exporter/single-export.tsx index 4fdcb4a15..bd73824cf 100644 --- a/web/components/exporter/single-export.tsx +++ b/web/components/exporter/single-export.tsx @@ -2,7 +2,7 @@ import { useState, FC } from "react"; // ui import { Button } from "@plane/ui"; // helpers -import { renderFormattedDate } from "helpers/date-time.helper"; +import { getDate, renderFormattedDate } from "helpers/date-time.helper"; // types import { IExportData } from "@plane/types"; @@ -18,7 +18,8 @@ export const SingleExport: FC = ({ service, refreshing }) => { const checkExpiry = (inputDateString: string) => { const currentDate = new Date(); - const expiryDate = new Date(inputDateString); + const expiryDate = getDate(inputDateString); + if (!expiryDate) return false; expiryDate.setDate(expiryDate.getDate() + 7); return expiryDate > currentDate; }; @@ -38,12 +39,12 @@ export const SingleExport: FC = ({ service, refreshing }) => { service.status === "completed" ? "bg-green-500/20 text-green-500" : service.status === "processing" - ? "bg-yellow-500/20 text-yellow-500" - : service.status === "failed" - ? "bg-red-500/20 text-red-500" - : service.status === "expired" - ? "bg-orange-500/20 text-orange-500" - : "" + ? "bg-yellow-500/20 text-yellow-500" + : service.status === "failed" + ? "bg-red-500/20 text-red-500" + : service.status === "expired" + ? "bg-orange-500/20 text-orange-500" + : "" }`} > {refreshing ? "Refreshing..." : service.status} diff --git a/web/components/gantt-chart/types/index.ts b/web/components/gantt-chart/types/index.ts index 6268e4363..cd90758fc 100644 --- a/web/components/gantt-chart/types/index.ts +++ b/web/components/gantt-chart/types/index.ts @@ -6,8 +6,8 @@ export interface IGanttBlock { width: number; }; sort_order: number; - start_date: Date | null; - target_date: Date | null; + start_date: Date | undefined; + target_date: Date | undefined; } export interface IBlockUpdateData { diff --git a/web/components/inbox/inbox-issue-actions.tsx b/web/components/inbox/inbox-issue-actions.tsx index 661bc2d72..57fecbe18 100644 --- a/web/components/inbox/inbox-issue-actions.tsx +++ b/web/components/inbox/inbox-issue-actions.tsx @@ -20,6 +20,8 @@ import { EUserProjectRoles } from "constants/project"; import { useUser, useInboxIssues, useIssueDetail, useWorkspace, useEventTracker } from "hooks/store"; // types import type { TInboxDetailedStatus } from "@plane/types"; +//helpers +import { getDate } from "helpers/date-time.helper"; type TInboxIssueActionsHeader = { workspaceSlug: string; @@ -168,11 +170,11 @@ export const InboxIssueActionsHeader: FC = observer((p const isAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER; const today = new Date(); - const tomorrow = new Date(today); - tomorrow.setDate(today.getDate() + 1); + const tomorrow = getDate(today); + tomorrow?.setDate(today.getDate() + 1); useEffect(() => { if (!issueStatus || !issueStatus.snoozed_till) return; - setDate(new Date(issueStatus.snoozed_till)); + setDate(issueStatus.snoozed_till); }, [issueStatus]); if (!issueStatus || !issue || !inboxIssues) return <>; @@ -266,19 +268,23 @@ export const InboxIssueActionsHeader: FC = observer((p {({ close }) => (
{ if (!date) return; setDate(date); }} mode="single" className="rounded-md border border-custom-border-200 p-3" - disabled={[ - { - before: tomorrow, - }, - ]} + disabled={ + tomorrow + ? [ + { + before: tomorrow, + }, + ] + : undefined + } />