Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
84 lines
2.4 KiB
TypeScript
84 lines
2.4 KiB
TypeScript
/**
|
|
* Products list selection + export id helpers (node:test friendly).
|
|
*/
|
|
|
|
export function idsEqual(a: string | number, b: string | number): boolean {
|
|
return String(a) === String(b);
|
|
}
|
|
|
|
export function selectionHas(
|
|
selected: ReadonlyArray<string | number>,
|
|
id: string | number
|
|
): boolean {
|
|
return selected.some((x) => idsEqual(x, id));
|
|
}
|
|
|
|
/** Immutable add/remove for the products table checkbox selection. */
|
|
export function setProductSelected(
|
|
selected: ReadonlyArray<string | number>,
|
|
id: string | number,
|
|
selectedOn: boolean
|
|
): Array<string | number> {
|
|
if (selectedOn) {
|
|
if (selectionHas(selected, id)) return [...selected];
|
|
return [...selected, id];
|
|
}
|
|
return selected.filter((x) => !idsEqual(x, id));
|
|
}
|
|
|
|
/** Toggle all visible (selectable) ids into / out of the selection. */
|
|
export function toggleSelectAllIds(
|
|
selected: ReadonlyArray<string | number>,
|
|
visibleIds: ReadonlyArray<string | number>
|
|
): Array<string | number> {
|
|
const allOn =
|
|
visibleIds.length > 0 && visibleIds.every((id) => selectionHas(selected, id));
|
|
if (allOn) {
|
|
return selected.filter((id) => !visibleIds.some((v) => idsEqual(v, id)));
|
|
}
|
|
const merged = [...selected];
|
|
for (const id of visibleIds) {
|
|
if (!selectionHas(merged, id)) merged.push(id);
|
|
}
|
|
return merged;
|
|
}
|
|
|
|
export function selectableProductIds(
|
|
products: ReadonlyArray<{ id: string | number; processing_status?: string | null }>
|
|
): Array<string | number> {
|
|
return products
|
|
.filter((p) => p.processing_status !== "processing")
|
|
.map((p) => p.id);
|
|
}
|
|
|
|
/** Raw product ids for processing jobs (raw tab uses row id; processed uses raw_product_id). */
|
|
export function selectedRawProductIds(
|
|
products: ReadonlyArray<{
|
|
id: string | number;
|
|
raw_product_id?: string | number | null;
|
|
}>,
|
|
selected: ReadonlyArray<string | number>,
|
|
kind: "processed" | "raw"
|
|
): string[] {
|
|
const ids: string[] = [];
|
|
for (const p of products) {
|
|
if (!selectionHas(selected, p.id)) continue;
|
|
if (kind === "raw") ids.push(String(p.id));
|
|
else if (p.raw_product_id) ids.push(String(p.raw_product_id));
|
|
}
|
|
return ids;
|
|
}
|
|
|
|
export function toExportProductIds(selected: ReadonlyArray<string | number>): string[] {
|
|
return selected.map(String);
|
|
}
|
|
|
|
export function canOpenExportDialog(selectedCount: number): boolean {
|
|
return selectedCount > 0;
|
|
}
|
|
|
|
/** Map processing_status to ProductStatusBadge branch key. */
|
|
export function normalizeStatusBadgeLabel(status?: string | null): string {
|
|
return String(status ?? "").trim() || "unknown";
|
|
}
|