fix(detail): handle non-Z timezone offsets in Last Seen
Backend sends ISO timestamps with +00:00 offset. Code blindly appended 'Z' when the string didn't end with 'Z', producing '...+00:00Z' which parses to Invalid Date. Detect any timezone marker (Z, z, or numeric offset like +00:00) and only append 'Z' for naive datetimes. Co-authored-by:
This commit is contained in:
@@ -234,7 +234,7 @@ export function DetailPanel({ onEdit }: DetailPanelProps) {
|
||||
{data.mac && <DetailRow label="MAC" value={data.mac} mono />}
|
||||
{data.os && <DetailRow label="OS" value={data.os} />}
|
||||
{data.check_method && <DetailRow label="Check" value={data.check_method} mono />}
|
||||
{data.last_seen && <DetailRow label="Last Seen" value={new Date(data.last_seen.endsWith('Z') ? data.last_seen : data.last_seen + 'Z').toLocaleString()} />}
|
||||
{data.last_seen && <DetailRow label="Last Seen" value={new Date(/[Zz]|[+-]\d{2}:?\d{2}$/.test(data.last_seen) ? data.last_seen : data.last_seen + 'Z').toLocaleString()} />}
|
||||
</div>
|
||||
|
||||
{/* Properties section */}
|
||||
|
||||
@@ -487,4 +487,27 @@ describe('DetailPanel', () => {
|
||||
expect(screen.getByText('health').tagName).not.toBe('A')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Last Seen formatting', () => {
|
||||
it('renders a valid date when last_seen has +00:00 offset (no Z)', () => {
|
||||
setupStore({ last_seen: '2026-05-10T17:54:38.221403+00:00' })
|
||||
render(<DetailPanel onEdit={vi.fn()} />)
|
||||
const row = screen.getByText('Last Seen').parentElement
|
||||
expect(row?.textContent).not.toMatch(/Invalid Date/)
|
||||
})
|
||||
|
||||
it('renders a valid date when last_seen ends with Z', () => {
|
||||
setupStore({ last_seen: '2026-05-10T17:54:38.221403Z' })
|
||||
render(<DetailPanel onEdit={vi.fn()} />)
|
||||
const row = screen.getByText('Last Seen').parentElement
|
||||
expect(row?.textContent).not.toMatch(/Invalid Date/)
|
||||
})
|
||||
|
||||
it('treats naive ISO strings as UTC', () => {
|
||||
setupStore({ last_seen: '2026-05-10T17:54:38' })
|
||||
render(<DetailPanel onEdit={vi.fn()} />)
|
||||
const row = screen.getByText('Last Seen').parentElement
|
||||
expect(row?.textContent).not.toMatch(/Invalid Date/)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user