Skip to content

Commit

Permalink
[WEB-761] fix: Time zone date misalignment (#3986)
Browse files Browse the repository at this point in the history
* fix date time misalignment

* fix failing build

* fix gantt chart view position fix

* comments for getDate method

* remove new Date() where not required

* changes from my self review
  • Loading branch information
rahulramesha authored Mar 19, 2024
1 parent aa3702c commit 1a46271
Show file tree
Hide file tree
Showing 41 changed files with 303 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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()}`}
/>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ export const InfoPopover: React.FC<Props> = (props) => {
<h6 className="text-xs text-custom-text-400">Last updated on</h6>
<h5 className="flex items-center gap-1 text-sm">
<History className="h-3 w-3" />
{renderDate(new Date(documentDetails.last_updated_at))}
{renderDate(documentDetails.last_updated_at)}
</h5>
</div>
<div className="space-y-1.5">
<h6 className="text-xs text-custom-text-400">Created on</h6>
<h5 className="flex items-center gap-1 text-sm">
<Calendar className="h-3 w-3" />
{renderDate(new Date(documentDetails.created_on))}
{renderDate(documentDetails.created_on)}
</h5>
</div>
</div>
Expand Down
65 changes: 39 additions & 26 deletions web/components/core/filters/date-filter-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { DateFilterSelect } from "./date-filter-select";
// ui
import { Button } from "@plane/ui";
// helpers
import { renderFormattedPayloadDate, renderFormattedDate } from "helpers/date-time.helper";
import { renderFormattedPayloadDate, renderFormattedDate, getDate } from "helpers/date-time.helper";

type Props = {
title: string;
Expand Down Expand Up @@ -43,7 +43,10 @@ export const DateFilterModal: React.FC<Props> = ({ title, handleClose, isOpen, o
handleClose();
};

const isInvalid = watch("filterType") === "range" ? new Date(watch("date1")) > new Date(watch("date2")) : false;
const date1 = getDate(watch("date1"));
const date2 = getDate(watch("date1"));

const isInvalid = watch("filterType") === "range" && date1 && date2 ? date1 > date2 : false;

return (
<Transition.Root show={isOpen} as={Fragment}>
Expand Down Expand Up @@ -86,35 +89,45 @@ export const DateFilterModal: React.FC<Props> = ({ title, handleClose, isOpen, o
<Controller
control={control}
name="date1"
render={({ field: { value, onChange } }) => (
<DayPicker
selected={value ? new Date(value) : undefined}
defaultMonth={value ? new Date(value) : undefined}
onSelect={(date) => onChange(date)}
mode="single"
disabled={[
{ after: new Date(watch("date2")) }
]}
className="border border-custom-border-200 p-3 rounded-md"
/>
)}
render={({ field: { value, onChange } }) => {
const dateValue = getDate(value);
const date2Value = getDate(watch("date2"));
return (
<DayPicker
selected={dateValue}
defaultMonth={dateValue}
onSelect={(date) => {
if (!date) return;
onChange(date);
}}
mode="single"
disabled={date2Value ? [{ after: date2Value }] : undefined}
className="border border-custom-border-200 p-3 rounded-md"
/>
);
}}
/>
{watch("filterType") === "range" && (
<Controller
control={control}
name="date2"
render={({ field: { value, onChange } }) => (
<DayPicker
selected={value ? new Date(value) : undefined}
defaultMonth={value ? new Date(value) : undefined}
onSelect={(date) => onChange(date)}
mode="single"
disabled={[
{ before: new Date(watch("date1")) }
]}
className="border border-custom-border-200 p-3 rounded-md"
/>
)}
render={({ field: { value, onChange } }) => {
const dateValue = getDate(value);
const date1Value = getDate(watch("date1"));
return (
<DayPicker
selected={dateValue}
defaultMonth={dateValue}
onSelect={(date) => {
if (!date) return;
onChange(date);
}}
mode="single"
disabled={date1Value ? [{ before: date1Value }] : undefined}
className="border border-custom-border-200 p-3 rounded-md"
/>
);
}}
/>
)}
</div>
Expand Down
8 changes: 4 additions & 4 deletions web/components/core/sidebar/progress-chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -47,11 +47,11 @@ const ProgressChart: React.FC<Props> = ({ 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 });
}

Expand Down
17 changes: 10 additions & 7 deletions web/components/cycles/active-cycle-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ import { EmptyState, getEmptyStateImagePath } 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";
// types
import { ICycle, TCycleGroups } from "@plane/types";
Expand Down Expand Up @@ -102,8 +107,10 @@ export const ActiveCycleDetails: React.FC<IActiveCycleDetails> = 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;

const groupedIssues: any = {
backlog: activeCycle.backlog_issues,
Expand All @@ -113,8 +120,6 @@ export const ActiveCycleDetails: React.FC<IActiveCycleDetails> = observer((props
cancelled: activeCycle.cancelled_issues,
};

const cycleStatus = activeCycle.status.toLowerCase() as TCycleGroups;

const handleAddToFavorites = (e: MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
if (!workspaceSlug || !projectId) return;
Expand Down Expand Up @@ -151,8 +156,6 @@ export const ActiveCycleDetails: React.FC<IActiveCycleDetails> = observer((props
color: group.color,
}));

const daysLeft = findHowManyDaysLeft(activeCycle.end_date) ?? 0;

return (
<div className="grid-row-2 grid divide-y rounded-[10px] border border-custom-border-200 bg-custom-background-100 shadow">
<div className="grid grid-cols-1 divide-y border-custom-border-200 lg:grid-cols-3 lg:divide-x lg:divide-y-0">
Expand Down
6 changes: 3 additions & 3 deletions web/components/cycles/cycles-board-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Avatar, AvatarGroup, CustomMenu, Tooltip, LayersIcon, CycleGroupIcon }
// icons
import { Info, LinkIcon, Pencil, Star, Trash2 } from "lucide-react";
// helpers
import { findHowManyDaysLeft, renderFormattedDate } from "helpers/date-time.helper";
import { findHowManyDaysLeft, getDate, renderFormattedDate } from "helpers/date-time.helper";
import { copyTextToClipboard } from "helpers/string.helper";
// constants
import { CYCLE_STATUS } from "constants/cycle";
Expand Down Expand Up @@ -50,8 +50,8 @@ export const CyclesBoardCard: FC<ICyclesBoardCard> = observer((props) => {

const cycleStatus = cycleDetails.status.toLocaleLowerCase();
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 isDateValid = cycleDetails.start_date || cycleDetails.end_date;

const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserWorkspaceRoles.MEMBER;
Expand Down
6 changes: 3 additions & 3 deletions web/components/cycles/cycles-list-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { CustomMenu, Tooltip, CircularProgressIndicator, CycleGroupIcon, AvatarG
// icons
import { Check, Info, LinkIcon, Pencil, Star, Trash2, User2 } from "lucide-react";
// helpers
import { findHowManyDaysLeft, renderFormattedDate } from "helpers/date-time.helper";
import { findHowManyDaysLeft, getDate, renderFormattedDate } from "helpers/date-time.helper";
import { copyTextToClipboard } from "helpers/string.helper";
// constants
import { CYCLE_STATUS } from "constants/cycle";
Expand Down Expand Up @@ -137,8 +137,8 @@ export const CyclesListItem: FC<TCyclesListItem> = 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 >= EUserWorkspaceRoles.MEMBER;

Expand Down
6 changes: 3 additions & 3 deletions web/components/cycles/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DateRangeDropdown, ProjectDropdown } from "components/dropdowns";
// ui
import { Button, Input, TextArea } from "@plane/ui";
// helpers
import { renderFormattedPayloadDate } from "helpers/date-time.helper";
import { getDate, renderFormattedPayloadDate } from "helpers/date-time.helper";
// types
import { ICycle } from "@plane/types";

Expand Down Expand Up @@ -135,8 +135,8 @@ export const CycleForm: React.FC<Props> = (props) => {
className="h-7"
minDate={new Date()}
value={{
from: startDateValue ? new Date(startDateValue) : undefined,
to: endDateValue ? new Date(endDateValue) : undefined,
from: getDate(startDateValue),
to: getDate(endDateValue),
}}
onSelect={(val) => {
onChangeStartDate(val?.from ? renderFormattedPayloadDate(val.from) : null);
Expand Down
5 changes: 3 additions & 2 deletions web/components/cycles/gantt-chart/cycles-list-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { GanttChartRoot, IBlockUpdateData, CycleGanttSidebar } from "components/
import { CycleGanttBlock } from "components/cycles";
// types
import { ICycle } from "@plane/types";
import { getDate } from "helpers/date-time.helper";
// constants
import { EUserProjectRoles } from "constants/project";

Expand Down Expand Up @@ -45,8 +46,8 @@ export const CyclesListGanttChartView: FC<Props> = 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;
Expand Down
13 changes: 8 additions & 5 deletions web/components/cycles/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import { Avatar, CustomMenu, Loader, LayersIcon } from "@plane/ui";
// icons
import { ChevronDown, LinkIcon, Trash2, UserCircle2, AlertCircle, ChevronRight, CalendarClock } from "lucide-react";
// helpers
import { findHowManyDaysLeft, getDate, renderFormattedPayloadDate } from "helpers/date-time.helper";
import { copyUrlToClipboard } from "helpers/string.helper";
import { findHowManyDaysLeft, renderFormattedPayloadDate } from "helpers/date-time.helper";
// types
import { ICycle } from "@plane/types";
// constants
Expand Down Expand Up @@ -186,8 +186,11 @@ export const CycleDetailsSidebar: React.FC<Props> = 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
Expand Down Expand Up @@ -317,8 +320,8 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
buttonVariant="background-with-text"
minDate={new Date()}
value={{
from: startDateValue ? new Date(startDateValue) : undefined,
to: endDateValue ? new Date(endDateValue) : undefined,
from: getDate(startDateValue),
to: getDate(endDateValue),
}}
onSelect={(val) => {
onChangeStartDate(val?.from ? renderFormattedPayloadDate(val.from) : null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useIssueDetail, useMember, useProject } from "hooks/store";
// 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";
// types
import { TIssue, TWidgetIssue } from "@plane/types";

Expand Down Expand Up @@ -34,6 +34,8 @@ export const AssignedUpcomingIssueListItem: React.FC<IssueListItemProps> = obser
const blockedByIssueProjectDetails =
blockedByIssues.length === 1 ? getProjectById(blockedByIssues[0]?.project_id ?? "") : null;

const targetDate = getDate(issueDetails.target_date);

return (
<ControlLink
href={`/${workspaceSlug}/projects/${issueDetails.project_id}/issues/${issueDetails.id}`}
Expand All @@ -48,11 +50,7 @@ export const AssignedUpcomingIssueListItem: React.FC<IssueListItemProps> = obser
<h6 className="text-sm flex-grow truncate">{issueDetails.name}</h6>
</div>
<div className="text-xs text-center">
{issueDetails.target_date
? isToday(new Date(issueDetails.target_date))
? "Today"
: renderFormattedDate(issueDetails.target_date)
: "-"}
{targetDate ? (isToday(targetDate) ? "Today" : renderFormattedDate(targetDate)) : "-"}
</div>
<div className="text-xs text-center">
{blockedByIssues.length > 0
Expand Down Expand Up @@ -83,7 +81,7 @@ export const AssignedOverdueIssueListItem: React.FC<IssueListItemProps> = 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 (
<ControlLink
Expand Down Expand Up @@ -212,7 +210,7 @@ export const CreatedOverdueIssueListItem: React.FC<IssueListItemProps> = 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 (
<ControlLink
Expand Down
6 changes: 3 additions & 3 deletions web/components/dropdowns/date.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import useOutsideClickDetector from "hooks/use-outside-click-detector";
// components
import { DropdownButton } from "./buttons";
// helpers
import { renderFormattedDate } from "helpers/date-time.helper";
import { getDate, renderFormattedDate } from "helpers/date-time.helper";
import { cn } from "helpers/common.helper";
// types
import { TDropdownProps } from "./types";
Expand Down Expand Up @@ -168,8 +168,8 @@ export const DateDropdown: React.FC<Props> = (props) => {
{...attributes.popper}
>
<DayPicker
selected={value ? new Date(value) : undefined}
defaultMonth={value ? new Date(value) : undefined}
selected={getDate(value)}
defaultMonth={getDate(value)}
onSelect={(date) => {
dropdownOnChange(date ?? null);
}}
Expand Down
5 changes: 3 additions & 2 deletions web/components/exporter/single-export.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -18,7 +18,8 @@ export const SingleExport: FC<Props> = ({ 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;
};
Expand Down
4 changes: 2 additions & 2 deletions web/components/gantt-chart/chart/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ export const ChartViewRoot: FC<ChartViewRootProps> = observer((props) => {
useGanttChart();

// rendering the block structure
const renderBlockStructure = (view: any, blocks: IGanttBlock[] | null) =>
const renderBlockStructure = (view: ChartDataType, blocks: IGanttBlock[] | null) =>
blocks
? blocks.map((block: any) => ({
? blocks.map((block: IGanttBlock) => ({
...block,
position: getMonthChartItemPositionWidthInMonth(view, block),
}))
Expand Down
Loading

0 comments on commit 1a46271

Please sign in to comment.