Skip to content

Commit 270a4d7

Browse files
committed
fix: fix truncated timestamps in sandbox logs and events and unify date formats
1 parent e1e7215 commit 270a4d7

13 files changed

Lines changed: 60 additions & 81 deletions

File tree

src/features/dashboard/billing/concurrent-sandboxes-addon-dialog.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,11 @@ function DialogContent_Inner({
142142
const limitIncreaseText = currentConcurrentSandboxesLimit ? (
143143
<>
144144
Increases total concurrent sandbox limit from{' '}
145-
<b>{currentConcurrentSandboxesLimit.toLocaleString()}</b> to{' '}
145+
<b>{currentConcurrentSandboxesLimit.toLocaleString('en-US')}</b> to{' '}
146146
<b>
147-
{(
148-
currentConcurrentSandboxesLimit + SANDBOXES_PER_ADDON
149-
).toLocaleString()}
147+
{(currentConcurrentSandboxesLimit + SANDBOXES_PER_ADDON).toLocaleString(
148+
'en-US'
149+
)}
150150
</b>
151151
</>
152152
) : (

src/features/dashboard/sandbox/events/table.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const SandboxEventsTable = ({
5353
<TableHeader className="grid sticky top-0 z-1 bg-bg">
5454
<TableRow className="flex min-w-full">
5555
<TableHead
56-
className="flex w-[174px] px-0 h-min pb-3 pr-4 text-fg"
56+
className="flex w-[190px] px-0 h-min pb-3 pr-4 text-fg"
5757
data-state="selected"
5858
>
5959
<Button
@@ -175,7 +175,7 @@ const SandboxEventRow = ({
175175
virtualizer={virtualizer}
176176
height={ROW_HEIGHT_PX}
177177
>
178-
<TableCell className="flex w-[174px] items-center px-0 py-0 pr-4">
178+
<TableCell className="flex w-[190px] items-center px-0 py-0 pr-4">
179179
{formattedTimestamp ? (
180180
<CopyButtonInline
181181
value={formattedTimestamp.iso}
Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client'
22

3+
import { Timestamp } from '@/features/dashboard/shared'
34
import CopyButton from '@/ui/copy-button'
45
import { useSandboxContext } from '../context'
56

@@ -22,31 +23,14 @@ export default function EndedAt() {
2223
return <p>N/A</p>
2324
}
2425

25-
const date = new Date(endedAt)
26-
const now = new Date()
27-
const isToday = date.toDateString() === now.toDateString()
28-
const isYesterday =
29-
date.toDateString() ===
30-
new Date(now.setDate(now.getDate() - 1)).toDateString()
31-
32-
const prefix = isToday
33-
? 'Today'
34-
: isYesterday
35-
? 'Yesterday'
36-
: date.toLocaleDateString()
37-
38-
const timeStr = date.toLocaleTimeString([], {
39-
hour: 'numeric',
40-
minute: '2-digit',
41-
second: '2-digit',
42-
})
43-
4426
return (
4527
<div className="flex items-center gap-3">
46-
<p>
47-
{prefix}, {timeStr}
48-
</p>
49-
<CopyButton value={endedAt} className="text-fg-secondary" />
28+
<Timestamp value={endedAt} />
29+
<CopyButton
30+
aria-label="Copy ended timestamp"
31+
value={endedAt}
32+
className="text-fg-secondary"
33+
/>
5034
</div>
5135
)
5236
}

src/features/dashboard/sandbox/inspect/stopped-banner.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export function StoppedBanner({ rootNodeCount }: StoppedBannerProps) {
6464
: 'Filesystem data is stale and is kept locally on your device.'}
6565
<span className="text-fg-tertiary">
6666
{' '}
67-
Last updated: {lastUpdated?.toLocaleTimeString()}
67+
Last updated: {lastUpdated?.toLocaleTimeString('en-US')}
6868
</span>
6969
</CardDescription>
7070
</CardHeader>

src/features/dashboard/sandbox/logs/logs-cells.tsx

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,8 @@
11
import type { SandboxLogModel } from '@/core/modules/sandboxes/models'
22
import { LogLevelBadge } from '@/features/dashboard/common/log-cells'
3+
import { formatLocalLogStyleTimestamp } from '@/lib/utils/formatting'
34
import CopyButtonInline from '@/ui/copy-button-inline'
45

5-
const LOCAL_DATE_FORMATTER = new Intl.DateTimeFormat(undefined, {
6-
month: 'short',
7-
day: '2-digit',
8-
})
9-
10-
const LOCAL_TIME_FORMATTER = new Intl.DateTimeFormat(undefined, {
11-
hour: '2-digit',
12-
minute: '2-digit',
13-
second: '2-digit',
14-
hour12: false,
15-
})
16-
176
export const LogLevel = ({ level }: { level: SandboxLogModel['level'] }) => {
187
return <LogLevelBadge level={level} />
198
}
@@ -23,21 +12,21 @@ interface TimestampProps {
2312
}
2413

2514
export const Timestamp = ({ timestampUnix }: TimestampProps) => {
26-
const date = new Date(timestampUnix)
15+
const formatted = formatLocalLogStyleTimestamp(timestampUnix, {
16+
includeCentiseconds: true,
17+
})
2718

28-
const centiseconds = Math.floor((date.getMilliseconds() / 10) % 100)
29-
.toString()
30-
.padStart(2, '0')
31-
const localDatePart = LOCAL_DATE_FORMATTER.format(date)
32-
const localTimePart = LOCAL_TIME_FORMATTER.format(date)
19+
if (!formatted) {
20+
return <span className="font-mono prose-table-numeric">--</span>
21+
}
3322

3423
return (
3524
<CopyButtonInline
36-
value={date.toISOString()}
25+
value={formatted.iso}
3726
className="font-mono group prose-table-numeric truncate"
3827
>
39-
<span className="text-fg-tertiary">{localDatePart}</span> {localTimePart}.
40-
{centiseconds}
28+
<span className="text-fg-tertiary">{formatted.datePart}</span>{' '}
29+
{formatted.timePart}.{formatted.subsecondPart}
4130
</CopyButtonInline>
4231
)
4332
}

src/features/dashboard/sandbox/logs/logs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import useLogFilters from './use-log-filters'
3939
import { useSandboxLogs } from './use-sandbox-logs'
4040

4141
// column widths are calculated as max width of the content + padding
42-
const COLUMN_WIDTHS_PX = { timestamp: 148 + 16, level: 48 + 16 } as const
42+
const COLUMN_WIDTHS_PX = { timestamp: 190, level: 48 + 16 } as const
4343
const ROW_HEIGHT_PX = 26
4444
const LIVE_STATUS_ROW_HEIGHT_PX = ROW_HEIGHT_PX + 16
4545
const VIRTUAL_OVERSCAN = 16

src/features/dashboard/sandbox/monitoring/components/monitoring-charts.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,9 @@ function renderUsageMarker(usedMb: number | null, value: number) {
174174

175175
return (
176176
<>
177-
<span className="text-fg">{normalizedUsedMb.toLocaleString()}</span>
177+
<span className="text-fg">
178+
{normalizedUsedMb.toLocaleString('en-US')}
179+
</span>
178180
<span className="text-fg-secondary">MB</span>
179181
<span className="text-fg-tertiary px-0.75">·</span>
180182
<span className="text-fg">{Math.round(value)}</span>

src/features/dashboard/sandboxes/list/table-cells.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ export function StartedAtCell({
170170
const dateValue = (getValue() as string | undefined) ?? ''
171171

172172
const formattedTimestamp = useMemo(() => {
173-
return formatLocalLogStyleTimestamp(dateValue)
173+
return formatLocalLogStyleTimestamp(dateValue, { includeTimezone: true })
174174
}, [dateValue])
175175

176176
return (

src/features/dashboard/templates/list/table-cells.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ export function CreatedAtCell({
322322
return formatLocalLogStyleTimestamp(dateValue, {
323323
includeSeconds: false,
324324
includeYear: true,
325+
includeTimezone: true,
325326
})
326327
}, [dateValue])
327328

@@ -351,6 +352,7 @@ export function UpdatedAtCell({
351352
return formatLocalLogStyleTimestamp(dateValue, {
352353
includeSeconds: false,
353354
includeYear: true,
355+
includeTimezone: true,
354356
})
355357
}, [dateValue])
356358

src/lib/utils/formatting.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,37 @@ import * as chrono from 'chrono-node'
77
import { format, isThisYear, isValid } from 'date-fns'
88
import { formatInTimeZone } from 'date-fns-tz'
99

10-
const LOCAL_LOG_STYLE_DATE_FORMATTER = new Intl.DateTimeFormat(undefined, {
10+
const LOCAL_LOG_STYLE_DATE_FORMATTER = new Intl.DateTimeFormat('en-US', {
1111
month: 'short',
1212
day: '2-digit',
1313
})
1414

1515
const LOCAL_LOG_STYLE_DATE_WITH_YEAR_FORMATTER = new Intl.DateTimeFormat(
16-
undefined,
16+
'en-US',
1717
{
1818
month: 'short',
1919
day: '2-digit',
2020
year: 'numeric',
2121
}
2222
)
2323

24-
const LOCAL_LOG_STYLE_TIME_FORMATTER = new Intl.DateTimeFormat(undefined, {
24+
const LOCAL_LOG_STYLE_TIME_FORMATTER = new Intl.DateTimeFormat('en-US', {
2525
hour: '2-digit',
2626
minute: '2-digit',
2727
second: '2-digit',
2828
hour12: false,
2929
})
3030

3131
const LOCAL_LOG_STYLE_TIME_NO_SECONDS_FORMATTER = new Intl.DateTimeFormat(
32-
undefined,
32+
'en-US',
3333
{
3434
hour: '2-digit',
3535
minute: '2-digit',
3636
hour12: false,
3737
}
3838
)
3939

40-
const LOCAL_LOG_STYLE_TIMEZONE_FORMATTER = new Intl.DateTimeFormat(undefined, {
40+
const LOCAL_LOG_STYLE_TIMEZONE_FORMATTER = new Intl.DateTimeFormat('en-US', {
4141
timeZoneName: 'short',
4242
})
4343

@@ -55,16 +55,18 @@ export function formatLocalLogStyleTimestamp(
5555
includeSeconds = true,
5656
includeYear = false,
5757
includeCentiseconds = false,
58+
includeTimezone = false,
5859
}: {
5960
includeSeconds?: boolean
6061
includeYear?: boolean
6162
includeCentiseconds?: boolean
63+
includeTimezone?: boolean
6264
} = {}
6365
): {
6466
datePart: string
6567
timePart: string
6668
subsecondPart: string | null
67-
timezonePart: string
69+
timezonePart: string | null
6870
iso: string
6971
} | null {
7072
const date = new Date(timestamp)
@@ -73,12 +75,13 @@ export function formatLocalLogStyleTimestamp(
7375
return null
7476
}
7577

76-
const timezonePart =
77-
LOCAL_LOG_STYLE_TIMEZONE_FORMATTER.formatToParts(date).find(
78-
(part) => part.type === 'timeZoneName'
79-
)?.value ??
80-
Intl.DateTimeFormat().resolvedOptions().timeZone ??
81-
'Local'
78+
const timezonePart = includeTimezone
79+
? (LOCAL_LOG_STYLE_TIMEZONE_FORMATTER.formatToParts(date).find(
80+
(part) => part.type === 'timeZoneName'
81+
)?.value ??
82+
Intl.DateTimeFormat().resolvedOptions().timeZone ??
83+
'Local')
84+
: null
8285

8386
return {
8487
datePart: (includeYear
@@ -148,8 +151,8 @@ export const formatDisplayTimestamp = (value: string | number | Date) => {
148151
? 'Today'
149152
: isYesterday
150153
? 'Yesterday'
151-
: date.toLocaleDateString()
152-
const timeStr = date.toLocaleTimeString([], {
154+
: date.toLocaleDateString('en-US')
155+
const timeStr = date.toLocaleTimeString('en-US', {
153156
hour: 'numeric',
154157
minute: '2-digit',
155158
second: '2-digit',

0 commit comments

Comments
 (0)