Merge remote-tracking branch 'origin/main' into filament-v4

This commit is contained in:
notCharles 2025-06-26 16:07:52 -04:00
commit 5370d9e2a6
5 changed files with 65 additions and 13 deletions

View File

@ -0,0 +1,7 @@
<?php
namespace App\Exceptions\Repository;
use Exception;
class FileExistsException extends Exception {}

View File

@ -2,6 +2,7 @@
namespace App\Filament\Server\Resources\FileResource\Pages; namespace App\Filament\Server\Resources\FileResource\Pages;
use App\Exceptions\Repository\FileExistsException;
use Exception; use Exception;
use App\Facades\Activity; use App\Facades\Activity;
use App\Filament\Server\Resources\FileResource; use App\Filament\Server\Resources\FileResource;
@ -11,6 +12,7 @@ use App\Models\Server;
use App\Repositories\Daemon\DaemonFileRepository; use App\Repositories\Daemon\DaemonFileRepository;
use App\Filament\Components\Tables\Columns\BytesColumn; use App\Filament\Components\Tables\Columns\BytesColumn;
use App\Filament\Components\Tables\Columns\DateTimeColumn; use App\Filament\Components\Tables\Columns\DateTimeColumn;
use App\Livewire\AlertBanner;
use App\Traits\Filament\CanCustomizeHeaderActions; use App\Traits\Filament\CanCustomizeHeaderActions;
use App\Traits\Filament\CanCustomizeHeaderWidgets; use App\Traits\Filament\CanCustomizeHeaderWidgets;
use Filament\Actions\Action; use Filament\Actions\Action;
@ -421,11 +423,22 @@ class ListFiles extends ListRecords
->keyBindings('') ->keyBindings('')
->modalSubmitActionLabel('Create') ->modalSubmitActionLabel('Create')
->action(function ($data) { ->action(function ($data) {
$this->getDaemonFileRepository()->putContent(join_paths($this->path, $data['name']), $data['editor'] ?? ''); $path = join_paths($this->path, $data['name']);
try {
$this->getDaemonFileRepository()->putContent($path, $data['editor'] ?? '');
Activity::event('server:file.write') Activity::event('server:file.write')
->property('file', join_paths($this->path, $data['name'])) ->property('file', join_paths($path, $data['name']))
->log(); ->log();
} catch (FileExistsException) {
AlertBanner::make()
->title('<code>' . $path . '</code> already exists!')
->danger()
->closable()
->send();
$this->redirect(self::getUrl(['path' => dirname($path)]));
}
}) })
->schema([ ->schema([
TextInput::make('name') TextInput::make('name')
@ -439,11 +452,22 @@ class ListFiles extends ListRecords
->label('New Folder') ->label('New Folder')
->color('gray') ->color('gray')
->action(function ($data) { ->action(function ($data) {
try {
$this->getDaemonFileRepository()->createDirectory($data['name'], $this->path); $this->getDaemonFileRepository()->createDirectory($data['name'], $this->path);
Activity::event('server:file.create-directory') Activity::event('server:file.create-directory')
->property(['directory' => $this->path, 'name' => $data['name']]) ->property(['directory' => $this->path, 'name' => $data['name']])
->log(); ->log();
} catch (FileExistsException) {
$path = join_paths($this->path, $data['name']);
AlertBanner::make()
->title('<code>' . $path . '</code> already exists!')
->danger()
->closable()
->send();
$this->redirect(self::getUrl(['path' => dirname($path)]));
}
}) })
->schema([ ->schema([
TextInput::make('name') TextInput::make('name')

View File

@ -14,6 +14,7 @@ use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle; use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Components\Utilities\Get;
use Filament\Actions\EditAction; use Filament\Actions\EditAction;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Tables\Table; use Filament\Tables\Table;
use Filament\Resources\RelationManagers\RelationManager; use Filament\Resources\RelationManagers\RelationManager;
use Filament\Actions\CreateAction; use Filament\Actions\CreateAction;
@ -48,10 +49,11 @@ class TasksRelationManager extends RelationManager
Select::make('action') Select::make('action')
->required() ->required()
->live() ->live()
->disableOptionWhen(fn (string $value): bool => $value === Task::ACTION_BACKUP && $schedule->server->backup_limit === 0) ->disableOptionWhen(fn (string $value) => $value === Task::ACTION_BACKUP && $schedule->server->backup_limit === 0)
->options($this->getActionOptions()) ->options($this->getActionOptions())
->selectablePlaceholder(false) ->selectablePlaceholder(false)
->default(Task::ACTION_POWER), ->default(Task::ACTION_POWER)
->afterStateUpdated(fn ($state, Set $set) => $set('payload', $state === Task::ACTION_POWER ? 'restart' : null)),
Textarea::make('payload') Textarea::make('payload')
->hidden(fn (Get $get) => $get('action') === Task::ACTION_POWER) ->hidden(fn (Get $get) => $get('action') === Task::ACTION_POWER)
->label(fn (Get $get) => $this->getActionOptions(false)[$get('action')] ?? 'Payload'), ->label(fn (Get $get) => $this->getActionOptions(false)[$get('action')] ?? 'Payload'),
@ -87,7 +89,8 @@ class TasksRelationManager extends RelationManager
$schedule = $this->getOwnerRecord(); $schedule = $this->getOwnerRecord();
return $table return $table
->reorderable('sequence_id', true) ->reorderable('sequence_id')
->defaultSort('sequence_id')
->columns([ ->columns([
TextColumn::make('action') TextColumn::make('action')
->state(fn (Task $task) => $this->getActionOptions()[$task->action] ?? $task->action), ->state(fn (Task $task) => $this->getActionOptions()[$task->action] ?? $task->action),

View File

@ -5,6 +5,7 @@ namespace App\Repositories\Daemon;
use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Http\Client\Response; use Illuminate\Http\Client\Response;
use App\Exceptions\Http\Server\FileSizeTooLargeException; use App\Exceptions\Http\Server\FileSizeTooLargeException;
use App\Exceptions\Repository\FileExistsException;
use App\Exceptions\Repository\FileNotEditableException; use App\Exceptions\Repository\FileNotEditableException;
use Illuminate\Http\Client\ConnectionException; use Illuminate\Http\Client\ConnectionException;
@ -46,13 +47,20 @@ class DaemonFileRepository extends DaemonRepository
* a file. * a file.
* *
* @throws ConnectionException * @throws ConnectionException
* @throws FileExistsException
*/ */
public function putContent(string $path, string $content): Response public function putContent(string $path, string $content): Response
{ {
return $this->getHttpClient() $response = $this->getHttpClient()
->withQueryParameters(['file' => $path]) ->withQueryParameters(['file' => $path])
->withBody($content) ->withBody($content)
->post("/api/servers/{$this->server->uuid}/files/write"); ->post("/api/servers/{$this->server->uuid}/files/write");
if ($response->getStatusCode() === 400) {
throw new FileExistsException();
}
return $response;
} }
/** /**
@ -73,15 +81,22 @@ class DaemonFileRepository extends DaemonRepository
* Creates a new directory for the server in the given $path. * Creates a new directory for the server in the given $path.
* *
* @throws ConnectionException * @throws ConnectionException
* @throws FileExistsException
*/ */
public function createDirectory(string $name, string $path): Response public function createDirectory(string $name, string $path): Response
{ {
return $this->getHttpClient()->post("/api/servers/{$this->server->uuid}/files/create-directory", $response = $this->getHttpClient()->post("/api/servers/{$this->server->uuid}/files/create-directory",
[ [
'name' => $name, 'name' => $name,
'path' => $path, 'path' => $path,
] ]
); );
if ($response->getStatusCode() === 400) {
throw new FileExistsException();
}
return $response;
} }
/** /**

View File

@ -57,6 +57,9 @@ abstract class DaemonRepository
if (is_bool($condition)) { if (is_bool($condition)) {
return $condition; return $condition;
} }
if ($condition->clientError()) {
return false;
}
$header = $condition->header('User-Agent'); $header = $condition->header('User-Agent');
if ( if (