mirror of
				https://github.com/pelican-dev/panel.git
				synced 2025-10-31 22:46:53 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			174 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace App\Filament\Server\Resources\Schedules\RelationManagers;
 | |
| 
 | |
| use App\Facades\Activity;
 | |
| use App\Models\Schedule;
 | |
| use App\Models\Task;
 | |
| use Exception;
 | |
| use Filament\Actions\CreateAction;
 | |
| use Filament\Actions\DeleteAction;
 | |
| use Filament\Actions\EditAction;
 | |
| use Filament\Forms\Components\Field;
 | |
| use Filament\Forms\Components\Select;
 | |
| use Filament\Forms\Components\Textarea;
 | |
| use Filament\Forms\Components\TextInput;
 | |
| use Filament\Forms\Components\Toggle;
 | |
| use Filament\Resources\RelationManagers\RelationManager;
 | |
| use Filament\Schemas\Components\Utilities\Get;
 | |
| use Filament\Schemas\Components\Utilities\Set;
 | |
| use Filament\Tables\Columns\IconColumn;
 | |
| use Filament\Tables\Columns\TextColumn;
 | |
| use Filament\Tables\Table;
 | |
| 
 | |
| class TasksRelationManager extends RelationManager
 | |
| {
 | |
|     protected static string $relationship = 'tasks';
 | |
| 
 | |
|     /**
 | |
|      * @return array<array-key, string>
 | |
|      */
 | |
|     private function getActionOptions(bool $full = true): array
 | |
|     {
 | |
|         return [
 | |
|             Task::ACTION_POWER => $full ? trans('server/schedule.tasks.actions.power.title') : trans('server/schedule.tasks.actions.power.action'),
 | |
|             Task::ACTION_COMMAND => $full ? trans('server/schedule.tasks.actions.command.title') : trans('server/schedule.tasks.actions.command.command'),
 | |
|             Task::ACTION_BACKUP => $full ? trans('server/schedule.tasks.actions.backup.title') : trans('server/schedule.tasks.actions.backup.files_to_ignore'),
 | |
|             Task::ACTION_DELETE_FILES => $full ? trans('server/schedule.tasks.actions.delete.title') : trans('server/schedule.tasks.actions.delete.files_to_delete'),
 | |
|         ];
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @return array<Field>
 | |
|      *
 | |
|      * @throws Exception
 | |
|      */
 | |
|     private function getTaskForm(Schedule $schedule): array
 | |
|     {
 | |
|         return [
 | |
|             Select::make('action')
 | |
|                 ->label(trans('server/schedule.tasks.actions.title'))
 | |
|                 ->required()
 | |
|                 ->live()
 | |
|                 ->disableOptionWhen(fn (string $value) => $value === Task::ACTION_BACKUP && $schedule->server->backup_limit === 0)
 | |
|                 ->options($this->getActionOptions())
 | |
|                 ->selectablePlaceholder(false)
 | |
|                 ->default(Task::ACTION_POWER)
 | |
|                 ->afterStateUpdated(fn ($state, Set $set) => $set('payload', $state === Task::ACTION_POWER ? 'restart' : null)),
 | |
|             Textarea::make('payload')
 | |
|                 ->hidden(fn (Get $get) => $get('action') === Task::ACTION_POWER)
 | |
|                 ->label(fn (Get $get) => $this->getActionOptions(false)[$get('action')] ?? trans('server/schedule.tasks.payload')),
 | |
|             Select::make('payload')
 | |
|                 ->visible(fn (Get $get) => $get('action') === Task::ACTION_POWER)
 | |
|                 ->label(trans('server/schedule.tasks.actions.power.action'))
 | |
|                 ->required()
 | |
|                 ->options([
 | |
|                     'start' => trans('server/schedule.tasks.actions.power.start'),
 | |
|                     'restart' => trans('server/schedule.tasks.actions.power.restart'),
 | |
|                     'stop' => trans('server/schedule.tasks.actions.power.stop'),
 | |
|                     'kill' => trans('server/schedule.tasks.actions.power.kill'),
 | |
|                 ])
 | |
|                 ->selectablePlaceholder(false)
 | |
|                 ->default('restart'),
 | |
|             TextInput::make('time_offset')
 | |
|                 ->label(trans('server/schedule.tasks.time_offset'))
 | |
|                 ->hidden(fn (Get $get) => config('queue.default') === 'sync' || $get('sequence_id') === 1 || $schedule->tasks->isEmpty())
 | |
|                 ->default(0)
 | |
|                 ->numeric()
 | |
|                 ->minValue(0)
 | |
|                 ->maxValue(900)
 | |
|                 ->suffix(trans_choice('server/schedule.tasks.seconds', 2)),
 | |
|             Toggle::make('continue_on_failure')
 | |
|                 ->label(trans('server/schedule.tasks.continue_on_failure')),
 | |
|         ];
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @throws Exception
 | |
|      */
 | |
|     public function table(Table $table): Table
 | |
|     {
 | |
|         /** @var Schedule $schedule */
 | |
|         $schedule = $this->getOwnerRecord();
 | |
| 
 | |
|         return $table
 | |
|             ->reorderable('sequence_id')
 | |
|             ->defaultSort('sequence_id')
 | |
|             ->columns([
 | |
|                 TextColumn::make('action')
 | |
|                     ->label(trans('server/schedule.tasks.actions.title'))
 | |
|                     ->state(fn (Task $task) => $this->getActionOptions()[$task->action] ?? $task->action),
 | |
|                 TextColumn::make('payload')
 | |
|                     ->label(trans('server/schedule.tasks.payload'))
 | |
|                     ->state(fn (Task $task) => match ($task->payload) {
 | |
|                         'start', 'restart', 'stop', 'kill' => mb_ucfirst($task->payload),
 | |
|                         default => explode(PHP_EOL, $task->payload)
 | |
|                     })
 | |
|                     ->badge(),
 | |
|                 TextColumn::make('time_offset')
 | |
|                     ->label(trans('server/schedule.tasks.time_offset'))
 | |
|                     ->hidden(fn () => config('queue.default') === 'sync')
 | |
|                     ->suffix(fn (Task $task) => $task->sequence_id > 1 ? ' '. trans_choice('server/schedule.tasks.seconds', $task->time_offset) : null)
 | |
|                     ->state(fn (Task $task) => $task->sequence_id === 1 ? null : $task->time_offset)
 | |
|                     ->placeholder(trans('server/schedule.tasks.first_task')),
 | |
|                 IconColumn::make('continue_on_failure')
 | |
|                     ->label(trans('server/schedule.tasks.continue_on_failure'))
 | |
|                     ->boolean(),
 | |
|             ])
 | |
|             ->recordActions([
 | |
|                 EditAction::make()
 | |
|                     ->schema($this->getTaskForm($schedule))
 | |
|                     ->mutateDataUsing(function ($data) {
 | |
|                         $data['payload'] ??= '';
 | |
| 
 | |
|                         return $data;
 | |
|                     })
 | |
|                     ->after(function ($data) {
 | |
|                         /** @var Schedule $schedule */
 | |
|                         $schedule = $this->getOwnerRecord();
 | |
| 
 | |
|                         Activity::event('server:task.update')
 | |
|                             ->subject($schedule)
 | |
|                             ->property(['name' => $schedule->name, 'action' => $data['action'], 'payload' => $data['payload']])
 | |
|                             ->log();
 | |
| 
 | |
|                     }),
 | |
|                 DeleteAction::make()
 | |
|                     ->action(function (Task $task) {
 | |
|                         /** @var Schedule $schedule */
 | |
|                         $schedule = $this->getOwnerRecord();
 | |
|                         $task->delete();
 | |
| 
 | |
|                         Activity::event('server:task.delete')
 | |
|                             ->subject($schedule)
 | |
|                             ->property(['name' => $schedule->name, 'action' => $task->action, 'payload' => $task->payload])
 | |
|                             ->log();
 | |
|                     }),
 | |
|             ])
 | |
|             ->headerActions([
 | |
|                 CreateAction::make()
 | |
|                     ->createAnother(false)
 | |
|                     ->label(fn () => $schedule->tasks()->count() >= config('panel.client_features.schedules.per_schedule_task_limit', 10) ? trans('server/schedule.tasks.limit') : trans('server/schedule.tasks.create'))
 | |
|                     ->disabled(fn () => $schedule->tasks()->count() >= config('panel.client_features.schedules.per_schedule_task_limit', 10))
 | |
|                     ->schema($this->getTaskForm($schedule))
 | |
|                     ->action(function ($data) use ($schedule) {
 | |
|                         $sequenceId = ($schedule->tasks()->orderByDesc('sequence_id')->first()->sequence_id ?? 0) + 1;
 | |
| 
 | |
|                         $task = Task::query()->create([
 | |
|                             'schedule_id' => $schedule->id,
 | |
|                             'sequence_id' => $sequenceId,
 | |
|                             'action' => $data['action'],
 | |
|                             'payload' => $data['payload'] ?? '',
 | |
|                             'time_offset' => $data['time_offset'] ?? 0,
 | |
|                             'continue_on_failure' => (bool) $data['continue_on_failure'],
 | |
|                         ]);
 | |
| 
 | |
|                         Activity::event('server:task.create')
 | |
|                             ->subject($schedule, $task)
 | |
|                             ->property(['name' => $schedule->name, 'action' => $task->action, 'payload' => $task->payload])
 | |
|                             ->log();
 | |
|                     }),
 | |
|             ]);
 | |
|     }
 | |
| }
 | 
