Prüfung / Lint, Typen, Tests (push) Canceled after 0s
Prüfung / Images bauen (pdf) (push) Canceled after 0s
Prüfung / Images bauen (web) (push) Canceled after 0s
Prüfung / Images bauen (worker) (push) Canceled after 0s
Images / bauen (pdf, docker/pdf.Dockerfile) (push) Canceled after 0s
Images / bauen (web, docker/web.Dockerfile) (push) Canceled after 0s
Images / bauen (worker, docker/worker.Dockerfile) (push) Canceled after 0s
375 Vorkommen in 210 Dateien. Betrifft Kommentare, Oberflaechentexte und die README; an keiner Stelle Bedeutung, nur Zeichensetzung.
181 lines
5.9 KiB
TypeScript
181 lines
5.9 KiB
TypeScript
import type { Metadata } from 'next'
|
|
import { db } from '@/lib/db'
|
|
import { loadDocumentSections } from '@/lib/documents/service'
|
|
import { loadVisibleDocument } from '@/lib/documents/service'
|
|
import { resolvePhotoUrls } from '@/lib/files/service'
|
|
import { permissionsForPrint } from '@/lib/export/printAccess'
|
|
import { Sheet } from '@/components/documents/Sheet'
|
|
import { de } from '@/lib/i18n/de'
|
|
import { NotAvailable } from '../../../NotAvailable'
|
|
import { isInputField, fillPlaceholders } from '@/lib/templates/fields'
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
export async function generateMetadata({
|
|
params,
|
|
}: {
|
|
params: Promise<{ documentNumber: string }>
|
|
}): Promise<Metadata> {
|
|
const { documentNumber } = await params
|
|
return { title: documentNumber, robots: { index: false, follow: false } }
|
|
}
|
|
|
|
/**
|
|
* Druckansicht eines einzelnen Dokuments.
|
|
*
|
|
* Kein Verlauf, keine Kopfdatentabelle einer Akte - das Dokument selbst, so
|
|
* wie seine Vorlage es vorsieht. Ein Aktenblatt kommt als Aktenblatt heraus,
|
|
* ein Vertrag als Vertrag. Siehe docs/08-suche-und-export.md.
|
|
*/
|
|
export default async function PrintDocumentPage({
|
|
params,
|
|
searchParams,
|
|
}: {
|
|
params: Promise<{ documentNumber: string }>
|
|
searchParams: Promise<{ token?: string }>
|
|
}) {
|
|
const { documentNumber } = await params
|
|
const { token } = await searchParams
|
|
|
|
const zugang = await permissionsForPrint(token)
|
|
if (!zugang) return <NotAvailable />
|
|
const { permissions, displayName } = zugang
|
|
|
|
const doc = await loadVisibleDocument(permissions, documentNumber)
|
|
if (!doc) return <NotAvailable />
|
|
|
|
const [sections, template, foundationLevels, levels] = await Promise.all([
|
|
loadDocumentSections(permissions, doc),
|
|
db.documentTemplate.findUnique({
|
|
where: { id: doc.templateId },
|
|
select: { sheetTitle: true, sheetSubtitle: true, name: true },
|
|
}),
|
|
db.foundationClearance.findMany({ orderBy: { sortOrder: 'asc' } }),
|
|
db.clearanceLevelConfig.findMany({ orderBy: { level: 'asc' } }),
|
|
])
|
|
|
|
const photoUrls = await resolvePhotoUrls(
|
|
permissions,
|
|
sections.map((section) => ({
|
|
fieldKey: section.fieldKey,
|
|
visible: section.visible,
|
|
value: section.visible ? section.value : null,
|
|
type: section.field.type,
|
|
})),
|
|
)
|
|
|
|
const levelName = new Map(levels.map((l) => [l.level, l.name]))
|
|
const werte = Object.fromEntries(
|
|
sections.filter((s) => s.visible).map((s) => [s.fieldKey, s.value]),
|
|
)
|
|
|
|
// Das Aktenblatt bringt sein eigenes Aussehen mit und braucht keinen
|
|
// Berichtsrahmen darum.
|
|
if (doc.layout === 'DOSSIER') {
|
|
return (
|
|
<Sheet
|
|
sections={sections}
|
|
title={template?.sheetTitle ?? de.app.name}
|
|
subtitle={template?.sheetSubtitle ?? template?.name ?? doc.title}
|
|
documentNumber={doc.documentNumber}
|
|
issuedAt={doc.createdAt}
|
|
foundationLevels={foundationLevels}
|
|
footerNote={de.document.footerNote}
|
|
photoUrls={photoUrls}
|
|
/>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<main className="print-sheet">
|
|
<section className="print-cover">
|
|
<span className="print-stamp">
|
|
{doc.classification} · {levelName.get(doc.classification) ?? de.common.unknown}
|
|
</span>
|
|
<h1 style={{ marginTop: '4mm' }}>{doc.title}</h1>
|
|
<p style={{ fontFamily: 'var(--font-mono, monospace)', margin: 0 }}>
|
|
{doc.documentNumber}
|
|
</p>
|
|
|
|
<table className="print-meta">
|
|
<tbody>
|
|
<tr>
|
|
<th>{de.case.status}</th>
|
|
<td>{de.document.statusNames[doc.status] ?? doc.status}</td>
|
|
</tr>
|
|
<tr>
|
|
<th>{de.document.kind}</th>
|
|
<td>{doc.templateKey}</td>
|
|
</tr>
|
|
<tr>
|
|
<th>{de.export.retrievedBy}</th>
|
|
<td>{displayName}</td>
|
|
</tr>
|
|
<tr>
|
|
<th>{de.export.asOf}</th>
|
|
<td>
|
|
{new Date().toLocaleString('de-DE')} · {de.clearance.label}{' '}
|
|
{permissions.clearanceLevel}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</section>
|
|
|
|
{doc.retractedAt ? (
|
|
<p className="print-stamp" style={{ marginBottom: '4mm' }}>
|
|
{de.document.statusNames.RETRACTED}
|
|
</p>
|
|
) : null}
|
|
|
|
{sections.map((section) => {
|
|
const field = section.field
|
|
|
|
if (!isInputField(field)) {
|
|
if (field.type === 'pagebreak') {
|
|
return <div key={field.key} style={{ breakAfter: 'page' }} />
|
|
}
|
|
const text = fillPlaceholders(field.text ?? '', werte)
|
|
return field.type === 'heading' ? (
|
|
<h3 key={field.key}>{text || field.label}</h3>
|
|
) : (
|
|
<p key={field.key} style={{ whiteSpace: 'pre-wrap' }}>
|
|
{text}
|
|
</p>
|
|
)
|
|
}
|
|
|
|
if (field.type === 'signature') {
|
|
return (
|
|
<div key={field.key} style={{ marginTop: '10mm', breakInside: 'avoid' }}>
|
|
<div style={{ borderTop: '1pt solid #000', width: '70mm' }} />
|
|
<p className="print-note">{fillPlaceholders(field.label, werte)}</p>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div key={field.key} style={{ marginBottom: '3mm', breakInside: 'avoid' }}>
|
|
<p className="print-label">{field.label}</p>
|
|
{!section.visible ? (
|
|
<p style={{ margin: '1mm 0' }}>
|
|
<span className="print-redacted"> </span>{' '}
|
|
<span className="print-note">
|
|
{de.export.redactedAt(
|
|
section.value.requiredLevel,
|
|
levelName.get(section.value.requiredLevel) ?? '',
|
|
)}
|
|
</span>
|
|
</p>
|
|
) : (
|
|
<p style={{ margin: '1mm 0', whiteSpace: 'pre-wrap' }}>
|
|
{String(section.value ?? '-')}
|
|
</p>
|
|
)}
|
|
</div>
|
|
)
|
|
})}
|
|
</main>
|
|
)
|
|
}
|