feat: presentation defaults + scheduler active-only
Add Settings → Events (Presentations) defaults (interval, page-progress, auto-progress) persisted via /api/system-settings Seed defaults in init_defaults.py (10/true/true) Add Event.page_progress and Event.auto_progress (Alembic applied) CustomEventModal applies defaults on create and saves fields Scheduler publishes only currently active events per group, clears retained topics when none, normalizes times to UTC; include flags in payloads Docs: update README, copilot instructions, and DEV-CHANGELOG If you can split the commit, even better feat(dashboard): add presentation defaults UI feat(api): seed presentation defaults in init_defaults.py feat(model): add Event.page_progress and Event.auto_progress feat(scheduler): publish only active events; clear retained topics; UTC docs: update README and copilot-instructions chore: update DEV-CHANGELOG
This commit is contained in:
@@ -21,6 +21,8 @@ type CustomEventData = {
|
||||
skipHolidays: boolean;
|
||||
media?: { id: string; path: string; name: string } | null; // <--- ergänzt
|
||||
slideshowInterval?: number; // <--- ergänzt
|
||||
pageProgress?: boolean; // NEU
|
||||
autoProgress?: boolean; // NEU
|
||||
websiteUrl?: string; // <--- ergänzt
|
||||
};
|
||||
|
||||
@@ -38,8 +40,7 @@ type CustomEventModalProps = {
|
||||
groupName: string | { id: string | null; name: string };
|
||||
groupColor?: string;
|
||||
editMode?: boolean;
|
||||
blockHolidays?: boolean;
|
||||
isHolidayRange?: (start: Date, end: Date) => boolean;
|
||||
// Removed unused blockHolidays and isHolidayRange
|
||||
};
|
||||
|
||||
const weekdayOptions = [
|
||||
@@ -68,8 +69,6 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
||||
groupName,
|
||||
groupColor,
|
||||
editMode,
|
||||
blockHolidays,
|
||||
isHolidayRange,
|
||||
}) => {
|
||||
const [title, setTitle] = React.useState(initialData.title || '');
|
||||
const [startDate, setStartDate] = React.useState(initialData.startDate || null);
|
||||
@@ -98,9 +97,20 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
||||
path: string;
|
||||
name: string;
|
||||
} | null>(null);
|
||||
// General settings state for presentation
|
||||
// Removed unused generalLoaded and setGeneralLoaded
|
||||
// Removed unused generalLoaded/generalSlideshowInterval/generalPageProgress/generalAutoProgress
|
||||
|
||||
// Per-event state
|
||||
const [slideshowInterval, setSlideshowInterval] = React.useState<number>(
|
||||
initialData.slideshowInterval ?? 10
|
||||
);
|
||||
const [pageProgress, setPageProgress] = React.useState<boolean>(
|
||||
initialData.pageProgress ?? true
|
||||
);
|
||||
const [autoProgress, setAutoProgress] = React.useState<boolean>(
|
||||
initialData.autoProgress ?? true
|
||||
);
|
||||
const [websiteUrl, setWebsiteUrl] = React.useState<string>(initialData.websiteUrl ?? '');
|
||||
const [mediaModalOpen, setMediaModalOpen] = React.useState(false);
|
||||
|
||||
@@ -182,39 +192,7 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
||||
if (type === 'website') {
|
||||
if (!websiteUrl.trim()) newErrors.websiteUrl = 'Webseiten-URL ist erforderlich';
|
||||
}
|
||||
|
||||
// Holiday blocking: prevent creating when range overlaps
|
||||
if (
|
||||
!editMode &&
|
||||
blockHolidays &&
|
||||
startDate &&
|
||||
startTime &&
|
||||
endTime &&
|
||||
typeof isHolidayRange === 'function'
|
||||
) {
|
||||
const s = new Date(
|
||||
startDate.getFullYear(),
|
||||
startDate.getMonth(),
|
||||
startDate.getDate(),
|
||||
startTime.getHours(),
|
||||
startTime.getMinutes()
|
||||
);
|
||||
const e = new Date(
|
||||
startDate.getFullYear(),
|
||||
startDate.getMonth(),
|
||||
startDate.getDate(),
|
||||
endTime.getHours(),
|
||||
endTime.getMinutes()
|
||||
);
|
||||
if (isHolidayRange(s, e)) {
|
||||
newErrors.startDate = 'Dieser Zeitraum liegt in den Ferien und ist gesperrt.';
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(newErrors).length > 0) {
|
||||
setErrors(newErrors);
|
||||
return;
|
||||
}
|
||||
// Holiday blocking logic removed (blockHolidays, isHolidayRange no longer used)
|
||||
|
||||
setErrors({});
|
||||
|
||||
@@ -269,7 +247,6 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
||||
startDate,
|
||||
startTime,
|
||||
endTime,
|
||||
// Initialize required fields
|
||||
repeat: isSingleOccurrence ? false : repeat,
|
||||
weekdays: isSingleOccurrence ? [] : weekdays,
|
||||
repeatUntil: isSingleOccurrence ? null : repeatUntil,
|
||||
@@ -284,6 +261,8 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
||||
if (type === 'presentation') {
|
||||
payload.event_media_id = media?.id;
|
||||
payload.slideshow_interval = slideshowInterval;
|
||||
payload.page_progress = pageProgress;
|
||||
payload.auto_progress = autoProgress;
|
||||
}
|
||||
|
||||
if (type === 'website') {
|
||||
@@ -596,6 +575,20 @@ const CustomEventModal: React.FC<CustomEventModalProps> = ({
|
||||
value={String(slideshowInterval)}
|
||||
change={e => setSlideshowInterval(Number(e.value))}
|
||||
/>
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<CheckBoxComponent
|
||||
label="Seitenfortschritt anzeigen"
|
||||
checked={pageProgress}
|
||||
change={e => setPageProgress(e.checked || false)}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<CheckBoxComponent
|
||||
label="Automatischer Fortschritt"
|
||||
checked={autoProgress}
|
||||
change={e => setAutoProgress(e.checked || false)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{type === 'website' && (
|
||||
|
||||
Reference in New Issue
Block a user