Der Wiedereintritt war da, nur nicht erreichbar

Aus dem Gespraech vom 17.09.2026.

Der Kunde suchte den Knopf "Wiedereintritt" an einer ausgetretenen Person
und hielt ihn fuer verschwunden — "ich dachte eigentlich, das ist schon
implementiert, das war mal drin". Er war drin. Er hing nur an
employee.status, und diese Spalte haengt nach: an einer Person, deren
Austritt erfasst und inzwischen vollzogen war, stand dort weiter "Aktiv".

Das ist mein Fehler beim Statusfix. Umgestellt waren dort `isActive` und
`canEditData` — die fuenf einzelnen Abfragen in derselben Datei blieben
stehen, dazu je eine in KarenzPanel und TerminatePanel. Jetzt liest keine
mehr die Spalte; die beiden Panels bekommen den abgeleiteten Status
uebergeben, statt ihn sich selbst aus der Zeile zu holen.

Betroffen war ausser dem Wiedereintritt auch: welcher Austritts-Knopf
erscheint ("Nicht angetreten" statt "Austritt"), die Beschriftung der
Abwesenheit, die Vorbelegung der Beendigungsart und ob die Zugehoerigkeit
angezeigt wird.

Dazu: die Niederlassung ist aus dem Reiter Organisation wieder raus. Sie
stand dort als unsere Auslegung von Anforderung 8; der Kunde hat sie im
Gespraech gestrichen ("nimm's mal hier raus"). Was mit der Anforderung
gemeint war, bleibt offen.
This commit is contained in:
2026-09-17 11:50:26 +02:00
parent bf7f59a959
commit 4165f3f8a1
5 changed files with 69 additions and 39 deletions

View File

@@ -10,16 +10,27 @@ import { SlideOver } from "@/components/ui/SlideOver";
import { useToast } from "@/components/ui/Toast";
import { ABSENCE_TYPES, absenceLabel, RUECKKEHR_GRUENDE } from "@/lib/absence";
import { fmtDate, fmtName } from "@/lib/format";
import type { Database } from "@/lib/types";
import type { Database, EmploymentStatus } from "@/lib/types";
type EmployeeRow = Database["public"]["Tables"]["employees"]["Row"];
type Mode = "adjust" | "return";
type EmploymentMode = "unverändert" | "Vollzeit" | "Teilzeit";
export function KarenzPanel({ open, onClose, employee }: { open: boolean; onClose: () => void; employee: EmployeeRow }) {
export function KarenzPanel({
open,
onClose,
employee,
status,
}: {
open: boolean;
onClose: () => void;
employee: EmployeeRow;
/** Der zum heutigen Tag abgeleitete Status — nicht `employee.status`, die Spalte hängt nach. */
status: EmploymentStatus;
}) {
const { showToast } = useToast();
const router = useRouter();
const isOnKarenz = employee.status === "Karenz";
const isOnKarenz = status === "Karenz";
const [mode, setMode] = useState<Mode>("adjust");
const [pending, setPending] = useState(false);
@@ -188,7 +199,7 @@ export function KarenzPanel({ open, onClose, employee }: { open: boolean; onClos
{mode === "adjust" && (
<>
<p className="rounded bg-surface px-3 py-2 text-sm text-ink-body">
<span className="font-semibold">{absenceLabel(employee.status, employee.absence_type)}</span>
<span className="font-semibold">{absenceLabel(status, employee.absence_type)}</span>
{" · Rückkehr "}
{fmtDate(employee.karenz_return_date)}
</p>

View File

@@ -15,7 +15,7 @@ import {
beendigungsartenZu,
type Austrittsart,
} from "@/lib/beendigung";
import type { Database } from "@/lib/types";
import type { Database, EmploymentStatus } from "@/lib/types";
import { fmtDate, fmtName } from "@/lib/format";
type EmployeeRow = Database["public"]["Tables"]["employees"]["Row"];
@@ -28,17 +28,19 @@ type TerminatePanelProps = {
open: boolean;
onClose: () => void;
employee: EmployeeRow;
/** Der zum heutigen Tag abgeleitete Status — nicht `employee.status`, die Spalte hängt nach. */
status: EmploymentStatus;
directReportCount: number;
};
export function TerminatePanel({ open, onClose, employee, directReportCount }: TerminatePanelProps) {
export function TerminatePanel({ open, onClose, employee, status, directReportCount }: TerminatePanelProps) {
const { showToast } = useToast();
const router = useRouter();
const [exitDate, setExitDate] = useState("");
// Wer noch gar nicht angefangen hat, tritt fast nie aus einem anderen Grund
// aus. Die Vorbelegung nimmt den wahrscheinlichen Fall vorweg, ohne die
// übrigen zu verstellen.
const [reason, setReason] = useState(employee.status === "Geplant" ? NO_SHOW : BEENDIGUNGSART_WERTE[0]);
const [reason, setReason] = useState(status === "Geplant" ? NO_SHOW : BEENDIGUNGSART_WERTE[0]);
// „Alle" statt einer Vorauswahl: die Einschränkung ist eine Hilfe beim
// Suchen, keine Pflichtangabe. Wer die gewünschte Art auswendig kennt,
// soll sie unmittelbar wählen können.