-
-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathTimeline.php
More file actions
111 lines (104 loc) · 4.31 KB
/
Timeline.php
File metadata and controls
111 lines (104 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php
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;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\View\Component;
class Timeline extends Component
{
public function __construct(private AppSettings $appSettings)
{
//
}
public function render(): View
{
$incidentDays = $this->appSettings->incident_days - 1;
$startDate = Carbon::createFromFormat('Y-m-d', request('from', now()->toDateString()));
$endDate = $startDate->clone()->subDays($incidentDays);
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(),
'nextPeriodTo' => $startDate->clone()->addDays($incidentDays + 1)->toDateString(),
'canPageForward' => $startDate->clone()->isBefore(now()),
]);
}
/**
* Fetch the incidents that occurred between the given start and end date.
* Incidents will be grouped by days.
*/
private function incidents(Carbon $startDate, Carbon $endDate, bool $onlyDisruptedDays = false): Collection
{
return Incident::query()
->with([
'components',
'incidentUpdates' => fn ($query) => $query->orderByDesc('created_at'),
])
->visible(auth()->check())
->where(function (Builder $query) use ($endDate, $startDate) {
$query->whereBetween('occurred_at', [
$endDate->startOfDay()->toDateTimeString(),
$startDate->endofDay()->toDateTimeString(),
])->orWhere(function (Builder $query) use ($endDate, $startDate) {
$query->whereNull('occurred_at')->whereBetween('created_at', [
$endDate->startOfDay()->toDateTimeString(),
$startDate->endofDay()->toDateTimeString(),
]);
});
})
->orderBy('occurred_at', 'desc')
->orderBy('created_at', 'desc')
->get()
->groupBy(fn (Incident $incident) => $incident->timestamp->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 ($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();
}
}