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:
pewdiepie-archdaemon
2026-06-05 02:52:07 +09:00
parent 4ed48baf68
commit b98ee04e2f
5 changed files with 178 additions and 11 deletions

View File

@@ -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);
};