diff --git a/public/build/manifest.json b/public/build/manifest.json
index 0a1c654f..d692ffcd 100644
--- a/public/build/manifest.json
+++ b/public/build/manifest.json
@@ -1,18 +1,17 @@
{
- "resources/css/cachet.css": {
- "file": "assets/cachet-D-feVIY7.css",
- "src": "resources/css/cachet.css",
+ "resources/js/cachet.js": {
+ "file": "assets/cachet.6122e927.js",
+ "src": "resources/js/cachet.js",
"isEntry": true
},
"resources/css/dashboard/theme.css": {
- "file": "assets/theme-C6ZKRDAs.css",
+ "file": "assets/theme.8251fad4.css",
"src": "resources/css/dashboard/theme.css",
"isEntry": true
},
- "resources/js/cachet.js": {
- "file": "assets/cachet-DCZQ8JcZ.js",
- "name": "cachet",
- "src": "resources/js/cachet.js",
+ "resources/css/cachet.css": {
+ "file": "assets/cachet.30cb9e62.css",
+ "src": "resources/css/cachet.css",
"isEntry": true
}
}
\ No newline at end of file
diff --git a/resources/views/components/incident.blade.php b/resources/views/components/incident.blade.php
index 5548b27e..d8d9d9db 100644
--- a/resources/views/components/incident.blade.php
+++ b/resources/views/components/incident.blade.php
@@ -4,9 +4,7 @@
'incidents',
])
-
-
- @forelse($incidents as $incident)
+ @foreach($incidents as $incident)
- @empty
-
-
-
- {{ __('No incidents reported.') }}
-
-
-
- @endforelse
-
+ @endforeach
diff --git a/resources/views/components/schedule-timeline.blade.php b/resources/views/components/schedule-timeline.blade.php
new file mode 100644
index 00000000..7225c677
--- /dev/null
+++ b/resources/views/components/schedule-timeline.blade.php
@@ -0,0 +1,43 @@
+@use('Cachet\Enums\ScheduleStatusEnum')
+@props([
+ 'date',
+ 'schedules',
+])
+
+ @foreach($schedules as $schedule)
+
+
+
+
+
+
+ {{ $schedule->name}}
+
+ @auth
+
+
+
+ @endauth
+
+
+ {{ $schedule->completed_at->diffForHumans() }} —
+
+
+
+
+
+
+
+
+
+
+
+
{!! $schedule->formattedMessage() !!}
+
+
+
+
+ @endforeach
diff --git a/resources/views/components/schedule.blade.php b/resources/views/components/schedule.blade.php
index 1ec66c48..1abb3c1b 100644
--- a/resources/views/components/schedule.blade.php
+++ b/resources/views/components/schedule.blade.php
@@ -13,6 +13,11 @@
{{ $schedule->scheduled_at->diffForHumans() }} —
+ @auth
+
+
+
+ @endauth
diff --git a/resources/views/components/incident-timeline.blade.php b/resources/views/components/timeline.blade.php
similarity index 66%
rename from resources/views/components/incident-timeline.blade.php
rename to resources/views/components/timeline.blade.php
index cda4b2d0..55a4107b 100644
--- a/resources/views/components/incident-timeline.blade.php
+++ b/resources/views/components/timeline.blade.php
@@ -29,13 +29,22 @@
- @forelse ($incidents as $date => $incident)
-
- @empty
-
- {{ __('No incidents reported between :from and :to.', ['from' => $from, 'to' => $to]) }}
+ @foreach ($incidents as $date => $incident)
+
+
+
+
+ @if(count($incident) === 0 && count($schedules[$date]) === 0)
+
+
+
+ {{ __('No incidents reported.') }}
+
+
+
+ @endif
+ @endforeach
- @endforelse
diff --git a/resources/views/status-page/index.blade.php b/resources/views/status-page/index.blade.php
index 5fef4e98..6d076988 100644
--- a/resources/views/status-page/index.blade.php
+++ b/resources/views/status-page/index.blade.php
@@ -18,7 +18,7 @@
@endif
-
+
diff --git a/src/Models/Schedule.php b/src/Models/Schedule.php
index bbbb5b2f..492e67f1 100644
--- a/src/Models/Schedule.php
+++ b/src/Models/Schedule.php
@@ -4,6 +4,7 @@
use Cachet\Database\Factories\ScheduleFactory;
use Cachet\Enums\ScheduleStatusEnum;
+use Cachet\Filament\Resources\ScheduleResource;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\Factory;
@@ -113,6 +114,19 @@ public function scopeInThePast(Builder $query): Builder
return $query->where('completed_at', '<=', Carbon::now());
}
+ /**
+ * Get the URL to the schedule page within the dashboard.
+ */
+ public function filamentDashboardEditUrl(): string
+ {
+ return ScheduleResource::getUrl(name: 'edit', parameters: ['record' => $this->id]);
+ }
+
+ public function timestamp(): Attribute
+ {
+ return Attribute::get(fn () => $this->completed_at ?: $this->scheduled_at);
+ }
+
/**
* Create a new factory instance for the model.
*/
diff --git a/src/View/Components/IncidentTimeline.php b/src/View/Components/Timeline.php
similarity index 65%
rename from src/View/Components/IncidentTimeline.php
rename to src/View/Components/Timeline.php
index c9cfeab6..6921a4d0 100644
--- a/src/View/Components/IncidentTimeline.php
+++ b/src/View/Components/Timeline.php
@@ -3,6 +3,7 @@
namespace Cachet\View\Components;
use Cachet\Models\Incident;
+use Cachet\Models\Schedule;
use Cachet\Settings\AppSettings;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Builder;
@@ -10,7 +11,7 @@
use Illuminate\Support\Collection;
use Illuminate\View\Component;
-class IncidentTimeline extends Component
+class Timeline extends Component
{
public function __construct(private AppSettings $appSettings)
{
@@ -23,12 +24,17 @@ public function render(): View
$startDate = Carbon::createFromFormat('Y-m-d', request('from', now()->toDateString()));
$endDate = $startDate->clone()->subDays($incidentDays);
- return view('cachet::components.incident-timeline', [
+ return view('cachet::components.timeline', [
'incidents' => $this->incidents(
$startDate,
$endDate,
$this->appSettings->only_disrupted_days
),
+ 'schedules' => $this->schedules(
+ $startDate,
+ $endDate,
+ $this->appSettings->only_disrupted_days
+ ),
'from' => $startDate->toDateString(),
'to' => $endDate->toDateString(),
'nextPeriodFrom' => $startDate->clone()->subDays($incidentDays + 1)->toDateString(),
@@ -72,4 +78,33 @@ private function incidents(Carbon $startDate, Carbon $endDate, bool $onlyDisrupt
->when($onlyDisruptedDays, fn ($collection) => $collection->filter(fn ($incidents) => $incidents->isNotEmpty()))
->sortKeysDesc();
}
+
+ /**
+ * Fetch the schedules that occurred between the given start and end date.
+ * Schedules will be grouped by days.
+ */
+ private function schedules(Carbon $startDate, Carbon $endDate, bool $onlyDisruptedDays = false): Collection
+ {
+ return Schedule::query()
+ ->with([
+ 'components',
+ ])
+ ->where(function (Builder $query) use ($endDate, $startDate) {
+ $query->whereBetween('completed_at', [
+ $endDate->startOfDay()->toDateTimeString(),
+ $startDate->endofDay()->toDateTimeString(),
+ ]);
+ })
+ ->orderBy('completed_at', 'desc')
+ ->get()
+ ->groupBy(fn (Schedule $schedule) => $schedule->completed_at->toDateString())
+ ->union(
+ // Back-fill any missing dates...
+ collect($endDate->toPeriod($startDate))
+ ->keyBy(fn ($period) => $period->toDateString())
+ ->map(fn ($period) => collect())
+ )
+ ->when($onlyDisruptedDays, fn ($collection) => $collection->filter(fn ($schedules) => $schedules->isNotEmpty()))
+ ->sortKeysDesc();
+ }
}