Zum Hauptinhalt springen
Sachbearbeiter-Cockpit

Mock-Modus

Die Library kann ohne ActaNova-Backend laufen: im Mock-Modus liefern die Services kuratierte Beispieldaten statt echter Requests. Das ist der schnellste Weg, ein Sachbearbeiter-Cockpit lokal zu entwickeln oder ein Widget vorzuführen.

Die Anmeldung ist davon nicht betroffen — Keycloak wird weiterhin gebraucht. Gemockt sind nur die Datenabrufe.

Einschalten

Beim Start der App

import { configureCockpit } from '@gentics/cockpit/core';

configureCockpit({ mock: true });

Einmal, bevor die erste Sachbearbeiter-Cockpit-Komponente rendert bzw. der erste Datenabruf läuft. Üblich ist es, den Wert aus einer Umgebungsvariable zu ziehen — die liest dein Projekt selbst aus, damit die Library bundler-unabhängig bleibt:

configureCockpit({ mock: import.meta.env.VITE_COCKPIT_MOCK === 'true' });

configureCockpit merget den Patch über die aktuelle Config; Teilangaben genügen. Den aktuellen Stand liest getConfig().

Zur Laufzeit in den DevTools

localStorage.setItem('cockpit:mock', 'true'); // danach Seite neu laden
localStorage.removeItem('cockpit:mock'); // zurück zur App-Config

Der localStorage-Wert überstimmt die App-Config — auch umgekehrt: 'false' erzwingt echte Requests, obwohl die App mock: true konfiguriert hat. Die Reihenfolge ist:

localStorage "cockpit:mock" → configureCockpit({ mock }) → false (Default)

Gelesen wird bei jedem Service-Aufruf neu, ein Reload genügt also; ein Rebuild ist nicht nötig.

Was gemockt ist — und was nicht

AufrufIm Mock-Modus
useFiles / useFile8 zusammenhängende Beispiel-Akten aus dem Behörden-/eGovernment-Kontext
useGroupsBeispielgruppen
useUsersBeispiel-User
usePersons / usePersonBeispiel-Personen
useDocumentsByFile3 Beispieldokumente je Akte
useUploadDocumentkein Request; die Datei landet in einem In-Memory-„Backend"
useSaveFilekein Request, liefert true — die Änderung wird nicht behalten
useCompleteActivitywird übersprungen
useCurrentUser{} — es gibt keine Mock-Daten für /Me
useAnnotations[] — es gibt keine Mock-Daten für Annotations

Der Mock-Datensatz ist mandantenneutral: jeder Tenant bekommt dieselben Daten. Die Akten tragen echte ActaNova-Feldnamen (title.de, formattedNumber, fileType.displayName, fileHandlingState, openingDate, leadingUser, leadingGroup, $apiId), sodass Spalten und jsonPath-Angaben sich genauso verhalten wie gegen das echte Backend.

Jeder gemockte Aufruf schreibt eine Zeile mit 🔧 in die Konsole — daran erkennst du auf einen Blick, ob der Modus aktiv ist.

Uploads sind ein echter Rundlauf

Eine im Mock-Modus hochgeladene Datei wird in eine Liste im Speicher gelegt und erscheint beim nächsten Laden der Dokumentliste tatsächlich — der Ablauf „hochladen → Liste aktualisiert sich" ist also testbar. Beim Reload ist der Stand wieder auf den drei Beispieldokumenten.

Gerechnet wird mit kurzen Verzögerungen (etwa 200 ms je Abruf, rund 1 s für einen Upload), damit Skeletons und Lade-Toasts sichtbar sind.

Der Datensatz im Detail

Damit du weißt, welche jsonPath-Angaben und Spalten im Mock-Modus tatsächlich etwas anzeigen: hier steht, was in den Mock-Daten drin ist.

Akten — useFiles, useFile

Jede der 8 Akten hat genau diese Felder:

FeldFormWerte im Datensatz
$apiTypeStringimmer "File"
$apiIdUUID-String8 verschiedene, siehe Tabelle unten
title.de / title.enObjektdeutscher und englischer Titel
displayNameStringidentisch mit title.de
formattedNumberString"2026/0431"-Form
numberZahlder Zähler ohne Jahr (431)
fileType.displayNameObjekt"Akte" (3×), "eGovernment-Akte" (5×)
subjectArea.displayNameObjekt8 verschiedene Fachgebiete (Bauwesen, Meldewesen, Abgaben, …)
fileHandlingStateString"Work" (5×), "Closed" (3×)
approvalStateString"Approved" (4×), "NotApproved" (4×)
leadingUserObjektdisplayName, $apiId, referencedApiType: "User"
leadingGroupObjektdisplayName, $apiId, referencedApiType: "Group"
createdAtISO-Datum mit Z2025 und 2026
openingDateISO-Datum ohne Zdito
closingDateISO-Datum oder nullgesetzt bei den 3 geschlossenen Akten
changedAtISO-Datum mit Zdito
yearZahl2025 (2×), 2026 (6×)
isPaperFileBooleantrue (2×), false (6×)
archiveimmer null
remarkString oder nullFreitext, bei 2 Akten null

Ein vollständiger Eintrag, so wie ihn useFile() liefert:

{
"$apiType": "File",
"$apiId": "0f9f8caa-1b7c-4170-8592-86e063da5b62",
"title": { "de": "Auskunftsersuchen Steiner (IFG)", "en": "Freedom-of-Information request Steiner" },
"displayName": "Auskunftsersuchen Steiner (IFG)",
"formattedNumber": "2026/0431",
"number": 431,
"fileType": { "displayName": "eGovernment-Akte" },
"subjectArea": { "displayName": "Informationsfreiheit" },
"fileHandlingState": "Work",
"approvalState": "NotApproved",
"leadingUser": {
"displayName": "Maria Huber",
"$apiId": "b2c3d4e5-0001-4a10-9b3e-200000000001",
"referencedApiType": "User"
},
"leadingGroup": {
"displayName": "Rechtsabteilung",
"$apiId": "a1b2c3d4-0001-4a10-9b3e-100000000001",
"referencedApiType": "Group"
},
"createdAt": "2026-02-11T10:38:53.868Z",
"openingDate": "2026-02-11T10:38:53",
"closingDate": null,
"changedAt": "2026-03-02T08:12:00.000Z",
"year": 2026,
"isPaperFile": false,
"archive": null,
"remark": "Frist für Beantwortung: 8 Wochen"
}

Die 8 Akten:

title.deformattedNumberfileType.displayNamefileHandlingState
Auskunftsersuchen Steiner (IFG)2026/0431eGovernment-AkteWork
Bauakte Musterstraße 122025/1187AkteWork
Gewerbeanmeldung Café Central2026/0089eGovernment-AkteClosed
Meldewesen – Zuzug Familie Novak2026/0512AkteWork
Förderantrag Photovoltaik-Anlage2026/0274eGovernment-AkteWork
Bürgeranfrage Straßenbeleuchtung2026/0603eGovernment-AkteClosed
Personenstandsakte Eheschließung Berger2025/0945AkteClosed
eZustellung Bescheid Abgabenkonto2026/0718eGovernment-AkteWork

Für Deep-Links und useFile(id) — die $apiId in derselben Reihenfolge:

0f9f8caa-1b7c-4170-8592-86e063da5b62 2026/0431 Auskunftsersuchen Steiner (IFG)
8c2d4e91-77af-4a10-9b3e-1f0a2b6c5d44 2025/1187 Bauakte Musterstraße 12
b41a90fe-2c33-4d8b-8e77-93a5c0117e21 2026/0089 Gewerbeanmeldung Café Central
d7e6c512-4b8a-42f0-9c1d-6a2f8b3e0d19 2026/0512 Meldewesen – Zuzug Familie Novak
1a5b8c02-9d4e-4f31-8271-0e6a4c9b7d33 2026/0274 Förderantrag Photovoltaik-Anlage
6f3e2d81-5a7c-4b09-9e14-2c8b1a6f4e07 2026/0603 Bürgeranfrage Straßenbeleuchtung
9b0c7a34-8e1f-4d52-8a63-5f2d9c0b1e88 2025/0945 Personenstandsakte Eheschließung Berger
3c8f1b60-2a9d-4e73-9146-7b0e5a2c8d55 2026/0718 eZustellung Bescheid Abgabenkonto

useFile() mit einer unbekannten Id liefert im Mock-Modus ein leeres Objekt {} — die Query ist dann erfolgreich, aber ohne Inhalt. Widgets zeigen dafür den Entwickler-Hinweis zum fehlenden Pfad, nicht einen Ladefehler.

Kein Eintrag hat fileHandlingState: "Destroyed". Der Filter, den useFiles gegen das echte Backend anwendet, ist im Mock-Modus also nie sichtbar.

Gruppen und User — useGroups, useUsers

Beide liefern Group-Objekte mit name, $apiId und referencedApiType:

useGroups() — 7 EinträgeuseUsers() — 5 Einträge
RechtsabteilungMaria Huber
BaubehördeJulia Wolf
BürgerservicePeter Lang
FinanzverwaltungSabine Mayr
GewerbereferatThomas Berger
Standesamt
Umweltreferat

Diese Namen und Ids sind dieselben wie in leadingGroup / leadingUser der Akten. Deshalb erkennt Assignment im Mock-Modus die bestehende Zuordnung und markiert sie vor — der Abgleich läuft über $apiId. Gespeichert wird trotzdem nichts (siehe Grenzen).

Dokumente — useDocumentsByFile

Drei Einträge in der Form DocumentSummary (name, size, url), identisch für jede File-Id:

namesize (Bytes)url
Auskunftsersuchen_Steiner.pdf84233https://example.com/mock/…
Bescheid_Abgabenkonto.pdf152119https://example.com/mock/…
Bauplan_Musterstrasse_12.pdf1048576https://example.com/mock/…

Die url zeigt auf example.com — der Download-Link ist also klickbar, führt aber ins Nichts.

Personen — usePersons, usePerson

Sechs Einträge mit $apiType: "Person", $apiId, firstName, lastName und fullName: Anna Steiner, Bernhard Gruber, Christina Fischer, Daniel Moser, Elisabeth Pichler, Florian Reiter. Wie bei den Akten liefert usePerson() mit unbekannter Id ein leeres Objekt.

Denk daran, dass usePersons nur mit enabled: true läuft — sonst bleibt die Liste auch im Mock-Modus leer.

Grenzen

  • Kein Schreiben. useSaveFile täuscht Erfolg vor, ohne etwas zu ändern. Eine gespeicherte Zuweisung ist nach dem Reload wieder weg.
  • Keine Mock-Daten für /Me. Das Profil-Menü fällt damit auf die Token-Claims zurück (Name, Benutzername, E-Mail aus Keycloak).
  • Die Mock-Daten sind nicht öffentlich importierbar. Sie liegen in der Library und lassen sich nicht aus @gentics/cockpit/core importieren oder erweitern. Wer eigene Testdaten braucht, gibt sie über eine eigene Datenquelle hinein — staticSource bzw. ein eigenes Store-Bündel.