studio/laravel-totem
Laravel Totem provides a Horizon-style dashboard to manage Laravel Scheduler jobs. Create, enable/disable, and edit scheduled Artisan commands without changing code. Includes migrations/assets, auth customization, and supports Laravel 11/12 on PHP 8.2+.
Date: 2026-02-24 Status: Approved
There is no way to see at a glance which tasks will run over the next 1–3 days. The existing Tasks list shows last-run stats and the next single upcoming run per task, but gives no sense of density, overlap, or schedule across a time window.
Add an "Upcoming" page with an Outlook-style time-grid calendar showing all scheduled task runs over a 1-day or 3-day window. The backend computes run times from each task's cron expression; the frontend renders a pure CSS/Vue grid — no new JS dependencies.
Two routes added to web.php inside the existing tasks group, before the {totemTask} wildcard:
Route::get('upcoming', 'UpcomingTasksController@index')->name('totem.upcoming');
Route::get('upcoming/events', 'UpcomingTasksController@events')->name('totem.upcoming.events');
A second nav item — "Upcoming" — added to resources/views/partials/sidebar.blade.php, linking to totem.upcoming.
resources/views/tasks/schedules.blade.php → repurposed as the calendar Blade pageresources/assets/js/tasks/components/ScheduleRow.vue → repurposed as UpcomingCalendar.vuesrc/Http/Controllers/UpcomingTasksController.phpindex()Returns the Blade view totem::tasks.schedules. No data passed — Vue fetches everything via AJAX.
events()Query parameters:
start — ISO 8601 timestamp (default: now, floored to current minute)days — integer, 1 or 3 (default: 1)Logic:
$start with Carbon, compute $end = $start->copy()->addDays($days)EloquentTaskRepository::findAllActive()CronExpression::factory($task->getCronExpression())->getNextRunDate($cursor), advancing $cursor to each result until $cursor >= $end{ task_id, description, command, scheduled_at (ISO 8601) }Response:
{
"start": "2026-02-24T00:00:00+00:00",
"end": "2026-02-25T00:00:00+00:00",
"days": 1,
"events": [
{ "task_id": 1, "description": "Send daily report", "command": "report:daily", "scheduled_at": "2026-02-24T08:00:00+00:00" }
]
}
All events shown — no truncation for high-frequency tasks.
currentStart — Date, defaults to start of current hourdays — integer, 1 or 3 (default: 1)events — array of event objects from APIloading — booleanCSS grid with days + 1 columns:
25 rows:
Event chips are placed in the cell matching their day column and hour row. Multiple events in the same cell stack vertically. Each chip shows the task description (truncated ~20 chars) and exact run time (HH:mm).
days, re-fetchescurrentStart by days days, re-fetchescurrentStart to now, re-fetchesOn mounted() and whenever currentStart or days changes (watcher), fetch:
GET /totem/tasks/upcoming/events?start=<ISO>&days=<1|3>
Populate events from response. Frontend performs no cron computation — display only.
totem.task.view)How can I help you explore Laravel packages today?