Surface exact service journey filing

This commit is contained in:
2026-08-06 12:42:20 +02:00
parent df51bb1787
commit 011c3880c8
3 changed files with 67 additions and 9 deletions
+59 -6
View File
@@ -58,6 +58,14 @@ import {
const EMPTY_CATALOG: RecordCatalog = { file_plan: [], classes: [] };
const PAGE_SIZE = 50;
type FilingPreset = {
sourceModule: string;
resourceType: string;
resourceId: string;
sourceRevision: string;
sourceLabel: string;
};
export default function RecordsPage({ settings, auth }: PlatformRouteContext) {
const [searchParams, setSearchParams] = useSearchParams();
const { selection, selectionKey, isDefault: temporalIsDefault } = useTemporalDataContext();
@@ -86,6 +94,7 @@ export default function RecordsPage({ settings, auth }: PlatformRouteContext) {
const canWrite = auth.scopes.includes("records:workspace:write") ||
auth.scopes.includes("records:workspace:admin");
const canAdmin = auth.scopes.includes("records:workspace:admin");
const filingPreset = useMemo(() => filingPresetFrom(searchParams), [searchParams]);
const reload = useCallback(() => setReloadKey((value) => value + 1), []);
@@ -267,6 +276,13 @@ export default function RecordsPage({ settings, auth }: PlatformRouteContext) {
</div>
{error && <DismissibleAlert tone="danger" resetKey={error}>{error}</DismissibleAlert>}
{filingPreset &&
<DismissibleAlert tone="info" dismissible={false} compact>
{i18nMessage("i18n:govoplan-records.source_ready", {
value0: filingPreset.sourceLabel || "An exact source revision"
})} {i18nMessage("i18n:govoplan-records.select_destination")}
</DismissibleAlert>
}
<div className="records-workspace">
<aside className="records-file-plan" data-help-context-id="records.file-plan">
<div className="records-pane-heading">
@@ -399,9 +415,11 @@ export default function RecordsPage({ settings, auth }: PlatformRouteContext) {
record={detail?.record ?? null}
volumes={detail?.volumes ?? []}
providers={sources}
preset={filingPreset}
onClose={() => setFileOpen(false)}
onSaved={() => {
setFileOpen(false);
clearFilingPreset(searchParams, setSearchParams);
reload();
}}
/>
@@ -691,6 +709,7 @@ function FilingDialog({
record,
volumes,
providers,
preset,
onClose,
onSaved
}: {
@@ -699,6 +718,7 @@ function FilingDialog({
record: RecordEntry | null;
volumes: RecordDetail["volumes"];
providers: RecordSourceProvider[];
preset: FilingPreset | null;
onClose: () => void;
onSaved: () => void;
}) {
@@ -715,16 +735,23 @@ function FilingDialog({
useEffect(() => {
if (!open) return;
const first = providers[0];
const requested = preset
? providers.find((item) => item.source_module === preset.sourceModule)
: undefined;
const first = requested ?? providers[0];
setSourceModule(first?.source_module ?? "");
setResourceType(first?.resource_types[0] ?? "");
setResourceId("");
setSourceRevision("");
setResourceType(
requested?.resource_types.includes(preset?.resourceType ?? "")
? preset!.resourceType
: first?.resource_types[0] ?? ""
);
setResourceId(requested ? preset?.resourceId ?? "" : "");
setSourceRevision(requested ? preset?.sourceRevision ?? "" : "");
setVolumeId("");
setPurpose(record?.purpose ?? "");
setFilingReason("");
setFilingReason(requested && preset?.sourceLabel ? `File ${preset.sourceLabel}.` : "");
setError("");
}, [open, providers, record?.purpose]);
}, [open, preset, providers, record?.purpose]);
useEffect(() => {
if (provider?.resource_types.includes(resourceType)) return;
@@ -862,6 +889,32 @@ function randomId(): string {
: `${Date.now()}-${Math.random().toString(16).slice(2)}`;
}
function filingPresetFrom(searchParams: URLSearchParams): FilingPreset | null {
const sourceModule = searchParams.get("sourceModule")?.trim() ?? "";
const resourceType = searchParams.get("resourceType")?.trim() ?? "";
const resourceId = searchParams.get("resourceId")?.trim() ?? "";
const sourceRevision = searchParams.get("sourceRevision")?.trim() ?? "";
if (!sourceModule || !resourceType || !resourceId || !sourceRevision) return null;
return {
sourceModule,
resourceType,
resourceId,
sourceRevision,
sourceLabel: (searchParams.get("sourceLabel")?.trim() ?? "").slice(0, 300)
};
}
function clearFilingPreset(
searchParams: URLSearchParams,
setSearchParams: ReturnType<typeof useSearchParams>[1]
) {
const next = new URLSearchParams(searchParams);
for (const key of ["sourceModule", "resourceType", "resourceId", "sourceRevision", "sourceLabel"]) {
next.delete(key);
}
setSearchParams(next, { replace: true });
}
function errorMessage(reason: unknown, fallback: string): string {
return reason instanceof Error && reason.message ? reason.message : fallback;
}
+4
View File
@@ -10,6 +10,8 @@ const en = {
"i18n:govoplan-records.record_detail": "Record detail",
"i18n:govoplan-records.file_source": "File source revision",
"i18n:govoplan-records.record_count": "{value0} records",
"i18n:govoplan-records.source_ready": "{value0} is ready for filing.",
"i18n:govoplan-records.select_destination": "Select the destination record, then choose File item.",
"Records": "Records",
"New record": "New record",
"Refresh": "Refresh",
@@ -161,6 +163,8 @@ const de: Record<keyof typeof en, string> = {
"i18n:govoplan-records.record_detail": "Aktendetails",
"i18n:govoplan-records.file_source": "Quellrevision verakten",
"i18n:govoplan-records.record_count": "{value0} Akten",
"i18n:govoplan-records.source_ready": "{value0} kann veraktet werden.",
"i18n:govoplan-records.select_destination": "Wählen Sie die Zielakte und anschließend Objekt verakten.",
"Records": "Akten",
"New record": "Neue Akte",
"Refresh": "Aktualisieren",