Add per-snapshot review link and snapshot picker to Reviews tab
This commit is contained in:
+27
-8
@@ -1,7 +1,7 @@
|
||||
import { get, type ByreEvent, type Schemas } from "./api.js";
|
||||
import { ago, errorText, h, replace } from "./dom.js";
|
||||
import { markdown } from "./markdown.js";
|
||||
import { onEach, state } from "./state.js";
|
||||
import { onEach, pickReview, state } from "./state.js";
|
||||
|
||||
type Review = Schemas["Review"];
|
||||
|
||||
@@ -80,7 +80,8 @@ function reviewResult(r: Review, taskId: string | undefined): HTMLElement {
|
||||
}
|
||||
|
||||
export function mountReviews(root: HTMLElement): () => void {
|
||||
const list = h("div", { class: "review-list" });
|
||||
const head = h("header", { class: "reviews-header" });
|
||||
const body = h("div", { class: "review-list" });
|
||||
let reviews: Review[] | undefined;
|
||||
let error = "";
|
||||
let target = 0;
|
||||
@@ -112,23 +113,40 @@ export function mountReviews(root: HTMLElement): () => void {
|
||||
|
||||
const render = () => {
|
||||
const taskId = state.selectedTaskId;
|
||||
replace(head);
|
||||
head.hidden = true;
|
||||
if (!taskId) {
|
||||
replace(list, h("div", { class: "empty" }, "No task selected."));
|
||||
replace(body, h("div", { class: "empty" }, "No task selected."));
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
replace(list, h("div", { class: "empty error-text" }, error));
|
||||
replace(body, h("div", { class: "empty error-text" }, error));
|
||||
return;
|
||||
}
|
||||
if (!reviews) {
|
||||
replace(list, h("div", { class: "empty" }, "Loading…"));
|
||||
replace(body, h("div", { class: "empty" }, "Loading…"));
|
||||
return;
|
||||
}
|
||||
if (reviews.length === 0) {
|
||||
replace(list, h("div", { class: "empty" }, "No reviews yet. Each new snapshot of the task is reviewed by an agent from the other vendor."));
|
||||
replace(body, h("div", { class: "empty" }, "No reviews yet. Each new snapshot of the task is reviewed by an agent from the other vendor."));
|
||||
return;
|
||||
}
|
||||
replace(list, ...[...reviews].reverse().map((r) => reviewCard(r, taskId)));
|
||||
const n = state.reviewed ?? reviews.at(-1)!.snapshot_n;
|
||||
const shown = reviews.findLast((r) => r.snapshot_n === n);
|
||||
const ns = [...new Set([n, ...reviews.map((r) => r.snapshot_n)])].sort((a, b) => b - a);
|
||||
const picker = h("select", { title: "Snapshot whose review to show" }, ...ns.map((s) => h("option", { value: String(s) }, `snapshot #${s}`)));
|
||||
picker.value = String(n);
|
||||
picker.onchange = () => pickReview(Number(picker.value));
|
||||
const step = (to: number, label: string) => {
|
||||
const b = h("button", { type: "button", class: "snap-step", disabled: !ns.includes(to) }, label);
|
||||
b.onclick = () => pickReview(to);
|
||||
return b;
|
||||
};
|
||||
const next = ns.filter((s) => s > n).at(-1);
|
||||
const prev = ns.find((s) => s < n);
|
||||
head.hidden = false;
|
||||
replace(head, picker, step(prev ?? n - 1, `← #${prev ?? n - 1}`), step(next ?? n + 1, `#${next ?? n + 1} →`));
|
||||
replace(body, shown ? reviewCard(shown, taskId) : h("div", { class: "empty" }, `No review of snapshot #${n} yet.`));
|
||||
};
|
||||
|
||||
const offs = [
|
||||
@@ -144,9 +162,10 @@ export function mountReviews(root: HTMLElement): () => void {
|
||||
void load();
|
||||
}
|
||||
}),
|
||||
onEach(["review"], render),
|
||||
];
|
||||
|
||||
replace(root, h("div", { class: "reviews-view" }, list));
|
||||
replace(root, h("div", { class: "reviews-view" }, head, body));
|
||||
render();
|
||||
void load();
|
||||
return () => {
|
||||
|
||||
Reference in New Issue
Block a user