import type { KeyboardEvent as ReactKeyboardEvent } from "react"; import { HOURS_PER_DAY, formatTimeOfDayHours } from "../document/project-time-settings"; import type { ProjectNpcActorRecord } from "../entities/npc-actor-registry"; import { PROJECT_SCHEDULE_WEEKDAYS, formatProjectScheduleDaySelection, formatProjectScheduleWeekdayLabel, getProjectScheduleTimelineSegments, type ProjectScheduler, type ProjectScheduleRoutine, type ProjectScheduleWeekday } from "../scheduler/project-scheduler"; interface ProjectSchedulePaneProps { actors: ProjectNpcActorRecord[]; scheduler: ProjectScheduler; selectedRoutineId: string | null; onSelectRoutine(routineId: string | null): void; onAddRoutine(actorId: string): void; onDeleteRoutine(routineId: string): void; onClose(): void; onSetRoutineActor(routineId: string, actorId: string): void; onSetRoutineTitle(routineId: string, title: string): void; onSetRoutineEnabled(routineId: string, enabled: boolean): void; onSetRoutineStartHour(routineId: string, startHour: number): void; onSetRoutineEndHour(routineId: string, endHour: number): void; onSetRoutinePriority(routineId: string, priority: number): void; onSetRoutinePresence(routineId: string, active: boolean): void; onSetRoutineDays( routineId: string, mode: "everyDay" | "selectedDays", days: ProjectScheduleWeekday[] ): void; } function handleCommitOnEnter( event: ReactKeyboardEvent, commit: () => void ) { if (event.key !== "Enter") { return; } event.currentTarget.blur(); commit(); } function getRoutineSummary(routine: ProjectScheduleRoutine): string { return `${formatProjectScheduleDaySelection(routine.days)} · ${formatTimeOfDayHours(routine.startHour)}-${formatTimeOfDayHours(routine.endHour)} · P${routine.priority}`; } export function ProjectSchedulePane({ actors, scheduler, selectedRoutineId, onSelectRoutine, onAddRoutine, onDeleteRoutine, onClose, onSetRoutineActor, onSetRoutineTitle, onSetRoutineEnabled, onSetRoutineStartHour, onSetRoutineEndHour, onSetRoutinePriority, onSetRoutinePresence, onSetRoutineDays }: ProjectSchedulePaneProps) { const selectedRoutine = selectedRoutineId === null ? null : scheduler.routines[selectedRoutineId] ?? null; const hourTicks = Array.from({ length: HOURS_PER_DAY }, (_, hour) => hour); const selectedRoutineDays = selectedRoutine === null ? PROJECT_SCHEDULE_WEEKDAYS : selectedRoutine.days.mode === "everyDay" ? PROJECT_SCHEDULE_WEEKDAYS : selectedRoutine.days.days; return (
Schedule
Scheduler-owned actor orchestration over global project time.
Actors
{hourTicks.map((hour) => (
{String(hour).padStart(2, "0")}
))}
{actors.length === 0 ? (
No NPC actors are authored in this project yet.
) : ( actors.map((actor) => { const routines = Object.values(scheduler.routines) .filter( (routine) => routine.target.kind === "actor" && routine.target.actorId === actor.actorId ) .sort((left, right) => left.startHour - right.startHour); return (
{actor.label}
{actor.actorId} {actor.usages.length > 1 ? ` · ${actor.usages.length} usages` : ""}
{routines.map((routine) => getProjectScheduleTimelineSegments(routine).map( (segment) => ( ) ) )}
); }) )}
); }