detailed data for verifications
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import {
|
||||
api, exportProjectUrl, exportVideoUrl, fmtDuration, fmtWhen, setAuthToken,
|
||||
api, exportProjectUrl, exportVideoUrl, fmtDuration, fmtWhen, passDeltas, setAuthToken,
|
||||
type Activity, type Member, type ProjectSummary, type Stats, type UserRow, type VideoRow,
|
||||
} from "./api";
|
||||
import { RemarkCell } from "./RemarkCell";
|
||||
@@ -505,15 +505,27 @@ export function App() {
|
||||
{v.annotation_count > 0
|
||||
? <a href={exportVideoUrl(v.id)} download title="Download this video's annotations (JSON)">{v.annotation_count} ⬇</a>
|
||||
: 0}
|
||||
{v.imported_count > 0 && (
|
||||
<div className="imported-line" title="annotations present when verification started (imported baseline)">
|
||||
<span className="dim">imported {v.imported_count}</span>
|
||||
{v.annotation_count < v.imported_count &&
|
||||
<span className="ann-del" title={`${v.imported_count - v.annotation_count} deleted by the user`}> · −{v.imported_count - v.annotation_count}</span>}
|
||||
{v.annotation_count > v.imported_count &&
|
||||
<span className="ann-add" title={`${v.annotation_count - v.imported_count} added by the user`}> · +{v.annotation_count - v.imported_count}</span>}
|
||||
</div>
|
||||
)}
|
||||
{(v.imported_count > 0 || (v.passes?.length ?? 0) > 0) && (() => {
|
||||
const deltas = passDeltas(v.imported_count, v.passes ?? []);
|
||||
return (
|
||||
<div className="imported-line" title="imported baseline → per-pass changes (verify / re-verify)">
|
||||
<span className="dim">imported {v.imported_count}</span>
|
||||
{deltas.length > 0
|
||||
? deltas.map((d, i) => (
|
||||
<span key={i} className={d.delta >= 0 ? "ann-add" : "ann-del"}
|
||||
title={`${d.label} by ${d.username} → ${d.total} total`}>
|
||||
{" · "}{d.label} {d.delta >= 0 ? "+" : ""}{d.delta}
|
||||
</span>
|
||||
))
|
||||
: <>
|
||||
{v.annotation_count < v.imported_count &&
|
||||
<span className="ann-del" title={`${v.imported_count - v.annotation_count} deleted by the user`}> · −{v.imported_count - v.annotation_count}</span>}
|
||||
{v.annotation_count > v.imported_count &&
|
||||
<span className="ann-add" title={`${v.annotation_count - v.imported_count} added by the user`}> · +{v.annotation_count - v.imported_count}</span>}
|
||||
</>}
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
</td>
|
||||
<td>{v.review_count > 0
|
||||
? <span className="review-flag" title={`${v.review_count} annotation(s) flagged for review`}>🚩 {v.review_count}</span>
|
||||
|
||||
@@ -42,6 +42,14 @@ export interface Remark {
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/** One verification pass (a push). `count` is the annotation total after that pass;
|
||||
* null for legacy pushes logged before we recorded it. */
|
||||
export interface Pass {
|
||||
username: string;
|
||||
at: string;
|
||||
count: number | null;
|
||||
}
|
||||
|
||||
export interface VideoRow {
|
||||
id: number;
|
||||
file_name: string;
|
||||
@@ -75,6 +83,7 @@ export interface VideoRow {
|
||||
ignored: boolean;
|
||||
ignored_by: string | null;
|
||||
remarks: Remark[];
|
||||
passes: Pass[]; // per-pass annotation-count history (push order)
|
||||
}
|
||||
|
||||
export interface LeaderRow {
|
||||
@@ -281,6 +290,25 @@ export const api = {
|
||||
post<{ folders: number }>(`/projects/${projectId}/folders`, { folders }, token),
|
||||
};
|
||||
|
||||
/** Per-pass annotation deltas from the imported baseline: verify +Δ, re-verify +Δ, …
|
||||
* Skips legacy passes that have no recorded count. The first pass is "verify",
|
||||
* subsequent ones "re-verify". `total` is the running annotation count after the pass. */
|
||||
export function passDeltas(
|
||||
importedCount: number,
|
||||
passes: Pass[],
|
||||
): { label: string; delta: number; username: string; total: number }[] {
|
||||
const out: { label: string; delta: number; username: string; total: number }[] = [];
|
||||
let prev = importedCount;
|
||||
let n = 0;
|
||||
for (const p of passes ?? []) {
|
||||
if (p.count == null) continue;
|
||||
n += 1;
|
||||
out.push({ label: n === 1 ? "verify" : "re-verify", delta: p.count - prev, username: p.username, total: p.count });
|
||||
prev = p.count;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** Human-readable byte size. */
|
||||
export function fmtBytes(n: number): string {
|
||||
if (!n || n <= 0) return "0 B";
|
||||
|
||||
Reference in New Issue
Block a user