33namespace Cachet \View \Components ;
44
55use Cachet \Models \Incident ;
6+ use Cachet \Models \Schedule ;
67use Cachet \Settings \AppSettings ;
78use Illuminate \Contracts \View \View ;
89use Illuminate \Database \Eloquent \Builder ;
@@ -30,7 +31,7 @@ public function render(): View
3031 $ endDate = $ startDate ->clone ()->subDays ($ incidentDays );
3132
3233 return view ('cachet::components.incident-timeline ' , [
33- 'incidents ' => $ this ->incidents (
34+ 'timeline ' => $ this ->timeline (
3435 $ startDate ,
3536 $ endDate ,
3637 $ this ->appSettings ->only_disrupted_days
@@ -45,11 +46,39 @@ public function render(): View
4546 ]);
4647 }
4748
49+ /**
50+ * Build the timeline of incidents and completed maintenance, grouped by day.
51+ *
52+ * @return Collection<string, array{incidents: Collection<int, Incident>, schedules: Collection<int, Schedule>}>
53+ */
54+ private function timeline (Carbon $ startDate , Carbon $ endDate , bool $ onlyDisruptedDays = false ): Collection
55+ {
56+ $ incidents = $ this ->incidents ($ startDate , $ endDate );
57+ $ schedules = $ this ->schedules ($ startDate , $ endDate );
58+
59+ return collect ($ endDate ->toPeriod ($ startDate ))
60+ ->keyBy (fn ($ period ) => $ period ->toDateString ())
61+ ->map (fn ($ period ) => collect ())
62+ ->union ($ incidents )
63+ ->union ($ schedules )
64+ ->keys ()
65+ ->mapWithKeys (fn (string $ date ) => [$ date => [
66+ 'incidents ' => $ incidents ->get ($ date , collect ()),
67+ 'schedules ' => $ schedules ->get ($ date , collect ()),
68+ ]])
69+ ->when ($ onlyDisruptedDays , fn ($ collection ) => $ collection ->filter (
70+ fn (array $ day ) => $ day ['incidents ' ]->isNotEmpty () || $ day ['schedules ' ]->isNotEmpty ()
71+ ))
72+ ->sortKeysDesc ();
73+ }
74+
4875 /**
4976 * Fetch the incidents that occurred between the given start and end date.
5077 * Incidents will be grouped by days.
78+ *
79+ * @return Collection<string, Collection<int, Incident>>
5180 */
52- private function incidents (Carbon $ startDate , Carbon $ endDate, bool $ onlyDisruptedDays = false ): Collection
81+ private function incidents (Carbon $ startDate , Carbon $ endDate ): Collection
5382 {
5483 return Incident::query ()
5584 ->with ([
@@ -86,15 +115,34 @@ private function incidents(Carbon $startDate, Carbon $endDate, bool $onlyDisrupt
86115 });
87116 })
88117 ->get ()
118+ ->toBase ()
89119 ->sortByDesc (fn (Incident $ incident ) => $ incident ->timestamp )
90- ->groupBy (fn (Incident $ incident ) => $ incident ->timestamp ->toDateString ())
91- ->union (
92- // Back-fill any missing dates...
93- collect ($ endDate ->toPeriod ($ startDate ))
94- ->keyBy (fn ($ period ) => $ period ->toDateString ())
95- ->map (fn ($ period ) => collect ())
96- )
97- ->when ($ onlyDisruptedDays , fn ($ collection ) => $ collection ->filter (fn ($ incidents ) => $ incidents ->isNotEmpty ()))
98- ->sortKeysDesc ();
120+ ->groupBy (fn (Incident $ incident ) => $ incident ->timestamp ->toDateString ());
121+ }
122+
123+ /**
124+ * Fetch the completed maintenance that occurred between the given start and end date.
125+ * Schedules will be grouped by the day they completed.
126+ *
127+ * @return Collection<string, Collection<int, Schedule>>
128+ */
129+ private function schedules (Carbon $ startDate , Carbon $ endDate ): Collection
130+ {
131+ return Schedule::query ()
132+ ->with (['components ' , 'updates ' => fn ($ query ) => $ query ->orderByDesc ('created_at ' )])
133+ ->inThePast ()
134+ ->when ($ this ->appSettings ->recent_incidents_only , fn ($ query ) => $ query ->whereDate (
135+ 'completed_at ' ,
136+ '> ' ,
137+ Carbon::now ()->subDays ($ this ->appSettings ->recent_incidents_days )->format ('Y-m-d ' )
138+ ))
139+ ->when (! $ this ->appSettings ->recent_incidents_only , fn ($ query ) => $ query ->whereBetween ('completed_at ' , [
140+ $ endDate ->startOfDay ()->toDateTimeString (),
141+ $ startDate ->endofDay ()->toDateTimeString (),
142+ ]))
143+ ->get ()
144+ ->toBase ()
145+ ->sortByDesc (fn (Schedule $ schedule ) => $ schedule ->completed_at )
146+ ->groupBy (fn (Schedule $ schedule ) => $ schedule ->completed_at ->toDateString ());
99147 }
100148}
0 commit comments