Apply guided scheduling interface patterns

This commit is contained in:
2026-08-03 08:29:29 +02:00
parent 3e9a14a970
commit 3d8272b28e
7 changed files with 225 additions and 4 deletions
+29
View File
@@ -8,11 +8,40 @@ import {
participantDraftsFromPicker,
participantPayload,
schedulingInvitationActionBlocks,
schedulingLifecycleStages,
schedulingPublicInvitationUrl,
schedulingSortPhase,
type SchedulingActor
} from "../src/features/scheduling/schedulingViewModel.ts";
test("derives the scheduling lifecycle without inventing new backend states", () => {
assert.deepEqual(schedulingLifecycleStages("draft"), [
{ id: "prepare", state: "current", current: true, locked: false },
{ id: "participate", state: "locked", current: false, locked: true },
{ id: "decide", state: "locked", current: false, locked: true }
]);
assert.deepEqual(schedulingLifecycleStages("collecting"), [
{ id: "prepare", state: "complete", current: false, locked: false },
{ id: "participate", state: "current", current: true, locked: false },
{ id: "decide", state: "locked", current: false, locked: true }
]);
assert.deepEqual(schedulingLifecycleStages("closed"), [
{ id: "prepare", state: "complete", current: false, locked: false },
{ id: "participate", state: "complete", current: false, locked: false },
{ id: "decide", state: "current", current: true, locked: false }
]);
assert.deepEqual(schedulingLifecycleStages("handed_off").map((stage) => stage.state), [
"complete",
"complete",
"complete"
]);
assert.deepEqual(schedulingLifecycleStages("cancelled"), [
{ id: "prepare", state: "complete", current: false, locked: false },
{ id: "participate", state: "stopped", current: true, locked: false },
{ id: "decide", state: "locked", current: false, locked: true }
]);
});
test("maps visible account and contact selections into bounded scheduling participant payloads", () => {
let sequence = 0;
const selected = participantDraftsFromPicker([