make all the timestamp local time and hovering shows UTC timestamp (#1164)
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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} />
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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>
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -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} />
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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 };
|
||||||
|
|||||||
@@ -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 };
|
||||||
|
|||||||
Reference in New Issue
Block a user