Cookbook scheduler: reuse the standard calendar event card + auto-create Cookbook calendar
Drop the custom Schedule modal in favor of opening the calendar's existing event-creation form pre-filled with the model's name + cookbook YAML in the description. The user lands in the same event editor they already know from regular calendar use, just pointed at the auto-created "Cookbook" calendar. Backend: - POST /api/cookbook/schedule/ensure-calendar — idempotent: creates a calendar named "Cookbook" if one doesn't exist for the current user, saves its href into cookbook_schedule_calendar_href, flips cookbook_scheduler_enabled on. Verifies the saved href against /api/calendar/calendars on every call so a manually-deleted calendar self-heals. Frontend: - calendar.js: expose window.cookbookOpenScheduleForm(draft) which opens the calendar modal (if not open), calls _showEventForm, then pre-fills summary / description / rrule / calendar dropdown. Force-expands the "Add details" section so the user can see which calendar it's heading into. - cookbookSchedule.js: Schedule-button click now calls ensure-calendar, builds the cookbook: YAML block, and routes to window.cookbookOpenScheduleForm instead of openModal(). The legacy custom modal stays as a fallback for the case where calendar.js hasn't loaded. UX tweak: - cookbookServe.js: replace the standalone "Schedule…" text button with a small icon-only button (clock SVG) glued to the right edge of Launch. The pair forms one visual unit — Launch on the left, schedule-now on the right — sharing a thin divider. CSS handles the rounded corners + divider.
This commit is contained in:
@@ -3346,3 +3346,42 @@ window.addEventListener('calendar-refresh', () => {
|
||||
const calendarModule = { openCalendar, closeCalendar, isCalendarOpen };
|
||||
export { openCalendar, openCalendarTo, closeCalendar, isCalendarOpen };
|
||||
export default calendarModule;
|
||||
|
||||
// ── Cookbook scheduler hook ─────────────────────────────────────────────
|
||||
// Lets the Cookbook tab's Schedule button open the standard calendar
|
||||
// event-create form pre-filled with the model's name + cookbook YAML in
|
||||
// the description, on the auto-created Cookbook calendar. Keeps the
|
||||
// Schedule UX identical to creating any other calendar event — no
|
||||
// custom modal, just the existing flow that users already know.
|
||||
window.cookbookOpenScheduleForm = function (draft) {
|
||||
// Open the calendar first so #cal-body exists for _showEventForm.
|
||||
if (!_open) openCalendar();
|
||||
// Defer a tick so the modal DOM is mounted before we touch it.
|
||||
setTimeout(() => {
|
||||
_showEventForm(null, _today(), _today());
|
||||
setTimeout(() => {
|
||||
try {
|
||||
const sumEl = document.getElementById('cal-f-sum');
|
||||
if (sumEl && draft && draft.summary) sumEl.value = draft.summary;
|
||||
const descEl = document.getElementById('cal-f-desc');
|
||||
if (descEl && draft && draft.description) descEl.value = draft.description;
|
||||
const rrEl = document.getElementById('cal-f-rrule');
|
||||
if (rrEl && draft && draft.rrule) rrEl.value = draft.rrule;
|
||||
// Calendar selector lives behind the "Add details" expand; force-
|
||||
// expand so the user sees it's heading into the Cookbook calendar.
|
||||
const form = document.querySelector('.cal-form-bespoke');
|
||||
if (form) form.classList.add('is-expanded');
|
||||
const calSel = document.getElementById('cal-f-cal');
|
||||
if (calSel && draft && draft.calendar_href) {
|
||||
const opt = Array.from(calSel.options).find(o => o.value === draft.calendar_href);
|
||||
if (opt) calSel.value = draft.calendar_href;
|
||||
}
|
||||
// Focus the title so the user can immediately type if they want
|
||||
// to rename the event (rare, but cheap to enable).
|
||||
if (sumEl) sumEl.focus();
|
||||
} catch (e) {
|
||||
console.warn('cookbook schedule prefill failed:', e);
|
||||
}
|
||||
}, 60);
|
||||
}, _open ? 0 : 80);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user