Skip to content

Commit 0015a14

Browse files
authored
Add ability to attach components to schedules (#307)
1 parent 596970e commit 0015a14

File tree

6 files changed

+123
-2
lines changed

6 files changed

+123
-2
lines changed

resources/views/components/schedule.blade.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
<span class="text-xs text-zinc-500 dark:text-zinc-400">
1414
{{ $schedule->scheduled_at->diffForHumans() }} — <time datetime="{{ $schedule->scheduled_at->toW3cString()}}" x-text="timestamp.toLocaleString(@if($appSettings->timezone !== '-')undefined, {timeZone: '{{$appSettings->timezone}}'}@endif )"></time>
1515
</span>
16+
@if ($schedule->components->isNotEmpty())
17+
<div class="text-xs font-semibold text-zinc-500 dark:text-zinc-400 mt-1">
18+
{{ __('Affected Components') }}: {{ $schedule->components->pluck('name')->join(', ', ' and ') }}
19+
</div>
20+
@endif
1621
</div>
1722

1823
<div class="flex justify-start sm:justify-end">
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace Cachet\Filament\Resources\Schedules\RelationManagers;
4+
5+
use Cachet\Enums\ComponentStatusEnum;
6+
use Filament\Actions\AttachAction;
7+
use Filament\Actions\BulkActionGroup;
8+
use Filament\Actions\DetachAction;
9+
use Filament\Actions\DetachBulkAction;
10+
use Filament\Forms\Components\Select;
11+
use Filament\Resources\RelationManagers\RelationManager;
12+
use Filament\Schemas\Schema;
13+
use Filament\Tables\Columns\TextColumn;
14+
use Filament\Tables\Table;
15+
use Illuminate\Database\Eloquent\Model;
16+
17+
class ComponentsRelationManager extends RelationManager
18+
{
19+
protected static string $relationship = 'components';
20+
21+
public static function getTitle(Model $ownerRecord, string $pageClass): string
22+
{
23+
return __('Components');
24+
}
25+
26+
public function form(Schema $schema): Schema
27+
{
28+
return $schema
29+
->components([
30+
// No form editing needed - components are only attached/detached
31+
]);
32+
}
33+
34+
public function table(Table $table): Table
35+
{
36+
return $table
37+
->recordTitleAttribute('name')
38+
->modelLabel(__('Component'))
39+
->pluralModelLabel(__('Components'))
40+
->columns([
41+
TextColumn::make('name')
42+
->label(__('Name')),
43+
])
44+
->filters([
45+
//
46+
])
47+
->headerActions([
48+
AttachAction::make()
49+
->preloadRecordSelect()
50+
->recordSelect(
51+
fn (Select $select) => $select->placeholder(__('Select a component')),
52+
)
53+
->multiple()
54+
->mutateFormDataUsing(function (array $data): array {
55+
// Set a default component_status value (Operational)
56+
$data['component_status'] = ComponentStatusEnum::operational->value;
57+
return $data;
58+
}),
59+
])
60+
->recordActions([
61+
DetachAction::make(),
62+
])
63+
->toolbarActions([
64+
BulkActionGroup::make([
65+
DetachBulkAction::make(),
66+
]),
67+
]);
68+
}
69+
}

src/Filament/Resources/Schedules/ScheduleResource.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,23 @@
44

55
use Cachet\Actions\Update\CreateUpdate;
66
use Cachet\Data\Requests\ScheduleUpdate\CreateScheduleUpdateRequestData;
7+
use Cachet\Enums\ComponentStatusEnum;
78
use Cachet\Enums\ScheduleStatusEnum;
89
use Cachet\Filament\Resources\Schedules\Pages\CreateSchedule;
910
use Cachet\Filament\Resources\Schedules\Pages\EditSchedule;
1011
use Cachet\Filament\Resources\Schedules\Pages\ListSchedules;
12+
use Cachet\Filament\Resources\Schedules\RelationManagers\ComponentsRelationManager;
1113
use Cachet\Filament\Resources\Updates\RelationManagers\UpdatesRelationManager;
1214
use Cachet\Models\Schedule;
1315
use Filament\Actions\Action;
1416
use Filament\Actions\BulkActionGroup;
1517
use Filament\Actions\DeleteBulkAction;
1618
use Filament\Actions\EditAction;
1719
use Filament\Forms\Components\DateTimePicker;
20+
use Filament\Forms\Components\Hidden;
1821
use Filament\Forms\Components\MarkdownEditor;
22+
use Filament\Forms\Components\Repeater;
23+
use Filament\Forms\Components\Select;
1924
use Filament\Forms\Components\TextInput;
2025
use Filament\Notifications\Notification;
2126
use Filament\Resources\Resource;
@@ -41,6 +46,23 @@ public static function form(Schema $schema): Schema
4146
MarkdownEditor::make('message')
4247
->label(__('cachet::schedule.form.message_label'))
4348
->columnSpanFull(),
49+
Repeater::make('scheduleComponents')
50+
->visibleOn('create')
51+
->relationship()
52+
->defaultItems(0)
53+
->addActionLabel(__('Add Component'))
54+
->schema([
55+
Select::make('component_id')
56+
->preload()
57+
->required()
58+
->relationship('component', 'name')
59+
->disableOptionsWhenSelectedInSiblingRepeaterItems()
60+
->label(__('Component')),
61+
Hidden::make('component_status')
62+
->default(ComponentStatusEnum::operational->value),
63+
])
64+
->label(__('Affected Components'))
65+
->columnSpanFull(),
4466
])->columnSpan(3),
4567
Section::make()->schema([
4668
DateTimePicker::make('scheduled_at')
@@ -146,6 +168,7 @@ public static function getPages(): array
146168
public static function getRelations(): array
147169
{
148170
return [
171+
ComponentsRelationManager::class,
149172
UpdatesRelationManager::class,
150173
];
151174
}

src/Http/Controllers/StatusPage/StatusPageController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public function index(): View
3939
->withCount('incidents')
4040
->get(),
4141

42-
'schedules' => Schedule::query()->with('updates')->incomplete()->orderBy('scheduled_at')->get(),
42+
'schedules' => Schedule::query()->with(['updates', 'components'])->incomplete()->orderBy('scheduled_at')->get(),
4343

4444
'display_graphs' => $this->appSettings->display_graphs,
4545
]);

src/Models/Component.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ public function incidents(): BelongsToMany
9494
->withPivot('component_status');
9595
}
9696

97+
/**
98+
* Get the schedules for the component.
99+
*
100+
* @return BelongsToMany<Schedule, $this>
101+
*/
102+
public function schedules(): BelongsToMany
103+
{
104+
return $this->belongsToMany(Schedule::class, 'schedule_components')
105+
->withTimestamps()
106+
->withPivot('component_status');
107+
}
108+
97109
/**
98110
* Get the subscribers for this component.
99111
*/

src/Models/Schedule.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Illuminate\Database\Eloquent\Factories\HasFactory;
1212
use Illuminate\Database\Eloquent\Model;
1313
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
14+
use Illuminate\Database\Eloquent\Relations\HasMany;
1415
use Illuminate\Database\Eloquent\Relations\MorphMany;
1516
use Illuminate\Database\Eloquent\SoftDeletes;
1617
use Illuminate\Support\Carbon;
@@ -87,7 +88,18 @@ public function components(): BelongsToMany
8788
return $this->belongsToMany(
8889
Component::class,
8990
'schedule_components',
90-
);
91+
)->withPivot(['component_status'])
92+
->withTimestamps();
93+
}
94+
95+
/**
96+
* Get the schedule components pivot entries.
97+
*
98+
* @return HasMany<ScheduleComponent, $this>
99+
*/
100+
public function scheduleComponents(): HasMany
101+
{
102+
return $this->hasMany(ScheduleComponent::class);
91103
}
92104

93105
/**

0 commit comments

Comments
 (0)