Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0fb107a

Browse files
fix: date formatting errors with invalid (empty) dates (#636)
1 parent dd63115 commit 0fb107a

File tree

8 files changed

+61
-87
lines changed

8 files changed

+61
-87
lines changed

‎ui/packages/shared/components/ResetCloneModal/index.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
import { useEffect, useState } from 'react'
99
import { makeStyles } from '@material-ui/core'
10-
import { formatDistanceToNowStrict } from 'date-fns'
11-
1210
import { Clone } from '@postgres.ai/shared/types/api/entities/clone'
1311
import { Snapshot } from '@postgres.ai/shared/types/api/entities/snapshot'
1412
import { Text } from '@postgres.ai/shared/components/Text'
@@ -18,7 +16,7 @@ import { ImportantText } from '@postgres.ai/shared/components/ImportantText'
1816
import { Spinner } from '@postgres.ai/shared/components/Spinner'
1917
import { SimpleModalControls } from '@postgres.ai/shared/components/SimpleModalControls'
2018
import { compareSnapshotsDesc } from '@postgres.ai/shared/utils/snapshot'
21-
import { isValidDate } from '@postgres.ai/shared/utils/date'
19+
import { formatDateWithDistance } from '@postgres.ai/shared/utils/date'
2220

2321
type Props = {
2422
isOpen: boolean
@@ -111,12 +109,7 @@ export const ResetCloneModal = (props: Props) => {
111109
value: snapshot.id,
112110
children: (
113111
<>
114-
{snapshot.dataStateAt} (
115-
{isValidDate(snapshot.dataStateAtDate) &&
116-
formatDistanceToNowStrict(snapshot.dataStateAtDate, {
117-
addSuffix: true,
118-
})}
119-
)
112+
{formatDateWithDistance(snapshot.dataStateAt, snapshot.dataStateAtDate)}
120113
{isLatest && (
121114
<span className={classes.snapshotTag}>Latest</span>
122115
)}

‎ui/packages/shared/pages/Branches/components/BranchesTable/index.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ import { useEffect, useState } from 'react'
1010
import copy from 'copy-to-clipboard'
1111
import { makeStyles } from '@material-ui/core'
1212
import { useHistory } from 'react-router-dom'
13-
import { formatDistanceToNowStrict } from 'date-fns'
14-
15-
import { isValidDate } from '@postgres.ai/shared/utils/date'
13+
import { formatDateWithDistance } from '@postgres.ai/shared/utils/date'
1614
import { ArrowDropDownIcon } from '@postgres.ai/shared/icons/ArrowDropDown'
1715
import { Branch } from '@postgres.ai/shared/types/api/endpoints/getBranches'
1816
import { HorizontalScrollContainer } from '@postgres.ai/shared/components/HorizontalScrollContainer'
@@ -168,13 +166,7 @@ export const BranchesTable = ({
168166
<TableBodyCell>{branch.name}</TableBodyCell>
169167
<TableBodyCell>{branch.parent}</TableBodyCell>
170168
<TableBodyCell>
171-
{branch.dataStateAt} (
172-
{isValidDate(new Date(branch.dataStateAt))
173-
? formatDistanceToNowStrict(new Date(branch.dataStateAt), {
174-
addSuffix: true,
175-
})
176-
: '-'}
177-
)
169+
{formatDateWithDistance(branch.dataStateAt, new Date(branch.dataStateAt))}
178170
</TableBodyCell>
179171
<TableBodyCell>{branch.snapshotID}</TableBodyCell>
180172
<TableBodyCell>{branch.numSnapshots}</TableBodyCell>

‎ui/packages/shared/pages/Instance/Clones/ClonesList/index.tsx

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import { useState } from 'react'
99
import cn from 'classnames'
10-
import { formatDistanceToNowStrict } from 'date-fns'
1110
import { useHistory } from 'react-router-dom'
1211

1312
import {
@@ -32,7 +31,7 @@ import {
3231
getCloneStatusText,
3332
} from '@postgres.ai/shared/utils/clone'
3433
import { formatBytesIEC } from '@postgres.ai/shared/utils/units'
35-
import { isValidDate } from '@postgres.ai/shared/utils/date'
34+
import { formatDateWithDistance } from '@postgres.ai/shared/utils/date'
3635

3736
import { MenuCell } from './MenuCell'
3837
import { ConnectionModal } from './ConnectionModal'
@@ -217,13 +216,7 @@ export const ClonesList = (props: Props) => {
217216
)}
218217
</TableBodyCell>
219218
<TableBodyCell>
220-
{clone.createdAt} (
221-
{isValidDate(clone.createdAtDate)
222-
? formatDistanceToNowStrict(clone.createdAtDate, {
223-
addSuffix: true,
224-
})
225-
: '-'}
226-
)
219+
{formatDateWithDistance(clone.createdAt, clone.createdAtDate)}
227220
</TableBodyCell>
228221
<TableBodyCell>{clone.db.port}</TableBodyCell>
229222
<TableBodyCell>{clone.db.username}</TableBodyCell>
@@ -232,22 +225,7 @@ export const ClonesList = (props: Props) => {
232225
</TableBodyCell>
233226
<TableBodyCell>{clone.snapshot?.pool ?? '-'}</TableBodyCell>
234227
<TableBodyCell>
235-
{clone.snapshot ? (
236-
<>
237-
{clone.snapshot.dataStateAt} (
238-
{isValidDate(clone.snapshot.dataStateAtDate)
239-
? formatDistanceToNowStrict(
240-
clone.snapshot.dataStateAtDate,
241-
{
242-
addSuffix: true,
243-
},
244-
)
245-
: '-'}
246-
)
247-
</>
248-
) : (
249-
'-'
250-
)}
228+
{clone.snapshot ? formatDateWithDistance(clone.snapshot.dataStateAt, clone.snapshot.dataStateAtDate) : '-'}
251229
</TableBodyCell>
252230
</TableRow>
253231
)

‎ui/packages/shared/pages/Instance/InactiveInstance/index.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Tooltip } from '@material-ui/core'
22
import { makeStyles } from '@material-ui/core'
3-
import { formatDistanceToNowStrict } from 'date-fns'
3+
import { formatDistanceSafe } from '@postgres.ai/shared/utils/date'
44

55
import { Link } from '@postgres.ai/shared/components/Link2'
66
import { Instance } from '@postgres.ai/shared/types/api/entities/instance'
@@ -95,10 +95,7 @@ export const InactiveInstance = ({
9595
classes={{ tooltip: classes.toolTip }}
9696
>
9797
<span>
98-
{instance?.createdAt &&
99-
formatDistanceToNowStrict(new Date(instance?.createdAt), {
100-
addSuffix: true,
101-
})}
98+
{instance?.createdAt ? formatDistanceSafe(new Date(instance?.createdAt)) : '-'}
10299
</span>
103100
</Tooltip>
104101
</span>
@@ -114,12 +111,7 @@ export const InactiveInstance = ({
114111
classes={{ tooltip: classes.toolTip }}
115112
>
116113
<span>
117-
{formatDistanceToNowStrict(
118-
new Date(instance?.telemetryLastReportedAt),
119-
{
120-
addSuffix: true,
121-
},
122-
)}
114+
{instance?.telemetryLastReportedAt ? formatDistanceSafe(new Date(instance?.telemetryLastReportedAt)) : '-'}
123115
</span>
124116
</Tooltip>
125117
</span>

‎ui/packages/shared/pages/Instance/Snapshots/components/SnapshotsList/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import {
1414
generateSnapshotPageId,
1515
groupSnapshotsByCreatedAtDate,
1616
} from '@postgres.ai/shared/pages/Instance/Snapshots/utils'
17-
import { format, formatDistanceToNowStrict } from 'date-fns'
17+
import { format } from 'date-fns'
18+
import { formatDistanceSafe } from '@postgres.ai/shared/utils/date'
1819
import { formatBytesIEC } from '@postgres.ai/shared/utils/units'
1920
import { useHistory } from 'react-router'
2021
import { DestroySnapshot } from '@postgres.ai/shared/types/api/endpoints/destroySnapshot'
@@ -129,7 +130,7 @@ const SnapshotListItem = ({
129130
setSnapshotModal: (modal: { isOpen: boolean; snapshotId: string }) => void
130131
}) => {
131132
const classes = useStyles()
132-
const timeAgo = formatDistanceToNowStrict(snapshot.createdAtDate)
133+
const timeAgo = formatDistanceSafe(snapshot.createdAtDate)
133134

134135
const history = useHistory()
135136
const host = useHost()

‎ui/packages/shared/pages/Instance/Snapshots/components/SnapshotsTable/index.tsx

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import React from 'react'
99
import cn from 'classnames'
1010
import { observer } from 'mobx-react-lite'
1111
import { makeStyles } from '@material-ui/core'
12-
import { formatDistanceToNowStrict } from 'date-fns'
1312
import copy from 'copy-to-clipboard'
1413
import { useHistory } from 'react-router-dom'
1514

@@ -19,7 +18,7 @@ import { DestroySnapshotModal } from '@postgres.ai/shared/pages/Snapshots/Snapsh
1918
import { useStores } from '@postgres.ai/shared/pages/Instance/context'
2019
import { ArrowDropDownIcon } from '@postgres.ai/shared/icons/ArrowDropDown'
2120
import { formatBytesIEC } from '@postgres.ai/shared/utils/units'
22-
import { isSameDayUTC, isValidDate } from '@postgres.ai/shared/utils/date'
21+
import { isSameDayUTC, formatDateWithDistance } from '@postgres.ai/shared/utils/date'
2322
import {
2423
Table,
2524
TableHead,
@@ -190,22 +189,10 @@ export const SnapshotsTable: React.FC<SnapshotsTableProps> = observer(
190189
]}
191190
/>
192191
<TableBodyCell>
193-
{snapshot.dataStateAt} (
194-
{isValidDate(snapshot.dataStateAtDate)
195-
? formatDistanceToNowStrict(snapshot.dataStateAtDate, {
196-
addSuffix: true,
197-
})
198-
: '-'}
199-
)
192+
{formatDateWithDistance(snapshot.dataStateAt, snapshot.dataStateAtDate)}
200193
</TableBodyCell>
201194
<TableBodyCell>
202-
{snapshot.createdAt} (
203-
{isValidDate(snapshot.createdAtDate)
204-
? formatDistanceToNowStrict(snapshot.createdAtDate, {
205-
addSuffix: true,
206-
})
207-
: '-'}
208-
)
195+
{formatDateWithDistance(snapshot.createdAt, snapshot.createdAtDate)}
209196
</TableBodyCell>
210197
<TableBodyCell>{snapshot.pool ?? '-'}</TableBodyCell>
211198
<TableBodyCell>{snapshot.numClones ?? '-'}</TableBodyCell>

‎ui/packages/shared/pages/Instance/SnapshotsModal/index.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import { observer } from 'mobx-react-lite'
99
import { makeStyles } from '@material-ui/core'
10-
import { formatDistanceToNowStrict } from 'date-fns'
1110
import copy from 'copy-to-clipboard'
1211

1312
import { useStores } from '@postgres.ai/shared/pages/Instance/context'
@@ -24,7 +23,7 @@ import {
2423
TableBodyCellMenu,
2524
} from '@postgres.ai/shared/components/Table'
2625
import { formatBytesIEC } from '@postgres.ai/shared/utils/units'
27-
import { isSameDayUTC } from '@postgres.ai/shared/utils/date'
26+
import { isSameDayUTC,formatDateWithDistance } from '@postgres.ai/shared/utils/date'
2827

2928
import { Tags } from '@postgres.ai/shared/pages/Instance/components/Tags'
3029
import { ModalReloadButton } from '@postgres.ai/shared/pages/Instance/components/ModalReloadButton'
@@ -137,18 +136,10 @@ export const SnapshotsModal = observer(() => {
137136
]}
138137
/>
139138
<TableBodyCell>
140-
{snapshot.dataStateAt} (
141-
{formatDistanceToNowStrict(snapshot.dataStateAtDate, {
142-
addSuffix: true,
143-
})}
144-
)
139+
{formatDateWithDistance(snapshot.dataStateAt, snapshot.dataStateAtDate)}
145140
</TableBodyCell>
146141
<TableBodyCell>
147-
{snapshot.createdAt} (
148-
{formatDistanceToNowStrict(snapshot.createdAtDate, {
149-
addSuffix: true,
150-
})}
151-
)
142+
{formatDateWithDistance(snapshot.createdAt, snapshot.createdAtDate)}
152143
</TableBodyCell>
153144
<TableBodyCell>{snapshot.pool ?? '-'}</TableBodyCell>
154145
<TableBodyCell>

‎ui/packages/shared/utils/date.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,24 @@ import {
2222
} from 'date-fns'
2323

2424
export const formatDateToISO = (dateString: string) => {
25-
const parsedDate = parse(dateString, 'yyyyMMddHHmmss', new Date())
26-
return format(parsedDate, "yyyy-MM-dd'T'HH:mm:ssXXX")
25+
// Handle empty or invalid date strings
26+
if (!dateString || dateString.trim() === '') {
27+
return ''
28+
}
29+
30+
try {
31+
const parsedDate = parse(dateString, 'yyyyMMddHHmmss', new Date())
32+
33+
// Additional validation of parsed date
34+
if (!isValidDate(parsedDate) || isNaN(parsedDate.getTime())) {
35+
return ''
36+
}
37+
38+
return format(parsedDate, "yyyy-MM-dd'T'HH:mm:ssXXX")
39+
} catch (error) {
40+
// Return empty string for invalid date formats
41+
return ''
42+
}
2743
}
2844

2945
// parseDate parses date of both format: '2006年01月02日 15:04:05 UTC' and `2006年01月02日T15:04:05Z` (RFC3339).
@@ -94,3 +110,27 @@ export const formatDateStd = (
94110
export const isValidDate = (dateObject: Date) => {
95111
return new Date(dateObject).toString() !== 'Invalid Date'
96112
}
113+
114+
// Safe date formatting with distance
115+
export const formatDateWithDistance = (dateString: string, dateObject: Date) => {
116+
if (!dateString || !isValidDate(dateObject)) return '-'
117+
118+
try {
119+
return `${dateString} (${formatDistanceToNowStrict(dateObject, { addSuffix: true })})`
120+
} catch (error) {
121+
console.warn('Error formatting date distance:', error, 'date:', dateObject)
122+
return '-'
123+
}
124+
}
125+
126+
// Safe distance formatting only
127+
export const formatDistanceSafe = (dateObject: Date) => {
128+
if (!isValidDate(dateObject)) return '-'
129+
130+
try {
131+
return formatDistanceToNowStrict(dateObject, { addSuffix: true })
132+
} catch (error) {
133+
console.warn('Error formatting distance:', error, 'date:', dateObject)
134+
return '-'
135+
}
136+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /