Complete assisted intake provenance UI
Module Package Release / publish-packages (push) Successful in 13s
Module Package Release / publish-packages (push) Successful in 13s
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@govoplan/forms-runtime-webui",
|
||||
"version": "0.1.19",
|
||||
"version": "0.1.20",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
|
||||
@@ -89,8 +89,7 @@ export default function FormInstancePage({ settings, auth }: PlatformRouteContex
|
||||
const [assistedOutcome, setAssistedOutcome] = useState<AssistedConfirmation["outcome"]>("confirmed");
|
||||
const [assistedMethod, setAssistedMethod] = useState<AssistedConfirmation["method"]>("spoken_readback");
|
||||
const [assistedConfirmedBy, setAssistedConfirmedBy] = useState("");
|
||||
const [assistedSource, setAssistedSource] = useState<AssistedIntakeContext["field_sources"][string]["source"]>("person_statement");
|
||||
const [assistedConfidence, setAssistedConfidence] = useState<AssistedIntakeContext["field_sources"][string]["confidence"]>("stated");
|
||||
const [assistedFieldSources, setAssistedFieldSources] = useState<AssistedIntakeContext["field_sources"]>({});
|
||||
const [assistedNote, setAssistedNote] = useState("");
|
||||
|
||||
const load = useCallback(async (signal?: AbortSignal) => {
|
||||
@@ -115,6 +114,11 @@ export default function FormInstancePage({ settings, auth }: PlatformRouteContex
|
||||
setHandoffs(nextHandoffs.handoffs);
|
||||
setAssistedConfirmations(nextConfirmations.confirmations);
|
||||
setAssistedConfirmedBy((current) => current || assisted?.affected_party_ref || "");
|
||||
setAssistedFieldSources(assistedSourcesForRevision(
|
||||
nextInstance,
|
||||
assisted,
|
||||
nextConfirmations.confirmations
|
||||
));
|
||||
setValues(nextInstance.values);
|
||||
setAttachmentRefs(nextInstance.attachment_refs);
|
||||
setSignatureRefs(nextInstance.signature_refs);
|
||||
@@ -147,7 +151,7 @@ export default function FormInstancePage({ settings, auth }: PlatformRouteContex
|
||||
const canAdmin = hasScope(auth, "forms_runtime:workspace:admin");
|
||||
const canEditPermission = canParticipate || canWrite;
|
||||
const editable = Boolean(editableLifecycle && canEditPermission);
|
||||
const canSave = Boolean(instance?.status === "draft" && definition?.allow_drafts && canEditPermission);
|
||||
const canSave = Boolean(editableLifecycle && definition?.allow_drafts && canEditPermission);
|
||||
const changed = useMemo(
|
||||
() => Boolean(instance && (
|
||||
JSON.stringify(values) !== JSON.stringify(instance.values)
|
||||
@@ -248,11 +252,9 @@ export default function FormInstancePage({ settings, auth }: PlatformRouteContex
|
||||
fieldSources: Object.fromEntries(
|
||||
Object.entries(values)
|
||||
.filter(([, value]) => value !== null && value !== undefined && value !== "")
|
||||
.map(([key]) => [key, {
|
||||
source: assistedSource,
|
||||
confidence: assistedConfidence,
|
||||
declared_by_ref: assistedConfirmedBy.trim()
|
||||
}])
|
||||
.map(([key]) => [key, assistedFieldSources[key] ?? defaultAssistedFieldSource(
|
||||
assistedConfirmedBy.trim() || assisted.affected_party_ref
|
||||
)])
|
||||
),
|
||||
correctionNote: assistedNote
|
||||
}
|
||||
@@ -277,6 +279,21 @@ export default function FormInstancePage({ settings, auth }: PlatformRouteContex
|
||||
setSignatureRefs([]);
|
||||
}
|
||||
|
||||
function changeAssistedFieldSource(
|
||||
fieldKey: string,
|
||||
patch: Partial<AssistedIntakeContext["field_sources"][string]>
|
||||
) {
|
||||
setAssistedFieldSources((current) => ({
|
||||
...current,
|
||||
[fieldKey]: {
|
||||
...(current[fieldKey] ?? defaultAssistedFieldSource(
|
||||
assistedConfirmedBy.trim() || assisted?.affected_party_ref || ""
|
||||
)),
|
||||
...patch
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
async function uploadAttachments(files: File[]) {
|
||||
if (!instance || !definition) return;
|
||||
const available = Math.max(0, definition.max_attachments - attachmentRefs.length);
|
||||
@@ -385,14 +402,14 @@ export default function FormInstancePage({ settings, auth }: PlatformRouteContex
|
||||
refreshable
|
||||
reloadAction={{ onReload: () => void load(), loading }}
|
||||
className="form-instance-toolbar"
|
||||
contextActions={<>
|
||||
contextActions={<span className="form-instance-toolbar-context">
|
||||
<Button onClick={() => navigate("/forms-runtime")}>
|
||||
<ArrowLeft size={16} aria-hidden="true" />
|
||||
Forms
|
||||
</Button>
|
||||
{definition && <strong>{localized.title}</strong>}
|
||||
{instance && <StatusBadge status={editableLifecycle ? "active" : "inactive"} label={stateLabel(instance.status)} />}
|
||||
</>}
|
||||
</span>}
|
||||
primaryActions={instance && recordsAvailable && !editableLifecycle ?
|
||||
<Button onClick={() => navigate(recordFilingPath(instance))}>
|
||||
<Archive size={16} aria-hidden="true" />
|
||||
@@ -437,8 +454,10 @@ export default function FormInstancePage({ settings, auth }: PlatformRouteContex
|
||||
<div className="form-evidence-heading">
|
||||
<h2>Assisted intake context</h2>
|
||||
<StatusBadge
|
||||
status={assistedConfirmationCurrent ? "active" : "inactive"}
|
||||
label={assistedConfirmationCurrent ? "Read-back current" : "Read-back required"}
|
||||
status={assistedConfirmationCurrent || (!editableLifecycle && assistedConfirmations.length > 0) ? "active" : "inactive"}
|
||||
label={editableLifecycle
|
||||
? assistedConfirmationCurrent ? "Read-back current" : "Read-back required"
|
||||
: assistedConfirmations.length > 0 ? "Read-back recorded" : "No read-back evidence"}
|
||||
/>
|
||||
</div>
|
||||
<DescriptionList columns={3} collapseAt="workspace" density="compact">
|
||||
@@ -697,26 +716,70 @@ export default function FormInstancePage({ settings, auth }: PlatformRouteContex
|
||||
<CoreFormField label="Confirming party reference">
|
||||
<input value={assistedConfirmedBy} onChange={(event) => setAssistedConfirmedBy(event.target.value)} disabled={saving} required />
|
||||
</CoreFormField>
|
||||
<CoreFormField label="Value source" help="Applied to each populated field in this first assisted-intake slice.">
|
||||
<select value={assistedSource} onChange={(event) => setAssistedSource(event.target.value as typeof assistedSource)} disabled={saving}>
|
||||
<option value="person_statement">Person statement</option>
|
||||
<option value="representative_statement">Representative statement</option>
|
||||
<option value="document">Document</option>
|
||||
<option value="system">Existing system</option>
|
||||
<option value="derived">Derived by operator</option>
|
||||
</select>
|
||||
</CoreFormField>
|
||||
<CoreFormField label="Source confidence">
|
||||
<select value={assistedConfidence} onChange={(event) => setAssistedConfidence(event.target.value as typeof assistedConfidence)} disabled={saving}>
|
||||
<option value="stated">Stated</option>
|
||||
<option value="verified">Verified</option>
|
||||
<option value="uncertain">Uncertain</option>
|
||||
</select>
|
||||
</CoreFormField>
|
||||
<CoreFormField label={assistedOutcome === "confirmed" ? "Note (optional)" : "Correction or exception note"}>
|
||||
<textarea rows={3} value={assistedNote} onChange={(event) => setAssistedNote(event.target.value)} disabled={saving} required={assistedOutcome !== "confirmed"} />
|
||||
</CoreFormField>
|
||||
</FormGrid>
|
||||
<section className="form-assisted-field-sources" aria-labelledby="assisted-field-sources-heading">
|
||||
<header>
|
||||
<h3 id="assisted-field-sources-heading">Source of each populated value</h3>
|
||||
<p>Classify every value independently. Use a governed party, document, or system reference instead of repeating sensitive evidence in free text.</p>
|
||||
</header>
|
||||
<div className="form-assisted-field-source-list">
|
||||
{Object.entries(values)
|
||||
.filter(([, value]) => value !== null && value !== undefined && value !== "")
|
||||
.map(([fieldKey]) => {
|
||||
const source = assistedFieldSources[fieldKey] ?? defaultAssistedFieldSource(
|
||||
assistedConfirmedBy.trim() || assisted?.affected_party_ref || ""
|
||||
);
|
||||
const fieldLabel = localized.fieldLabels[fieldKey]
|
||||
?? definition?.fields.find((field) => field.key === fieldKey)?.label
|
||||
?? humanize(fieldKey);
|
||||
return (
|
||||
<fieldset key={fieldKey} className="form-assisted-field-source">
|
||||
<legend>{fieldLabel}</legend>
|
||||
<FormGrid columns={3} gap="small" collapseAt="workspace">
|
||||
<CoreFormField label="Value source">
|
||||
<select
|
||||
value={source.source}
|
||||
onChange={(event) => changeAssistedFieldSource(fieldKey, {
|
||||
source: event.target.value as typeof source.source
|
||||
})}
|
||||
disabled={saving}>
|
||||
<option value="person_statement">Person statement</option>
|
||||
<option value="representative_statement">Representative statement</option>
|
||||
<option value="document">Document</option>
|
||||
<option value="system">Existing system</option>
|
||||
<option value="derived">Derived by operator</option>
|
||||
</select>
|
||||
</CoreFormField>
|
||||
<CoreFormField label="Source confidence">
|
||||
<select
|
||||
value={source.confidence}
|
||||
onChange={(event) => changeAssistedFieldSource(fieldKey, {
|
||||
confidence: event.target.value as typeof source.confidence
|
||||
})}
|
||||
disabled={saving}>
|
||||
<option value="stated">Stated</option>
|
||||
<option value="verified">Verified</option>
|
||||
<option value="uncertain">Uncertain</option>
|
||||
</select>
|
||||
</CoreFormField>
|
||||
<CoreFormField label="Declared by or source reference" help="Optional for derived values; otherwise identify the governed party, document, or source system.">
|
||||
<input
|
||||
value={source.declared_by_ref ?? ""}
|
||||
onChange={(event) => changeAssistedFieldSource(fieldKey, {
|
||||
declared_by_ref: event.target.value || null
|
||||
})}
|
||||
disabled={saving}
|
||||
/>
|
||||
</CoreFormField>
|
||||
</FormGrid>
|
||||
</fieldset>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
</Dialog>
|
||||
<ConfirmDialog
|
||||
open={confirmingAcknowledgement}
|
||||
@@ -955,6 +1018,70 @@ function intakeContext(instance: FormInstance | null): AssistedIntakeContext | n
|
||||
};
|
||||
}
|
||||
|
||||
function defaultAssistedFieldSource(
|
||||
declaredByRef: string
|
||||
): AssistedIntakeContext["field_sources"][string] {
|
||||
return {
|
||||
source: "person_statement",
|
||||
confidence: "stated",
|
||||
declared_by_ref: declaredByRef || null
|
||||
};
|
||||
}
|
||||
|
||||
function assistedSourcesForRevision(
|
||||
instance: FormInstance,
|
||||
assisted: AssistedIntakeContext | null,
|
||||
confirmations: AssistedConfirmation[]
|
||||
): AssistedIntakeContext["field_sources"] {
|
||||
const currentConfirmation = confirmations.find(
|
||||
(confirmation) => confirmation.instance_revision === instance.revision
|
||||
);
|
||||
const confirmedSources = currentConfirmation?.metadata?.field_sources;
|
||||
return normalizeAssistedFieldSources(confirmedSources)
|
||||
?? assisted?.field_sources
|
||||
?? {};
|
||||
}
|
||||
|
||||
function normalizeAssistedFieldSources(
|
||||
value: unknown
|
||||
): AssistedIntakeContext["field_sources"] | null {
|
||||
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
||||
const result: AssistedIntakeContext["field_sources"] = {};
|
||||
for (const [fieldKey, candidate] of Object.entries(value)) {
|
||||
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
|
||||
const source = (candidate as Record<string, unknown>).source;
|
||||
const confidence = (candidate as Record<string, unknown>).confidence;
|
||||
const declaredByRef = (candidate as Record<string, unknown>).declared_by_ref;
|
||||
if (!isAssistedSource(source) || !isAssistedConfidence(confidence)) continue;
|
||||
result[fieldKey] = {
|
||||
source,
|
||||
confidence,
|
||||
declared_by_ref: typeof declaredByRef === "string" && declaredByRef.trim()
|
||||
? declaredByRef
|
||||
: null
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function isAssistedSource(
|
||||
value: unknown
|
||||
): value is AssistedIntakeContext["field_sources"][string]["source"] {
|
||||
return [
|
||||
"person_statement",
|
||||
"representative_statement",
|
||||
"document",
|
||||
"system",
|
||||
"derived"
|
||||
].includes(String(value));
|
||||
}
|
||||
|
||||
function isAssistedConfidence(
|
||||
value: unknown
|
||||
): value is AssistedIntakeContext["field_sources"][string]["confidence"] {
|
||||
return ["stated", "verified", "uncertain"].includes(String(value));
|
||||
}
|
||||
|
||||
function statusAccessMessage(mode: "authenticated" | "email_link" | "permanent_link"): string {
|
||||
if (mode === "authenticated") return "Only the bound applicant account can open this status page.";
|
||||
if (mode === "email_link") return "The applicant uses this tracking ID and linked email address to request an expiring link.";
|
||||
@@ -989,9 +1116,11 @@ export function visibleGroups(definition: FormDefinition, values: Record<string,
|
||||
}
|
||||
|
||||
function evaluateCondition(condition: NonNullable<FormFieldDefinition["visibility_condition"]>, values: Record<string, unknown>): boolean {
|
||||
if (condition.kind === "all") return condition.conditions.every((item) => evaluateCondition(item, values));
|
||||
if (condition.kind === "any") return condition.conditions.some((item) => evaluateCondition(item, values));
|
||||
if (condition.kind === "not") return !evaluateCondition(condition.conditions[0], values);
|
||||
if ("conditions" in condition) {
|
||||
if (condition.kind === "all") return condition.conditions.every((item) => evaluateCondition(item, values));
|
||||
if (condition.kind === "any") return condition.conditions.some((item) => evaluateCondition(item, values));
|
||||
return !evaluateCondition(condition.conditions[0], values);
|
||||
}
|
||||
const actual = values[condition.field_key];
|
||||
const expected = condition.value;
|
||||
switch (condition.operator) {
|
||||
|
||||
@@ -19,7 +19,7 @@ import { Button,
|
||||
type PlatformRouteContext
|
||||
} from "@govoplan/core-webui";
|
||||
import { listFormInstances, type FormInstance } from "../../api/formsRuntime";
|
||||
import { FORMS_RUNTIME_DOCUMENTATION, FORMS_RUNTIME_I18N } from "./interfacePatterns";
|
||||
import { FORMS_RUNTIME_DOCUMENTATION } from "./interfacePatterns";
|
||||
import IntakeProfilesDialog from "./IntakeProfilesDialog";
|
||||
import AssistedIntakeDialog from "./AssistedIntakeDialog";
|
||||
import StatusAccessPoliciesDialog from "./StatusAccessPoliciesDialog";
|
||||
|
||||
@@ -120,7 +120,85 @@ const en = {
|
||||
"Submission received": "Submission received",
|
||||
"Receipt": "Receipt",
|
||||
"Submit Form": "Submit Form",
|
||||
"Submit this Form? The values and managed attachment references become an immutable submission revision.": "Submit this Form? The values and managed attachment references become an immutable submission revision."
|
||||
"Submit this Form? The values and managed attachment references become an immutable submission revision.": "Submit this Form? The values and managed attachment references become an immutable submission revision.",
|
||||
"Assisted intake": "Assisted intake",
|
||||
"Start assisted intake": "Start assisted intake",
|
||||
"Capture who is acting, for whom, through which channel, and for what purpose before entering Form values.": "Capture who is acting, for whom, through which channel, and for what purpose before entering Form values.",
|
||||
"Cancel": "Cancel",
|
||||
"Start session": "Start session",
|
||||
"Loading assisted intake profiles": "Loading assisted intake profiles",
|
||||
"No assisted intake profile is enabled. Ask a Forms Runtime administrator to add one for the published Form.": "No assisted intake profile is enabled. Ask a Forms Runtime administrator to add one for the published Form.",
|
||||
"Intake channel": "Intake channel",
|
||||
"Service counter": "Service counter",
|
||||
"Telephone": "Telephone",
|
||||
"Paper": "Paper",
|
||||
"Email": "Email",
|
||||
"Mobile service": "Mobile service",
|
||||
"Representative": "Representative",
|
||||
"Offline import": "Offline import",
|
||||
"Affected party reference": "Affected party reference",
|
||||
"Use the governed person or organization reference; do not enter a display name only.": "Use the governed person or organization reference; do not enter a display name only.",
|
||||
"Represented party reference": "Represented party reference",
|
||||
"Optional when the affected party is acting directly.": "Optional when the affected party is acting directly.",
|
||||
"Authority basis": "Authority basis",
|
||||
"Acting for self": "Acting for self",
|
||||
"Documented representation": "Documented representation",
|
||||
"Legal guardianship": "Legal guardianship",
|
||||
"Statutory authority": "Statutory authority",
|
||||
"Responsible function reference": "Responsible function reference",
|
||||
"Purpose": "Purpose",
|
||||
"Legal basis reference": "Legal basis reference",
|
||||
"Consent basis": "Consent basis",
|
||||
"Accessibility or communication support": "Accessibility or communication support",
|
||||
"Separate multiple needs with commas.": "Separate multiple needs with commas.",
|
||||
"Privacy and procedural notice was provided": "Privacy and procedural notice was provided",
|
||||
"Record the fact of notice here; retain any separately required evidence through its owning module.": "Record the fact of notice here; retain any separately required evidence through its owning module.",
|
||||
"Assisted intake context": "Assisted intake context",
|
||||
"Read-back current": "Read-back current",
|
||||
"Read-back required": "Read-back required",
|
||||
"Read-back recorded": "Read-back recorded",
|
||||
"No read-back evidence": "No read-back evidence",
|
||||
"Channel": "Channel",
|
||||
"Affected party": "Affected party",
|
||||
"Represented party": "Represented party",
|
||||
"Authority": "Authority",
|
||||
"Responsible function": "Responsible function",
|
||||
"Notice": "Notice",
|
||||
"Provided": "Provided",
|
||||
"Not recorded": "Not recorded",
|
||||
"Language": "Language",
|
||||
"Communication support": "Communication support",
|
||||
"This context records provenance and does not bypass the published Form rules. Any saved correction invalidates the earlier read-back for submission.": "This context records provenance and does not bypass the published Form rules. Any saved correction invalidates the earlier read-back for submission.",
|
||||
"Read back and submit": "Read back and submit",
|
||||
"Record assisted read-back": "Record assisted read-back",
|
||||
"Make the exact values and managed evidence available to the confirming party. Record corrections before continuing; the server binds this evidence to the current revision and submission payload.": "Make the exact values and managed evidence available to the confirming party. Record corrections before continuing; the server binds this evidence to the current revision and submission payload.",
|
||||
"Record and continue": "Record and continue",
|
||||
"Outcome": "Outcome",
|
||||
"Confirmed without correction": "Confirmed without correction",
|
||||
"Corrected and confirmed": "Corrected and confirmed",
|
||||
"Confirmation unavailable": "Confirmation unavailable",
|
||||
"Confirmation method": "Confirmation method",
|
||||
"Spoken read-back": "Spoken read-back",
|
||||
"Written preview": "Written preview",
|
||||
"Accessible copy": "Accessible copy",
|
||||
"Unavailable": "Unavailable",
|
||||
"Confirming party reference": "Confirming party reference",
|
||||
"Note (optional)": "Note (optional)",
|
||||
"Correction or exception note": "Correction or exception note",
|
||||
"Source of each populated value": "Source of each populated value",
|
||||
"Classify every value independently. Use a governed party, document, or system reference instead of repeating sensitive evidence in free text.": "Classify every value independently. Use a governed party, document, or system reference instead of repeating sensitive evidence in free text.",
|
||||
"Value source": "Value source",
|
||||
"Person statement": "Person statement",
|
||||
"Representative statement": "Representative statement",
|
||||
"Document": "Document",
|
||||
"Existing system": "Existing system",
|
||||
"Derived by operator": "Derived by operator",
|
||||
"Source confidence": "Source confidence",
|
||||
"Stated": "Stated",
|
||||
"Verified": "Verified",
|
||||
"Uncertain": "Uncertain",
|
||||
"Declared by or source reference": "Declared by or source reference",
|
||||
"Optional for derived values; otherwise identify the governed party, document, or source system.": "Optional for derived values; otherwise identify the governed party, document, or source system."
|
||||
} as const;
|
||||
|
||||
const de: Record<keyof typeof en, string> = {
|
||||
@@ -243,7 +321,85 @@ const de: Record<keyof typeof en, string> = {
|
||||
"Submission received": "Übermittlung eingegangen",
|
||||
"Receipt": "Beleg",
|
||||
"Submit Form": "Formular absenden",
|
||||
"Submit this Form? The values and managed attachment references become an immutable submission revision.": "Dieses Formular absenden? Die Werte und Referenzen auf verwaltete Anhänge werden zu einer unveränderlichen Übermittlungsrevision."
|
||||
"Submit this Form? The values and managed attachment references become an immutable submission revision.": "Dieses Formular absenden? Die Werte und Referenzen auf verwaltete Anhänge werden zu einer unveränderlichen Übermittlungsrevision.",
|
||||
"Assisted intake": "Assistierte Erfassung",
|
||||
"Start assisted intake": "Assistierte Erfassung starten",
|
||||
"Capture who is acting, for whom, through which channel, and for what purpose before entering Form values.": "Erfassen Sie vor den Formularwerten, wer für wen, über welchen Kanal und zu welchem Zweck handelt.",
|
||||
"Cancel": "Abbrechen",
|
||||
"Start session": "Sitzung starten",
|
||||
"Loading assisted intake profiles": "Profile für die assistierte Erfassung werden geladen",
|
||||
"No assisted intake profile is enabled. Ask a Forms Runtime administrator to add one for the published Form.": "Es ist kein Profil für die assistierte Erfassung aktiviert. Bitten Sie die Formularadministration, eines für das veröffentlichte Formular einzurichten.",
|
||||
"Intake channel": "Erfassungskanal",
|
||||
"Service counter": "Serviceschalter",
|
||||
"Telephone": "Telefon",
|
||||
"Paper": "Papier",
|
||||
"Email": "E-Mail",
|
||||
"Mobile service": "Mobiler Dienst",
|
||||
"Representative": "Vertretung",
|
||||
"Offline import": "Offline-Import",
|
||||
"Affected party reference": "Referenz der betroffenen Partei",
|
||||
"Use the governed person or organization reference; do not enter a display name only.": "Verwenden Sie die geregelte Personen- oder Organisationsreferenz, nicht nur einen Anzeigenamen.",
|
||||
"Represented party reference": "Referenz der vertretenen Partei",
|
||||
"Optional when the affected party is acting directly.": "Optional, wenn die betroffene Partei selbst handelt.",
|
||||
"Authority basis": "Befugnisgrundlage",
|
||||
"Acting for self": "Handelt für sich selbst",
|
||||
"Documented representation": "Dokumentierte Vertretung",
|
||||
"Legal guardianship": "Gesetzliche Betreuung",
|
||||
"Statutory authority": "Gesetzliche Befugnis",
|
||||
"Responsible function reference": "Referenz der zuständigen Funktion",
|
||||
"Purpose": "Zweck",
|
||||
"Legal basis reference": "Referenz der Rechtsgrundlage",
|
||||
"Consent basis": "Einwilligungsgrundlage",
|
||||
"Accessibility or communication support": "Barrierefreiheits- oder Kommunikationsunterstützung",
|
||||
"Separate multiple needs with commas.": "Trennen Sie mehrere Bedarfe durch Kommas.",
|
||||
"Privacy and procedural notice was provided": "Datenschutz- und Verfahrenshinweis wurde erteilt",
|
||||
"Record the fact of notice here; retain any separately required evidence through its owning module.": "Erfassen Sie hier die Erteilung; gesondert erforderliche Nachweise verbleiben im zuständigen Modul.",
|
||||
"Assisted intake context": "Kontext der assistierten Erfassung",
|
||||
"Read-back current": "Rücklesen aktuell",
|
||||
"Read-back required": "Rücklesen erforderlich",
|
||||
"Read-back recorded": "Rücklesen erfasst",
|
||||
"No read-back evidence": "Kein Rücklesenachweis",
|
||||
"Channel": "Kanal",
|
||||
"Affected party": "Betroffene Partei",
|
||||
"Represented party": "Vertretene Partei",
|
||||
"Authority": "Befugnis",
|
||||
"Responsible function": "Zuständige Funktion",
|
||||
"Notice": "Hinweis",
|
||||
"Provided": "Erteilt",
|
||||
"Not recorded": "Nicht erfasst",
|
||||
"Language": "Sprache",
|
||||
"Communication support": "Kommunikationsunterstützung",
|
||||
"This context records provenance and does not bypass the published Form rules. Any saved correction invalidates the earlier read-back for submission.": "Dieser Kontext erfasst die Herkunft und umgeht die Regeln des veröffentlichten Formulars nicht. Jede gespeicherte Korrektur macht das frühere Rücklesen für die Einreichung ungültig.",
|
||||
"Read back and submit": "Rücklesen und absenden",
|
||||
"Record assisted read-back": "Assistiertes Rücklesen erfassen",
|
||||
"Make the exact values and managed evidence available to the confirming party. Record corrections before continuing; the server binds this evidence to the current revision and submission payload.": "Stellen Sie der bestätigenden Partei die exakten Werte und verwalteten Nachweise bereit. Erfassen Sie Korrekturen vor dem Fortfahren; der Server bindet diesen Nachweis an die aktuelle Revision und die Einreichungsnutzdaten.",
|
||||
"Record and continue": "Erfassen und fortfahren",
|
||||
"Outcome": "Ergebnis",
|
||||
"Confirmed without correction": "Ohne Korrektur bestätigt",
|
||||
"Corrected and confirmed": "Korrigiert und bestätigt",
|
||||
"Confirmation unavailable": "Bestätigung nicht verfügbar",
|
||||
"Confirmation method": "Bestätigungsmethode",
|
||||
"Spoken read-back": "Mündliches Rücklesen",
|
||||
"Written preview": "Schriftliche Vorschau",
|
||||
"Accessible copy": "Barrierefreie Kopie",
|
||||
"Unavailable": "Nicht verfügbar",
|
||||
"Confirming party reference": "Referenz der bestätigenden Partei",
|
||||
"Note (optional)": "Notiz (optional)",
|
||||
"Correction or exception note": "Korrektur- oder Ausnahmenotiz",
|
||||
"Source of each populated value": "Quelle jedes ausgefüllten Werts",
|
||||
"Classify every value independently. Use a governed party, document, or system reference instead of repeating sensitive evidence in free text.": "Klassifizieren Sie jeden Wert einzeln. Verwenden Sie eine geregelte Partei-, Dokument- oder Systemreferenz, statt sensible Nachweise im Freitext zu wiederholen.",
|
||||
"Value source": "Wertquelle",
|
||||
"Person statement": "Angabe der Person",
|
||||
"Representative statement": "Angabe der Vertretung",
|
||||
"Document": "Dokument",
|
||||
"Existing system": "Bestehendes System",
|
||||
"Derived by operator": "Durch Bearbeitung abgeleitet",
|
||||
"Source confidence": "Quellenvertrauen",
|
||||
"Stated": "Angegeben",
|
||||
"Verified": "Geprüft",
|
||||
"Uncertain": "Unsicher",
|
||||
"Declared by or source reference": "Erklärende Partei oder Quellenreferenz",
|
||||
"Optional for derived values; otherwise identify the governed party, document, or source system.": "Bei abgeleiteten Werten optional; sonst die geregelte Partei, das Dokument oder Quellsystem angeben."
|
||||
};
|
||||
|
||||
export const generatedTranslations: PlatformTranslations = { en, de };
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ const routeScopes = [
|
||||
export const formsRuntimeModule: PlatformWebModule = {
|
||||
id: "forms_runtime",
|
||||
label: "i18n:govoplan-forms-runtime.forms",
|
||||
version: "0.1.19",
|
||||
version: "0.1.20",
|
||||
dependencies: ["access", "forms"],
|
||||
optionalDependencies: ["files", "approvals", "workflow_engine", "portal", "cases", "records", "policy", "audit"],
|
||||
translations: generatedTranslations,
|
||||
|
||||
@@ -21,6 +21,21 @@
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.form-instance-toolbar-context {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.form-instance-toolbar-context > strong {
|
||||
min-width: 0;
|
||||
flex: 1 1 180px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.forms-runtime-list-viewport,
|
||||
.form-instance-viewport {
|
||||
flex: 1;
|
||||
@@ -278,6 +293,46 @@
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.form-assisted-field-sources {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
margin-top: 18px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.form-assisted-field-sources > header h3,
|
||||
.form-assisted-field-sources > header p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.form-assisted-field-sources > header p {
|
||||
margin-top: 5px;
|
||||
color: var(--text-soft);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.form-assisted-field-source-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.form-assisted-field-source {
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-compact);
|
||||
background: var(--surface-subtle);
|
||||
}
|
||||
|
||||
.form-assisted-field-source legend {
|
||||
padding-inline: 5px;
|
||||
color: var(--text-strong);
|
||||
font-size: 0.84rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.form-status-policy-save {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
@@ -557,6 +612,19 @@
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.form-instance-toolbar .page-action-slot-context {
|
||||
max-width: 100%;
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
|
||||
.form-instance-toolbar-context {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-instance-toolbar-context .status-badge {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.form-instance-content {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user