diff --git a/app/Filament/Components/Forms/Actions/CronPresetAction.php b/app/Filament/Components/Forms/Actions/CronPresetAction.php new file mode 100644 index 000000000..d2713d9ec --- /dev/null +++ b/app/Filament/Components/Forms/Actions/CronPresetAction.php @@ -0,0 +1,53 @@ +disabled(fn (string $operation) => $operation === 'view'); + + $this->color(fn (Get $get) => $get('cron_minute') == $this->minute && + $get('cron_hour') == $this->hour && + $get('cron_day_of_month') == $this->dayOfMonth && + $get('cron_month') == $this->month && + $get('cron_day_of_week') == $this->dayOfWeek + ? 'success' : 'primary'); + + $this->action(function (Set $set) { + $set('cron_minute', $this->minute); + $set('cron_hour', $this->hour); + $set('cron_day_of_month', $this->dayOfMonth); + $set('cron_month', $this->month); + $set('cron_day_of_week', $this->dayOfWeek); + }); + } + + public function cron(string $minute, string $hour, string $dayOfMonth, string $month, string $dayOfWeek): static + { + $this->minute = $minute; + $this->hour = $hour; + $this->dayOfMonth = $dayOfMonth; + $this->month = $month; + $this->dayOfWeek = $dayOfWeek; + + return $this; + } +} diff --git a/app/Filament/Server/Resources/ScheduleResource.php b/app/Filament/Server/Resources/ScheduleResource.php index b22ec3c8d..8f641cac3 100644 --- a/app/Filament/Server/Resources/ScheduleResource.php +++ b/app/Filament/Server/Resources/ScheduleResource.php @@ -3,6 +3,7 @@ namespace App\Filament\Server\Resources; use App\Facades\Activity; +use App\Filament\Components\Forms\Actions\CronPresetAction; use App\Filament\Components\Tables\Columns\DateTimeColumn; use App\Filament\Server\Resources\ScheduleResource\Pages; use App\Filament\Server\Resources\ScheduleResource\RelationManagers\TasksRelationManager; @@ -18,13 +19,14 @@ use Carbon\Carbon; use Exception; use Filament\Facades\Filament; use Filament\Forms\Components\Actions; -use Filament\Forms\Components\Actions\Action; +use Filament\Forms\Components\Group; use Filament\Forms\Components\Section; use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Toggle; use Filament\Forms\Components\ToggleButtons; use Filament\Forms\Form; +use Filament\Forms\Get; use Filament\Forms\Set; use Filament\Notifications\Notification; use Filament\Resources\Pages\PageRegistration; @@ -38,6 +40,7 @@ use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\HtmlString; class ScheduleResource extends Resource { @@ -77,20 +80,31 @@ class ScheduleResource extends Resource { return $form ->columns([ - 'default' => 4, - 'lg' => 5, + 'default' => 1, + 'lg' => 2, ]) ->schema([ TextInput::make('name') - ->columnSpan([ - 'default' => 4, - 'md' => 3, - 'lg' => 4, - ]) + ->columnSpanFull() ->label('Schedule Name') ->placeholder('A human readable identifier for this schedule.') ->autocomplete(false) ->required(), + Toggle::make('only_when_online') + ->label('Only when Server is Online?') + ->hintIconTooltip('Only execute this schedule when the server is in a running state.') + ->hintIcon('tabler-question-mark') + ->inline(false) + ->required() + ->default(1), + Toggle::make('is_active') + ->label('Enable Schedule?') + ->hintIconTooltip('This schedule will be executed automatically if enabled.') + ->hintIcon('tabler-question-mark') + ->inline(false) + ->hiddenOn('view') + ->required() + ->default(1), ToggleButtons::make('Status') ->formatStateUsing(fn (Schedule $schedule) => !$schedule->is_active ? 'inactive' : ($schedule->is_processing ? 'processing' : 'active')) ->options(fn (Schedule $schedule) => !$schedule->is_active ? ['inactive' => 'Inactive'] : ($schedule->is_processing ? ['processing' => 'Processing'] : ['active' => 'Active'])) @@ -99,117 +113,29 @@ class ScheduleResource extends Resource 'processing' => 'warning', 'active' => 'success', ]) - ->visibleOn('view') - ->columnSpan([ - 'default' => 4, - 'md' => 1, - 'lg' => 1, - ]), - Toggle::make('only_when_online') - ->label('Only when Server is Online?') - ->hintIconTooltip('Only execute this schedule when the server is in a running state.') - ->hintIcon('tabler-question-mark') - ->inline(false) - ->columnSpan([ - 'default' => 2, - 'lg' => 3, - ]) - ->required() - ->default(1), - Toggle::make('is_active') - ->label('Enable Schedule?') - ->hintIconTooltip('This schedule will be executed automatically if enabled.') - ->hintIcon('tabler-question-mark') - ->inline(false) - ->columnSpan([ - 'default' => 2, - 'lg' => 2, - ]) - ->required() - ->default(1), - TextInput::make('cron_minute') - ->columnSpan([ - 'default' => 2, - 'lg' => 1, - ]) - ->label('Minute') - ->default('*/5') - ->required(), - TextInput::make('cron_hour') - ->columnSpan([ - 'default' => 2, - 'lg' => 1, - ]) - ->label('Hour') - ->default('*') - ->required(), - TextInput::make('cron_day_of_month') - ->columnSpan([ - 'default' => 2, - 'lg' => 1, - ]) - ->label('Day of Month') - ->default('*') - ->required(), - TextInput::make('cron_month') - ->columnSpan([ - 'default' => 2, - 'lg' => 1, - ]) - ->label('Month') - ->default('*') - ->required(), - TextInput::make('cron_day_of_week') - ->columnSpan([ - 'default' => 2, - 'lg' => 1, - ]) - ->label('Day of Week') - ->default('*') - ->required(), - Section::make('Presets') - ->hiddenOn('view') - ->columns(1) + ->visibleOn('view'), + Section::make('Cron') + ->description(fn (Get $get) => new HtmlString('Please keep in mind that the cron inputs below always assume UTC.
Next run in your timezone (' . auth()->user()->timezone . '): '. Utilities::getScheduleNextRunDate($get('cron_minute'), $get('cron_hour'), $get('cron_day_of_month'), $get('cron_month'), $get('cron_day_of_week'))->timezone(auth()->user()->timezone) . '')) ->schema([ Actions::make([ - Action::make('hourly') - ->disabled(fn (string $operation) => $operation === 'view') - ->action(function (Set $set) { - $set('cron_minute', '0'); - $set('cron_hour', '*'); - $set('cron_day_of_month', '*'); - $set('cron_month', '*'); - $set('cron_day_of_week', '*'); - }), - Action::make('daily') - ->disabled(fn (string $operation) => $operation === 'view') - ->action(function (Set $set) { - $set('cron_minute', '0'); - $set('cron_hour', '0'); - $set('cron_day_of_month', '*'); - $set('cron_month', '*'); - $set('cron_day_of_week', '*'); - }), - Action::make('weekly') - ->disabled(fn (string $operation) => $operation === 'view') - ->action(function (Set $set) { - $set('cron_minute', '0'); - $set('cron_hour', '0'); - $set('cron_day_of_month', '*'); - $set('cron_month', '*'); - $set('cron_day_of_week', '0'); - }), - Action::make('monthly') - ->disabled(fn (string $operation) => $operation === 'view') - ->action(function (Set $set) { - $set('cron_minute', '0'); - $set('cron_hour', '0'); - $set('cron_day_of_month', '1'); - $set('cron_month', '*'); - $set('cron_day_of_week', '0'); - }), - Action::make('every_x_minutes') - ->disabled(fn (string $operation) => $operation === 'view') + CronPresetAction::make('hourly') + ->cron('0', '*', '*', '*', '*'), + CronPresetAction::make('daily') + ->cron('0', '0', '*', '*', '*'), + CronPresetAction::make('weekly_monday') + ->label('Weekly (Monday)') + ->cron('0', '0', '*', '*', '1'), + CronPresetAction::make('weekly_sunday') + ->label('Weekly (Sunday)') + ->cron('0', '0', '*', '*', '0'), + CronPresetAction::make('monthly') + ->cron('0', '0', '1', '*', '*'), + CronPresetAction::make('every_x_minutes') + ->color(fn (Get $get) => str($get('cron_minute'))->startsWith('*/') + && $get('cron_hour') == '*' + && $get('cron_day_of_month') == '*' + && $get('cron_month') == '*' + && $get('cron_day_of_week') == '*' ? 'success' : 'primary') ->form([ TextInput::make('x') ->label('') @@ -226,8 +152,12 @@ class ScheduleResource extends Resource $set('cron_month', '*'); $set('cron_day_of_week', '*'); }), - Action::make('every_x_hours') - ->disabled(fn (string $operation) => $operation === 'view') + CronPresetAction::make('every_x_hours') + ->color(fn (Get $get) => $get('cron_minute') == '0' + && str($get('cron_hour'))->startsWith('*/') + && $get('cron_day_of_month') == '*' + && $get('cron_month') == '*' + && $get('cron_day_of_week') == '*' ? 'success' : 'primary') ->form([ TextInput::make('x') ->label('') @@ -244,8 +174,12 @@ class ScheduleResource extends Resource $set('cron_month', '*'); $set('cron_day_of_week', '*'); }), - Action::make('every_x_days') - ->disabled(fn (string $operation) => $operation === 'view') + CronPresetAction::make('every_x_days') + ->color(fn (Get $get) => $get('cron_minute') == '0' + && $get('cron_hour') == '0' + && str($get('cron_day_of_month'))->startsWith('*/') + && $get('cron_month') == '*' + && $get('cron_day_of_week') == '*' ? 'success' : 'primary') ->form([ TextInput::make('x') ->label('') @@ -262,8 +196,12 @@ class ScheduleResource extends Resource $set('cron_month', '*'); $set('cron_day_of_week', '*'); }), - Action::make('every_x_months') - ->disabled(fn (string $operation) => $operation === 'view') + CronPresetAction::make('every_x_months') + ->color(fn (Get $get) => $get('cron_minute') == '0' + && $get('cron_hour') == '0' + && $get('cron_day_of_month') == '1' + && str($get('cron_month'))->startsWith('*/') + && $get('cron_day_of_week') == '*' ? 'success' : 'primary') ->form([ TextInput::make('x') ->label('') @@ -280,8 +218,12 @@ class ScheduleResource extends Resource $set('cron_month', '*/' . $data['x']); $set('cron_day_of_week', '*'); }), - Action::make('every_x_day_of_week') - ->disabled(fn (string $operation) => $operation === 'view') + CronPresetAction::make('every_x_day_of_week') + ->color(fn (Get $get) => $get('cron_minute') == '0' + && $get('cron_hour') == '0' + && $get('cron_day_of_month') == '*' + && $get('cron_month') == '*' + && $get('cron_day_of_week') != '*' ? 'success' : 'primary') ->form([ Select::make('x') ->label('') @@ -305,7 +247,59 @@ class ScheduleResource extends Resource $set('cron_month', '*'); $set('cron_day_of_week', $data['x']); }), - ]), + ]) + ->hiddenOn('view'), + Group::make([ + TextInput::make('cron_minute') + ->columnSpan([ + 'default' => 2, + 'lg' => 1, + ]) + ->label('Minute') + ->default('*/5') + ->required() + ->live(), + TextInput::make('cron_hour') + ->columnSpan([ + 'default' => 2, + 'lg' => 1, + ]) + ->label('Hour') + ->default('*') + ->required() + ->live(), + TextInput::make('cron_day_of_month') + ->columnSpan([ + 'default' => 2, + 'lg' => 1, + ]) + ->label('Day of Month') + ->default('*') + ->required() + ->live(), + TextInput::make('cron_month') + ->columnSpan([ + 'default' => 2, + 'lg' => 1, + ]) + ->label('Month') + ->default('*') + ->required() + ->live(), + TextInput::make('cron_day_of_week') + ->columnSpan([ + 'default' => 2, + 'lg' => 1, + ]) + ->label('Day of Week') + ->default('*') + ->required() + ->live(), + ]) + ->columns([ + 'default' => 4, + 'lg' => 5, + ]), ]), ]); }