From b07bbfe18b90a340dbb758ffb2bf7b28fb0898a7 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 7 Oct 2024 12:33:45 +0200 Subject: [PATCH] add "global search" to files list requires https://github.com/pelican-dev/wings/pull/44 --- .../FileResource/Pages/ListFiles.php | 70 +++++++++++++++++++ .../Daemon/DaemonFileRepository.php | 48 +++++++++++++ 2 files changed, 118 insertions(+) diff --git a/app/Filament/App/Resources/FileResource/Pages/ListFiles.php b/app/Filament/App/Resources/FileResource/Pages/ListFiles.php index 6e5cdc8d0e..0c32b23402 100644 --- a/app/Filament/App/Resources/FileResource/Pages/ListFiles.php +++ b/app/Filament/App/Resources/FileResource/Pages/ListFiles.php @@ -14,17 +14,24 @@ use Carbon\CarbonImmutable; use Filament\Actions\Action as HeaderAction; use Filament\Facades\Filament; +use Filament\Forms\Components\Actions; +use Filament\Forms\Components\Actions\Action as FormAction; use Filament\Forms\Components\CheckboxList; use Filament\Forms\Components\FileUpload; use Filament\Forms\Components\Placeholder; +use Filament\Forms\Components\Repeater; use Filament\Forms\Components\Select; use Filament\Forms\Components\Tabs; use Filament\Forms\Components\TextInput; +use Filament\Forms\Components\Wizard; +use Filament\Forms\Components\Wizard\Step; use Filament\Forms\Get; +use Filament\Forms\Set; use Filament\Notifications\Notification; use Filament\Panel; use Filament\Resources\Pages\ListRecords; use Filament\Resources\Pages\PageRegistration; +use Filament\Support\Enums\VerticalAlignment; use Filament\Tables\Actions\Action; use Filament\Tables\Actions\ActionGroup; use Filament\Tables\Actions\BulkAction; @@ -37,7 +44,9 @@ use Illuminate\Database\Eloquent\Collection; use Illuminate\Http\UploadedFile; use Illuminate\Routing\Route; +use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Route as RouteFacade; +use Illuminate\Support\HtmlString; use Livewire\Attributes\Locked; class ListFiles extends ListRecords @@ -554,6 +563,67 @@ protected function getHeaderActions(): array ]), ]), ]), + HeaderAction::make('search') + ->authorize(auth()->user()->can(Permission::ACTION_FILE_READ, Filament::getTenant())) + ->label('Global Search') + ->modalSubmitAction(false) + ->modalCancelAction(false) + ->form([ + Wizard::make([ + Step::make('Input') + ->schema([ + TextInput::make('searchTerm') + ->placeholder('Enter a search term, e.g. *.txt') + ->minLength(3), + ]) + ->afterValidation(function (Get $get, Set $set) { + /** @var Server $server */ + $server = Filament::getTenant(); + + $foundFiles = app(DaemonFileRepository::class) + ->setServer($server) + ->search($get('searchTerm'), $this->path); + + $set('foundFiles', $foundFiles); + }), + Step::make('Result') + ->schema([ + Repeater::make('foundFiles') + ->disabled() + ->addable(false) + ->deletable(false) + ->reorderable(false) + ->defaultItems(0) + ->columns(5) + ->live() + ->schema([ // TODO: make pretty and mobile friendly + TextInput::make('name') + ->hidden(), + TextInput::make('symlink') + ->hidden(), + Placeholder::make('icon') + ->label('') + ->content(fn (Get $get) => new HtmlString(Blade::render(<<<'BLADE' +
+ +
+ BLADE, ['icon' => $get('symlink') ? 'tabler-file-symlink' : 'tabler-file']))), + Placeholder::make('name') + ->label('') + ->content(fn (Get $get) => $get('name')) + ->columnSpan(3), + Actions::make([ + FormAction::make('edit') + ->authorize(auth()->user()->can(Permission::ACTION_FILE_READ_CONTENT, Filament::getTenant())) + ->icon('tabler-edit') + ->url(fn (Get $get) => EditFiles::getUrl(['path' => join_paths($this->path, $get('name'))])), + ]) + ->verticalAlignment(VerticalAlignment::End), + ]), + ]), + ]) + ->nextAction(fn (FormAction $action) => $action->label('Search')), + ]), ]; } diff --git a/app/Repositories/Daemon/DaemonFileRepository.php b/app/Repositories/Daemon/DaemonFileRepository.php index 7667f482e8..20ae3dff1d 100644 --- a/app/Repositories/Daemon/DaemonFileRepository.php +++ b/app/Repositories/Daemon/DaemonFileRepository.php @@ -272,4 +272,52 @@ public function pull(string $url, ?string $directory, array $params = []) throw new DaemonConnectionException($exception); } } + + /** + * Searches all files in the directory (and its subdirectories) for the given search term. + * + * @throws \App\Exceptions\Http\Connection\DaemonConnectionException + */ + public function search(string $searchTerm, ?string $directory): array + { + Assert::isInstanceOf($this->server, Server::class); + + // DEBUG + return [ + [ + 'name' => 'yeet.txt', + 'size' => 420, + 'file' => true, + 'symlink' => false, + ], + [ + 'name' => 'yeet2.txt', + 'size' => 4200, + 'file' => true, + 'symlink' => false, + ], + [ + 'name' => 'yeet3.txt', + 'size' => 0, + 'file' => true, + 'symlink' => true, + ], + ]; + + try { + $response = $this->getHttpClient() + ->timeout(120) + ->get( + sprintf('/api/servers/%s/files/search', $this->server->uuid), + [ + 'pattern' => $searchTerm, + 'directory' => $directory ?? '/', + ] + ); + } catch (TransferException $exception) { + throw new DaemonConnectionException($exception); + } + + return $response->json(); + } }