This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
// The labels each component takes, built from a message lookup. Every key this module's pages use is
|
||||
// named here and nowhere else, so `__tests__/i18n.test.ts` can run these builders against the
|
||||
// catalogues and fail on a key either language lacks -- the page itself holds no string.
|
||||
//
|
||||
// `t` takes a key relative to the module (`status.queued`); the page binds it to
|
||||
// `i18n.message("documents." + key)`. The two messages that are not this module's own -- the app's
|
||||
// `app.failed`, and the kit's `ui.aiDisclosure` and `ui.page` -- are passed in already looked up.
|
||||
|
||||
import { DOCUMENT_STATUSES, FAILURE_CODES, LINE_STATUSES } from "../contract/constants.js"
|
||||
import type { DocumentListLabels } from "./document-list.js"
|
||||
import type { ExportLabels } from "./export-button.js"
|
||||
import type { ReviewLabels } from "./line-review.js"
|
||||
import type { UploadLabels } from "./upload-form.js"
|
||||
|
||||
/** `{ a: f("a"), b: f("b") }` for a list of keys, typed by the keys. */
|
||||
function byKey<K extends string>(keys: readonly K[], f: (key: K) => string): Record<K, string> {
|
||||
return Object.fromEntries(keys.map((key) => [key, f(key)])) as Record<K, string>
|
||||
}
|
||||
|
||||
export type Translate = (key: string, values?: Record<string, string | number>) => string
|
||||
|
||||
/** The statuses a document shows: the stored ones, and `queued` for an upload nobody has read yet. */
|
||||
const LISTED_STATUSES = ["queued", ...DOCUMENT_STATUSES] as const
|
||||
|
||||
export function uploadLabels(t: Translate, failed: string): UploadLabels {
|
||||
return {
|
||||
label: t("upload.label"),
|
||||
hint: t("upload.hint"),
|
||||
submit: t("upload.submit"),
|
||||
busy: t("upload.busy"),
|
||||
done: t("upload.done"),
|
||||
progress: t("upload.progress"),
|
||||
failed,
|
||||
}
|
||||
}
|
||||
|
||||
export function listLabels(t: Translate): DocumentListLabels {
|
||||
return {
|
||||
caption: t("title"),
|
||||
empty: t("list.empty"),
|
||||
file: t("list.file"),
|
||||
status: t("list.status"),
|
||||
pages: t("list.pages"),
|
||||
pending: t("list.pending"),
|
||||
approved: t("list.approved"),
|
||||
uploaded: t("list.uploaded"),
|
||||
actions: t("list.actions"),
|
||||
// The `{filename}` placeholder is the component's to fill, so it is passed through untouched.
|
||||
review: t("list.review", { filename: "{filename}" }),
|
||||
download: t("list.download", { filename: "{filename}" }),
|
||||
statuses: byKey(LISTED_STATUSES, (status) => t(`status.${status}`)),
|
||||
failures: byKey(FAILURE_CODES, (code) => t(`failure.${code}`)),
|
||||
}
|
||||
}
|
||||
|
||||
export function reviewLabels(
|
||||
t: Translate,
|
||||
shared: { failed: string; aiDisclosure: string; pageWord: string },
|
||||
): ReviewLabels {
|
||||
// A message with a `{label}` or `{page}` or `{model}` placeholder is filled per line by the
|
||||
// component; it is looked up with the placeholder kept in place.
|
||||
const keep = (key: string, name: string) => t(key, { [name]: `{${name}}` })
|
||||
return {
|
||||
caption: t("review.tableLabel"),
|
||||
empty: t("review.noLines"),
|
||||
label: t("review.label"),
|
||||
value: t("review.value"),
|
||||
page: t("review.page"),
|
||||
source: t("review.source"),
|
||||
confidence: t("review.confidence"),
|
||||
decision: t("review.decision"),
|
||||
actions: t("review.actions"),
|
||||
approve: keep("review.approve", "label"),
|
||||
reject: keep("review.reject", "label"),
|
||||
edit: keep("review.edit", "label"),
|
||||
save: t("review.save"),
|
||||
cancel: t("review.cancel"),
|
||||
approveAll: t("review.approveAll"),
|
||||
needsReview: t("review.needsReview"),
|
||||
scannedQuote: t("review.scannedQuote"),
|
||||
block: keep("review.block", "id"),
|
||||
edited: t("review.edited"),
|
||||
sourceOnPage: keep("review.sourceOnPage", "page"),
|
||||
proposedBy: keep("review.proposedBy", "model"),
|
||||
aiDisclosure: shared.aiDisclosure,
|
||||
pageWord: shared.pageWord,
|
||||
states: byKey(LINE_STATUSES, (status) => t(`review.state.${status}`)),
|
||||
failed: shared.failed,
|
||||
}
|
||||
}
|
||||
|
||||
export function exportLabels(t: Translate, failed: string): ExportLabels {
|
||||
return {
|
||||
export: t("review.export"),
|
||||
hint: t("review.exportHint"),
|
||||
nothing: t("review.exportNothing"),
|
||||
exported: t("review.exported"),
|
||||
failed,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user