Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ const AlertImagesActions = ({
const blob = await response.blob();
const extension = detection.url.split('.').pop()?.split('?')[0] ?? 'jpg';
// Format: YYYY-MM-DDTHH-MM-SS_DETECTION_ID.extension
const createdAtFormatted = detection.created_at.split('.')[0];
const filename = `${createdAtFormatted}_${detection.id}.${extension}`;
const recordedAtFormatted = detection.recorded_at.split('.')[0];
const filename = `${recordedAtFormatted}_${detection.id}.${extension}`;
zip.file(filename, blob);
});
await Promise.all(fetchPromises);
Expand All @@ -157,8 +157,8 @@ const AlertImagesActions = ({
const blob = await response.blob();
const extension = detection.url.split('.').pop()?.split('?')[0] ?? 'jpg';
// Format: YYYY-MM-DDTHH-MM-SS_DETECTION_ID.extension
const createdAtFormatted = detection.created_at.split('.')[0];
const filename = `${createdAtFormatted}_${detection.id}.${extension}`;
const recordedAtFormatted = detection.recorded_at.split('.')[0];
const filename = `${recordedAtFormatted}_${detection.id}.${extension}`;

const img = new Image();
img.crossOrigin = 'anonymous';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ export const AlertPlayerProvider = ({
const marks = useMemo(
() =>
detections.map((d, i) => ({
value: convertIsoToUnix(d.created_at),
value: convertIsoToUnix(d.recorded_at),
id: d.id,
label:
i === 0 || i === detections.length - 1
? formatIsoToTime(d.created_at)
? formatIsoToTime(d.recorded_at)
: null,
})),
[detections]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,13 @@ export const AlertPlayerControls = ({
}}
>
<Slider
value={convertIsoToUnix(selectedDetection.created_at)}
value={convertIsoToUnix(selectedDetection.recorded_at)}
onChange={onChangeSlider}
min={marks[0].value}
max={marks[marks.length - 1].value}
step={null}
valueLabelDisplay={isPlaying ? 'off' : 'on'}
valueLabelFormat={formatIsoToTime(selectedDetection.created_at)}
valueLabelFormat={formatIsoToTime(selectedDetection.recorded_at)}
marks={marks}
sx={{
verticalAlign: 'middle',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ vi.mock('@/services/alerts', async () => {
};
});

const makeDetection = (id: number): alertsService.DetectionType => ({
const makeDetection = (
id: number,
recordedAt?: string
): alertsService.DetectionType => ({
id,
camera_id: 1,
pose_id: 1,
Expand All @@ -28,6 +31,8 @@ const makeDetection = (id: number): alertsService.DetectionType => ({
bbox: '(0.1,0.1,0.2,0.2)',
others_bboxes: null,
created_at: `2025-01-01T00:00:${id.toString().padStart(2, '0')}`,
recorded_at:
recordedAt ?? `2025-01-01T00:00:${id.toString().padStart(2, '0')}`,
url: `https://example/${id.toString()}`,
});

Expand Down Expand Up @@ -75,6 +80,29 @@ describe('useSampledDetections', () => {
expect(vi.mocked(alertsService.getDetectionsPage)).toHaveBeenCalledTimes(2);
});

it('orders detections by capture time, not by database creation time', async () => {
// created_at ascending by id, recorded_at deliberately reversed
vi.mocked(alertsService.getDetectionsPage).mockResolvedValueOnce([
makeDetection(1, '2025-01-01T00:00:20'),
makeDetection(2, '2025-01-01T00:00:05'),
]);

const { result } = renderHook(
() =>
useSampledDetections({
sequenceId: 42,
detectionsCount: 2,
}),
{ wrapper: wrapper(newClient()) }
);

await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});

expect(result.current.detections.map((d) => d.id)).toEqual([2, 1]);
});

it('returns empty list and not-loading when detectionsCount is 0', async () => {
const { result } = renderHook(
() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export const useSampledDetections = ({
.flat()
.sort(
(d1, d2) =>
convertIsoToUnix(d1.created_at) - convertIsoToUnix(d2.created_at)
convertIsoToUnix(d1.recorded_at) - convertIsoToUnix(d2.recorded_at)
) ?? [];

return {
Expand Down
1 change: 1 addition & 0 deletions src/services/alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const apiDetectionResponseSchema = z.object({
bbox: z.string(),
others_bboxes: z.nullable(z.string()),
created_at: z.iso.datetime({ local: true }),
recorded_at: z.iso.datetime({ local: true }),
url: z.string(),
crop_url: z.string().nullish(),
});
Expand Down
Loading