62 lines
2.6 KiB
TypeScript
62 lines
2.6 KiB
TypeScript
// What a document's page says about the document above its lines: its status, how many lines wait and
|
|
// how many are approved, and which pages the extraction left out. The page keeps the document live, so
|
|
// these are built wherever it renders -- on the server for the first paint and in the browser on each
|
|
// change -- from messages that keep their placeholders (`@conusai-kit/i18n/format`: the language's plural
|
|
// rules, and no catalogue).
|
|
|
|
import { formatMessage } from "@conusai-kit/i18n/format"
|
|
import type { PAGE_CLASSES } from "../contract/constants.js"
|
|
import type { DocumentView } from "../contract/procedures.js"
|
|
import type { DocumentListLabels } from "./document-list.js"
|
|
|
|
export interface DocumentHeaderLabels {
|
|
/** "Status", the word before the status. */
|
|
readonly status: string
|
|
readonly statuses: DocumentListLabels["statuses"]
|
|
readonly failures: DocumentListLabels["failures"]
|
|
/** `{count, plural, ...}`, with its placeholder left in. */
|
|
readonly pendingCount: string
|
|
/** `{count, plural, ...}`, with its placeholder left in. */
|
|
readonly approvedCount: string
|
|
/** What a document nobody has read yet says. */
|
|
readonly waiting: string
|
|
readonly skippedTitle: string
|
|
/** `Page {page}: {kind}. ...`, with both placeholders left in. */
|
|
readonly skippedPage: string
|
|
readonly pageClasses: Readonly<Record<(typeof PAGE_CLASSES)[number], string>>
|
|
}
|
|
|
|
export interface DocumentHeader {
|
|
readonly status: string
|
|
readonly counts: string
|
|
readonly waiting?: string
|
|
readonly skipped?: {
|
|
readonly title: string
|
|
readonly pages: readonly { readonly page: number; readonly text: string }[]
|
|
}
|
|
}
|
|
|
|
export function documentHeader(document: DocumentView, labels: DocumentHeaderLabels, locale: string): DocumentHeader {
|
|
const failure = document.failureCode ? ` ${labels.failures[document.failureCode]}` : ""
|
|
return {
|
|
status: `${labels.status}: ${labels.statuses[document.status]}${failure}`,
|
|
counts: `${formatMessage(labels.pendingCount, { count: document.pending }, locale)}. ${formatMessage(labels.approvedCount, { count: document.approved }, locale)}.`,
|
|
...(document.status === "queued" || document.status === "processing" ? { waiting: labels.waiting } : {}),
|
|
...(document.skippedPages.length > 0
|
|
? {
|
|
skipped: {
|
|
title: labels.skippedTitle,
|
|
pages: document.skippedPages.map((skipped) => ({
|
|
page: skipped.page,
|
|
text: formatMessage(
|
|
labels.skippedPage,
|
|
{ page: skipped.page, kind: labels.pageClasses[skipped.pageClass] },
|
|
locale,
|
|
),
|
|
})),
|
|
},
|
|
}
|
|
: {}),
|
|
}
|
|
}
|