diff --git a/app/Filament/Server/Resources/FileResource/Pages/EditFiles.php b/app/Filament/Server/Resources/FileResource/Pages/EditFiles.php index 3d0ee258d..8795bee82 100644 --- a/app/Filament/Server/Resources/FileResource/Pages/EditFiles.php +++ b/app/Filament/Server/Resources/FileResource/Pages/EditFiles.php @@ -26,6 +26,7 @@ use Filament\Resources\Pages\Page; use Filament\Resources\Pages\PageRegistration; use Filament\Support\Enums\Alignment; use Illuminate\Contracts\Filesystem\FileNotFoundException; +use Illuminate\Http\Client\ConnectionException; use Illuminate\Routing\Route; use Illuminate\Support\Facades\Route as RouteFacade; use Livewire\Attributes\Locked; @@ -128,31 +129,33 @@ class EditFiles extends Page return $this->getDaemonFileRepository()->getContent($this->path, config('panel.files.max_edit_size')); } catch (FileSizeTooLargeException) { AlertBanner::make() - ->title('File too large!') - ->body('' . $this->path . ' Max is ' . convert_bytes_to_readable(config('panel.files.max_edit_size'))) + ->title('' . basename($this->path) . ' is too large!') + ->body('Max is ' . convert_bytes_to_readable(config('panel.files.max_edit_size'))) ->danger() ->closable() ->send(); - $this->redirect(ListFiles::getUrl()); + $this->redirect(ListFiles::getUrl(['path' => dirname($this->path)])); } catch (FileNotFoundException) { AlertBanner::make() - ->title('File Not found!') - ->body('' . $this->path . '') + ->title('' . basename($this->path) . ' not found!') ->danger() ->closable() ->send(); - $this->redirect(ListFiles::getUrl()); + $this->redirect(ListFiles::getUrl(['path' => dirname($this->path)])); } catch (FileNotEditableException) { AlertBanner::make() - ->title('Could not edit directory!') - ->body('' . $this->path . '') + ->title('' . basename($this->path) . ' is a directory') ->danger() ->closable() ->send(); - $this->redirect(ListFiles::getUrl()); + $this->redirect(ListFiles::getUrl(['path' => dirname($this->path)])); + } catch (ConnectionException) { + // Alert banner for this one will be handled by ListFiles + + $this->redirect(ListFiles::getUrl(['path' => dirname($this->path)])); } }) ->language(fn (Get $get) => $get('lang')) diff --git a/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php b/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php index fd709812f..5992f31a7 100644 --- a/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php +++ b/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php @@ -12,7 +12,6 @@ use App\Models\Server; use App\Repositories\Daemon\DaemonFileRepository; use App\Filament\Components\Tables\Columns\BytesColumn; use App\Filament\Components\Tables\Columns\DateTimeColumn; -use App\Livewire\AlertBanner; use Filament\Actions\Action as HeaderAction; use Filament\Facades\Filament; use Filament\Forms\Components\CheckboxList; @@ -30,14 +29,12 @@ use Filament\Resources\Pages\PageRegistration; use Filament\Tables\Actions\Action; use Filament\Tables\Actions\ActionGroup; use Filament\Tables\Actions\BulkAction; -use Filament\Tables\Actions\BulkActionGroup; use Filament\Tables\Actions\DeleteAction; use Filament\Tables\Actions\DeleteBulkAction; use Filament\Tables\Actions\EditAction; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Collection; -use Illuminate\Http\Client\ConnectionException; use Illuminate\Http\UploadedFile; use Illuminate\Routing\Route; use Illuminate\Support\Carbon; @@ -53,24 +50,11 @@ class ListFiles extends ListRecords private DaemonFileRepository $fileRepository; - private bool $isDisabled = false; - public function mount(?string $path = null): void { parent::mount(); $this->path = $path ?? '/'; - - try { - $this->getDaemonFileRepository()->getDirectory('/'); - } catch (ConnectionException) { - $this->isDisabled = true; - - AlertBanner::make('node_connection_error') - ->title('Could not connect to the node!') - ->danger() - ->send(); - } } public function getBreadcrumbs(): array @@ -130,21 +114,18 @@ class ListFiles extends ListRecords ->actions([ Action::make('view') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_READ, $server)) - ->disabled($this->isDisabled) ->label('Open') ->icon('tabler-eye') ->visible(fn (File $file) => $file->is_directory) ->url(fn (File $file) => self::getUrl(['path' => join_paths($this->path, $file->name)])), EditAction::make('edit') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_READ_CONTENT, $server)) - ->disabled($this->isDisabled) ->icon('tabler-edit') ->visible(fn (File $file) => $file->canEdit()) ->url(fn (File $file) => EditFiles::getUrl(['path' => join_paths($this->path, $file->name)])), ActionGroup::make([ Action::make('rename') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_UPDATE, $server)) - ->disabled($this->isDisabled) ->label('Rename') ->icon('tabler-forms') ->form([ @@ -173,7 +154,6 @@ class ListFiles extends ListRecords }), Action::make('copy') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_CREATE, $server)) - ->disabled($this->isDisabled) ->label('Copy') ->icon('tabler-copy') ->visible(fn (File $file) => $file->is_file) @@ -193,14 +173,12 @@ class ListFiles extends ListRecords }), Action::make('download') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_READ_CONTENT, $server)) - ->disabled($this->isDisabled) ->label('Download') ->icon('tabler-download') ->visible(fn (File $file) => $file->is_file) ->url(fn (File $file) => DownloadFiles::getUrl(['path' => join_paths($this->path, $file->name)]), true), Action::make('move') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_UPDATE, $server)) - ->disabled($this->isDisabled) ->label('Move') ->icon('tabler-replace') ->form([ @@ -236,7 +214,6 @@ class ListFiles extends ListRecords }), Action::make('permissions') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_UPDATE, $server)) - ->disabled($this->isDisabled) ->label('Permissions') ->icon('tabler-license') ->form([ @@ -293,7 +270,6 @@ class ListFiles extends ListRecords }), Action::make('archive') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_ARCHIVE, $server)) - ->disabled($this->isDisabled) ->label('Archive') ->icon('tabler-archive') ->form([ @@ -321,7 +297,6 @@ class ListFiles extends ListRecords }), Action::make('unarchive') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_ARCHIVE, $server)) - ->disabled($this->isDisabled) ->label('Unarchive') ->icon('tabler-archive') ->visible(fn (File $file) => $file->isArchive()) @@ -343,7 +318,6 @@ class ListFiles extends ListRecords ]), DeleteAction::make() ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_DELETE, $server)) - ->disabled($this->isDisabled) ->label('') ->icon('tabler-trash') ->requiresConfirmation() @@ -358,83 +332,77 @@ class ListFiles extends ListRecords ->log(); }), ]) - ->bulkActions([ - BulkActionGroup::make([ - BulkAction::make('move') - ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_UPDATE, $server)) - ->disabled($this->isDisabled) - ->form([ - TextInput::make('location') - ->label('Directory') - ->hint('Enter the new directory, relative to the current directory.') - ->required() - ->live(), - Placeholder::make('new_location') - ->content(fn (Get $get) => resolve_path('./' . join_paths($this->path, $get('location') ?? ''))), - ]) - ->action(function (Collection $files, $data) { - $location = rtrim($data['location'], '/'); + ->groupedBulkActions([ + BulkAction::make('move') + ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_UPDATE, $server)) + ->form([ + TextInput::make('location') + ->label('Directory') + ->hint('Enter the new directory, relative to the current directory.') + ->required() + ->live(), + Placeholder::make('new_location') + ->content(fn (Get $get) => resolve_path('./' . join_paths($this->path, $get('location') ?? ''))), + ]) + ->action(function (Collection $files, $data) { + $location = rtrim($data['location'], '/'); - $files = $files->map(fn ($file) => ['to' => join_paths($location, $file['name']), 'from' => $file['name']])->toArray(); - $this->getDaemonFileRepository() - ->renameFiles($this->path, $files); + $files = $files->map(fn ($file) => ['to' => join_paths($location, $file['name']), 'from' => $file['name']])->toArray(); + $this->getDaemonFileRepository()->renameFiles($this->path, $files); - Activity::event('server:file.rename') - ->property('directory', $this->path) - ->property('files', $files) - ->log(); + Activity::event('server:file.rename') + ->property('directory', $this->path) + ->property('files', $files) + ->log(); - Notification::make() - ->title(count($files) . ' Files were moved to ' . resolve_path(join_paths($this->path, $location))) - ->success() - ->send(); - }), - BulkAction::make('archive') - ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_ARCHIVE, $server)) - ->disabled($this->isDisabled) - ->form([ - TextInput::make('name') - ->label('Archive name') - ->placeholder(fn () => 'archive-' . str(Carbon::now()->toRfc3339String())->replace(':', '')->before('+0000') . 'Z') - ->suffix('.tar.gz'), - ]) - ->action(function ($data, Collection $files) { - $files = $files->map(fn ($file) => $file['name'])->toArray(); + Notification::make() + ->title(count($files) . ' Files were moved to ' . resolve_path(join_paths($this->path, $location))) + ->success() + ->send(); + }), + BulkAction::make('archive') + ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_ARCHIVE, $server)) + ->form([ + TextInput::make('name') + ->label('Archive name') + ->placeholder(fn () => 'archive-' . str(Carbon::now()->toRfc3339String())->replace(':', '')->before('+0000') . 'Z') + ->suffix('.tar.gz'), + ]) + ->action(function ($data, Collection $files) { + $files = $files->map(fn ($file) => $file['name'])->toArray(); - $archive = $this->getDaemonFileRepository()->compressFiles($this->path, $files, $data['name']); + $archive = $this->getDaemonFileRepository()->compressFiles($this->path, $files, $data['name']); - Activity::event('server:file.compress') - ->property('name', $archive['name']) - ->property('directory', $this->path) - ->property('files', $files) - ->log(); + Activity::event('server:file.compress') + ->property('name', $archive['name']) + ->property('directory', $this->path) + ->property('files', $files) + ->log(); - Notification::make() - ->title('Archive created') - ->body($archive['name']) - ->success() - ->send(); + Notification::make() + ->title('Archive created') + ->body($archive['name']) + ->success() + ->send(); - return redirect(ListFiles::getUrl(['path' => $this->path])); - }), - DeleteBulkAction::make() - ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_DELETE, $server)) - ->disabled($this->isDisabled) - ->action(function (Collection $files) { - $files = $files->map(fn ($file) => $file['name'])->toArray(); - $this->getDaemonFileRepository()->deleteFiles($this->path, $files); + return redirect(ListFiles::getUrl(['path' => $this->path])); + }), + DeleteBulkAction::make() + ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_DELETE, $server)) + ->action(function (Collection $files) { + $files = $files->map(fn ($file) => $file['name'])->toArray(); + $this->getDaemonFileRepository()->deleteFiles($this->path, $files); - Activity::event('server:file.delete') - ->property('directory', $this->path) - ->property('files', $files) - ->log(); + Activity::event('server:file.delete') + ->property('directory', $this->path) + ->property('files', $files) + ->log(); - Notification::make() - ->title(count($files) . ' Files deleted.') - ->success() - ->send(); - }), - ]), + Notification::make() + ->title(count($files) . ' Files deleted.') + ->success() + ->send(); + }), ]); } @@ -446,7 +414,6 @@ class ListFiles extends ListRecords return [ HeaderAction::make('new_file') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_CREATE, $server)) - ->disabled($this->isDisabled) ->label('New File') ->color('gray') ->keyBindings('') @@ -478,7 +445,6 @@ class ListFiles extends ListRecords ]), HeaderAction::make('new_folder') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_CREATE, $server)) - ->disabled($this->isDisabled) ->label('New Folder') ->color('gray') ->action(function ($data) { @@ -495,7 +461,6 @@ class ListFiles extends ListRecords ]), HeaderAction::make('upload') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_CREATE, $server)) - ->disabled($this->isDisabled) ->label('Upload') ->action(function ($data) { if (count($data['files']) > 0 && !isset($data['url'])) { @@ -545,7 +510,6 @@ class ListFiles extends ListRecords ]), HeaderAction::make('search') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_READ, $server)) - ->disabled($this->isDisabled) ->label('Global Search') ->modalSubmitActionLabel('Search') ->form([ diff --git a/app/Models/File.php b/app/Models/File.php index 12479554b..1f4aa8b31 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -153,16 +153,10 @@ class File extends Model try { $fileRepository = (new DaemonFileRepository())->setServer(self::$server); - $contents = []; - - try { - if (!is_null(self::$searchTerm)) { - $contents = cache()->remember('file_search_' . self::$path . '_' . self::$searchTerm, now()->addMinute(), fn () => $fileRepository->search(self::$searchTerm, self::$path)); - } else { - $contents = $fileRepository->getDirectory(self::$path ?? '/'); - } - } catch (ConnectionException $exception) { - report($exception); + if (!is_null(self::$searchTerm)) { + $contents = cache()->remember('file_search_' . self::$path . '_' . self::$searchTerm, now()->addMinute(), fn () => $fileRepository->search(self::$searchTerm, self::$path)); + } else { + $contents = $fileRepository->getDirectory(self::$path ?? '/'); } if (isset($contents['error'])) { @@ -199,8 +193,12 @@ class File extends Model $message = $message->after('cURL error 7: ')->before(' after '); } + if ($exception instanceof ConnectionException) { + $message = str('Node connection failed'); + } + AlertBanner::make() - ->title('Could not load files') + ->title('Could not load files!') ->body($message->toString()) ->danger() ->send();