make all the timestamp local time and hovering shows UTC timestamp (#1164)

This commit is contained in:
Shuchang Zheng
2024-11-11 13:03:40 -08:00
committed by GitHub
parent c1c2b5ca24
commit 068535b719
10 changed files with 76 additions and 24 deletions

View File

@@ -13,7 +13,7 @@ import { ZoomableImage } from "@/components/ZoomableImage";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import { getImageURL } from "./artifactUtils"; import { getImageURL } from "./artifactUtils";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { basicTimeFormat } from "@/util/timeFormat"; import { basicLocalTimeFormat, basicTimeFormat } from "@/util/timeFormat";
import { useCredentialGetter } from "@/hooks/useCredentialGetter"; import { useCredentialGetter } from "@/hooks/useCredentialGetter";
import { Artifact } from "./Artifact"; import { Artifact } from "./Artifact";
@@ -132,7 +132,11 @@ function StepArtifacts({ id, stepProps }: Props) {
{isFetching ? ( {isFetching ? (
<Skeleton className="h-4 w-40" /> <Skeleton className="h-4 w-40" />
) : stepProps ? ( ) : stepProps ? (
<Input value={basicTimeFormat(stepProps.created_at)} readOnly /> <Input
value={basicLocalTimeFormat(stepProps.created_at)}
readOnly
title={basicTimeFormat(stepProps.created_at)}
/>
) : null} ) : null}
</div> </div>
</div> </div>

View File

@@ -2,7 +2,7 @@ import { StepApiResponse } from "@/api/types";
import { StatusBadge } from "@/components/StatusBadge"; import { StatusBadge } from "@/components/StatusBadge";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import { basicTimeFormat } from "@/util/timeFormat"; import { basicLocalTimeFormat, basicTimeFormat } from "@/util/timeFormat";
type Props = { type Props = {
isFetching: boolean; isFetching: boolean;
@@ -33,7 +33,9 @@ function StepInfo({ isFetching, stepProps }: Props) {
{isFetching ? ( {isFetching ? (
<Skeleton className="h-4 w-40" /> <Skeleton className="h-4 w-40" />
) : stepProps ? ( ) : stepProps ? (
<span>{basicTimeFormat(stepProps.created_at)}</span> <span title={basicTimeFormat(stepProps.created_at)}>
{basicLocalTimeFormat(stepProps.created_at)}
</span>
) : null} ) : null}
</div> </div>
</div> </div>

View File

@@ -22,7 +22,7 @@ import {
PaginationPrevious, PaginationPrevious,
} from "@/components/ui/pagination"; } from "@/components/ui/pagination";
import { StatusBadge } from "@/components/StatusBadge"; import { StatusBadge } from "@/components/StatusBadge";
import { basicTimeFormat } from "@/util/timeFormat"; import { basicLocalTimeFormat, basicTimeFormat } from "@/util/timeFormat";
import { cn } from "@/util/utils"; import { cn } from "@/util/utils";
import { TaskActions } from "./TaskActions"; import { TaskActions } from "./TaskActions";
@@ -120,8 +120,9 @@ function TaskHistory() {
<TableCell <TableCell
className="w-1/4 cursor-pointer" className="w-1/4 cursor-pointer"
onClick={(event) => handleNavigate(event, task.task_id)} onClick={(event) => handleNavigate(event, task.task_id)}
title={basicTimeFormat(task.created_at)}
> >
{basicTimeFormat(task.created_at)} {basicLocalTimeFormat(task.created_at)}
</TableCell> </TableCell>
<TableCell className="w-1/12"> <TableCell className="w-1/12">
<TaskActions task={task} /> <TaskActions task={task} />

View File

@@ -1,7 +1,7 @@
import { getClient } from "@/api/AxiosClient"; import { getClient } from "@/api/AxiosClient";
import { TaskApiResponse } from "@/api/types"; import { TaskApiResponse } from "@/api/types";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { basicTimeFormat } from "@/util/timeFormat"; import { basicLocalTimeFormat, basicTimeFormat } from "@/util/timeFormat";
import { import {
Table, Table,
TableBody, TableBody,
@@ -77,8 +77,11 @@ function QueuedTasks() {
<TableCell className="w-1/4"> <TableCell className="w-1/4">
<StatusBadge status={task.status} /> <StatusBadge status={task.status} />
</TableCell> </TableCell>
<TableCell className="w-1/4"> <TableCell
{basicTimeFormat(task.created_at)} className="w-1/4"
title={basicTimeFormat(task.created_at)}
>
{basicLocalTimeFormat(task.created_at)}
</TableCell> </TableCell>
</TableRow> </TableRow>
); );

View File

@@ -10,7 +10,7 @@ import {
CardHeader, CardHeader,
CardTitle, CardTitle,
} from "@/components/ui/card"; } from "@/components/ui/card";
import { basicTimeFormat } from "@/util/timeFormat"; import { basicLocalTimeFormat, basicTimeFormat } from "@/util/timeFormat";
import { LatestScreenshot } from "./LatestScreenshot"; import { LatestScreenshot } from "./LatestScreenshot";
import { useCredentialGetter } from "@/hooks/useCredentialGetter"; import { useCredentialGetter } from "@/hooks/useCredentialGetter";
@@ -70,7 +70,9 @@ function RunningTasks() {
<LatestScreenshot id={task.task_id} /> <LatestScreenshot id={task.task_id} />
</div> </div>
</CardContent> </CardContent>
<CardFooter>Created: {basicTimeFormat(task.created_at)}</CardFooter> <CardFooter title={basicTimeFormat(task.created_at)}>
Created: {basicLocalTimeFormat(task.created_at)}
</CardFooter>
</Card> </Card>
); );
}); });

View File

@@ -20,7 +20,7 @@ import {
TableRow, TableRow,
} from "@/components/ui/table"; } from "@/components/ui/table";
import { useCredentialGetter } from "@/hooks/useCredentialGetter"; import { useCredentialGetter } from "@/hooks/useCredentialGetter";
import { basicTimeFormat } from "@/util/timeFormat"; import { basicLocalTimeFormat, basicTimeFormat } from "@/util/timeFormat";
import { cn } from "@/util/utils"; import { cn } from "@/util/utils";
import { Pencil2Icon, PlayIcon } from "@radix-ui/react-icons"; import { Pencil2Icon, PlayIcon } from "@radix-ui/react-icons";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
@@ -147,8 +147,8 @@ function WorkflowPage() {
<TableCell> <TableCell>
<StatusBadge status={workflowRun.status} /> <StatusBadge status={workflowRun.status} />
</TableCell> </TableCell>
<TableCell> <TableCell title={basicTimeFormat(workflowRun.created_at)}>
{basicTimeFormat(workflowRun.created_at)} {basicLocalTimeFormat(workflowRun.created_at)}
</TableCell> </TableCell>
</TableRow> </TableRow>
)) ))

View File

@@ -32,7 +32,11 @@ import { useApiCredential } from "@/hooks/useApiCredential";
import { useCredentialGetter } from "@/hooks/useCredentialGetter"; import { useCredentialGetter } from "@/hooks/useCredentialGetter";
import { copyText } from "@/util/copyText"; import { copyText } from "@/util/copyText";
import { apiBaseUrl, envCredential } from "@/util/env"; import { apiBaseUrl, envCredential } from "@/util/env";
import { basicTimeFormat, timeFormatWithShortDate } from "@/util/timeFormat"; import {
basicLocalTimeFormat,
basicTimeFormat,
timeFormatWithShortDate,
} from "@/util/timeFormat";
import { cn } from "@/util/utils"; import { cn } from "@/util/utils";
import { import {
CopyIcon, CopyIcon,
@@ -468,8 +472,9 @@ function WorkflowRun() {
onClick={(event) => onClick={(event) =>
handleNavigate(event, task.task_id) handleNavigate(event, task.task_id)
} }
title={basicTimeFormat(task.created_at)}
> >
{basicTimeFormat(task.created_at)} {basicLocalTimeFormat(task.created_at)}
</TableCell> </TableCell>
<TableCell className="w-1/12"> <TableCell className="w-1/12">
<TaskActions task={task} /> <TaskActions task={task} />

View File

@@ -26,7 +26,7 @@ import {
TooltipTrigger, TooltipTrigger,
} from "@/components/ui/tooltip"; } from "@/components/ui/tooltip";
import { useCredentialGetter } from "@/hooks/useCredentialGetter"; import { useCredentialGetter } from "@/hooks/useCredentialGetter";
import { basicTimeFormat } from "@/util/timeFormat"; import { basicLocalTimeFormat, basicTimeFormat } from "@/util/timeFormat";
import { cn } from "@/util/utils"; import { cn } from "@/util/utils";
import { import {
ExclamationTriangleIcon, ExclamationTriangleIcon,
@@ -241,8 +241,9 @@ function Workflows() {
onClick={(event) => { onClick={(event) => {
handleRowClick(event, workflow.workflow_permanent_id); handleRowClick(event, workflow.workflow_permanent_id);
}} }}
title={basicTimeFormat(workflow.created_at)}
> >
{basicTimeFormat(workflow.created_at)} {basicLocalTimeFormat(workflow.created_at)}
</TableCell> </TableCell>
<TableCell> <TableCell>
<div className="flex justify-end gap-2"> <div className="flex justify-end gap-2">
@@ -384,8 +385,11 @@ function Workflows() {
<TableCell className="w-1/5"> <TableCell className="w-1/5">
<StatusBadge status={workflowRun.status} /> <StatusBadge status={workflowRun.status} />
</TableCell> </TableCell>
<TableCell className="w-1/5"> <TableCell
{basicTimeFormat(workflowRun.created_at)} className="w-1/5"
title={basicTimeFormat(workflowRun.created_at)}
>
{basicLocalTimeFormat(workflowRun.created_at)}
</TableCell> </TableCell>
</TableRow> </TableRow>
); );

View File

@@ -1,6 +1,6 @@
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import { useWorkflowLastRunQuery } from "../hooks/useWorkflowLastRunQuery"; import { useWorkflowLastRunQuery } from "../hooks/useWorkflowLastRunQuery";
import { basicTimeFormat } from "@/util/timeFormat"; import { basicLocalTimeFormat, basicTimeFormat } from "@/util/timeFormat";
type Props = { type Props = {
workflowId: string; workflowId: string;
@@ -21,7 +21,11 @@ function LastRunAtTime({ workflowId }: Props) {
return <span>N/A</span>; return <span>N/A</span>;
} }
return <span>{basicTimeFormat(data.time)}</span>; return (
<span title={basicTimeFormat(data.time)}>
{basicLocalTimeFormat(data.time)}
</span>
);
} }
export { LastRunAtTime }; export { LastRunAtTime };

View File

@@ -1,3 +1,30 @@
function basicLocalTimeFormat(time: string): string {
// Adjust the fractional seconds to milliseconds (3 digits)
time = time.replace(/\.(\d{3})\d*/, ".$1");
// Append 'Z' to indicate UTC time if not already present
if (!time.endsWith("Z")) {
time += "Z";
}
const date = new Date(time);
const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
// Format the date and time in the local time zone
const dateString = date.toLocaleDateString("en-US", {
weekday: "short",
year: "numeric",
month: "short",
day: "numeric",
timeZone: localTimezone,
});
const timeString = date.toLocaleTimeString("en-US", {
timeZone: localTimezone,
});
return `${dateString} at ${timeString}`;
}
function basicTimeFormat(time: string): string { function basicTimeFormat(time: string): string {
const date = new Date(time); const date = new Date(time);
const dateString = date.toLocaleDateString("en-US", { const dateString = date.toLocaleDateString("en-US", {
@@ -7,7 +34,7 @@ function basicTimeFormat(time: string): string {
day: "numeric", day: "numeric",
}); });
const timeString = date.toLocaleTimeString("en-US"); const timeString = date.toLocaleTimeString("en-US");
return `${dateString} at ${timeString}`; return `${dateString} at ${timeString} UTC`;
} }
function timeFormatWithShortDate(time: string): string { function timeFormatWithShortDate(time: string): string {
@@ -18,4 +45,4 @@ function timeFormatWithShortDate(time: string): string {
return `${dateString} at ${timeString}`; return `${dateString} at ${timeString}`;
} }
export { basicTimeFormat, timeFormatWithShortDate }; export { basicLocalTimeFormat, basicTimeFormat, timeFormatWithShortDate };