diff --git a/app/Filament/App/Resources/FileResource.php b/app/Filament/App/Resources/FileResource.php index e7f7efac77..fad0dec86c 100644 --- a/app/Filament/App/Resources/FileResource.php +++ b/app/Filament/App/Resources/FileResource.php @@ -16,7 +16,8 @@ class FileResource extends Resource public static function getPages(): array { return [ - 'edit' => Pages\EditFiles::route('/edit/{path?}'), + 'edit' => Pages\EditFiles::route('/edit/{path}'), + 'search' => Pages\SearchFiles::route('/search/{searchTerm}/{path}'), // TODO: find better way? 'index' => Pages\ListFiles::route('/{path?}'), ]; } diff --git a/app/Filament/App/Resources/FileResource/Pages/ListFiles.php b/app/Filament/App/Resources/FileResource/Pages/ListFiles.php index 688e121e9c..8b0f4cdc1e 100644 --- a/app/Filament/App/Resources/FileResource/Pages/ListFiles.php +++ b/app/Filament/App/Resources/FileResource/Pages/ListFiles.php @@ -14,24 +14,17 @@ 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; @@ -44,9 +37,7 @@ 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 @@ -566,71 +557,16 @@ 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([ // TODO: replace modal with custom page - 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(6) - ->live() - ->schema([ - TextInput::make('name') - ->hidden(), - TextInput::make('size') - ->hidden(), - TextInput::make('symlink') - ->hidden(), - TextInput::make('directory') - ->hidden(), - Placeholder::make('icon') - ->label('') - ->content(fn (Get $get) => new HtmlString(Blade::render(<<<'BLADE' -
- -
- BLADE, ['icon' => $get('directory') ? 'tabler-folder' : ($get('symlink') ? 'tabler-file-symlink' : 'tabler-file')]))), - Placeholder::make('name') - ->label('') - ->content(fn (Get $get) => $get('name')) - ->columnSpan(3), - Placeholder::make('size') - ->label('') - ->content(fn (Get $get) => $get('directory') ? '' : convert_bytes_to_readable($get('size'))), - 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')), - ]), + ->modalSubmitActionLabel('Search') + ->form([ + TextInput::make('searchTerm') + ->placeholder('Enter a search term, e.g. *.txt') + ->minLength(3), + ]) + ->action(fn ($data) => redirect(SearchFiles::getUrl([ + 'searchTerm' => $data['searchTerm'], + 'path' => $this->path, + ]))), ]; } diff --git a/app/Filament/App/Resources/FileResource/Pages/SearchFiles.php b/app/Filament/App/Resources/FileResource/Pages/SearchFiles.php new file mode 100644 index 0000000000..e0950057ce --- /dev/null +++ b/app/Filament/App/Resources/FileResource/Pages/SearchFiles.php @@ -0,0 +1,75 @@ +searchTerm = $searchTerm; + $this->path = $path ?? '/'; + } + + public function table(Table $table): Table + { + return $table + ->paginated(false) + ->query(function () { + /** @var Server $server */ + $server = Filament::getTenant(); + + return File::get($server, $this->path, $this->searchTerm)->orderByDesc('is_directory')->orderBy('name'); + }) + ->columns([ + TextColumn::make('name') + ->searchable() + ->icon(fn (File $file) => $file->getIcon()), + TextColumn::make('size') + ->formatStateUsing(fn ($state, File $file) => $file->is_file ? convert_bytes_to_readable($state) : ''), + TextColumn::make('modified_at') + ->dateTime() + ->sortable() + ->formatStateUsing(fn ($state) => $state->diffForHumans()) + ->tooltip(fn (File $file) => $file->modified_at), + ]) + ->recordUrl(function (File $file) { + if ($file->is_directory) { + return ListFiles::getUrl(['path' => join_paths($this->path, $file->name)]); + } + + return $file->canEdit() ? EditFiles::getUrl(['path' => join_paths($this->path, $file->name)]) : null; + }); + } + + public static function route(string $path): PageRegistration + { + return new PageRegistration( + page: static::class, + route: fn (Panel $panel): Route => RouteFacade::get($path, static::class) + ->middleware(static::getRouteMiddleware($panel)) + ->withoutMiddleware(static::getWithoutRouteMiddleware($panel)) + ->where('path', '.*'), + ); + } +} diff --git a/app/Models/File.php b/app/Models/File.php index 3a0b6149de..c5660cfdcf 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -49,11 +49,13 @@ class File extends Model protected static Server $server; protected static string $path; + protected static ?string $searchTerm; - public static function get(Server $server, string $path = '/'): Builder + public static function get(Server $server, string $path = '/', string $searchTerm = null): Builder { self::$server = $server; self::$path = $path; + self::$searchTerm = $searchTerm; return self::query(); } @@ -126,9 +128,10 @@ public function getSchema(): array public function getRows(): array { try { - $contents = app(DaemonFileRepository::class) - ->setServer($this->server()) - ->getDirectory(self::$path ?? '/'); + /** @var DaemonFileRepository $fileRepository */ + $fileRepository = app(DaemonFileRepository::class)->setServer($this->server); + + $contents = is_null(self::$searchTerm) ? $fileRepository->getDirectory(self::$path ?? '/') : $fileRepository->search(self::$searchTerm, self::$path); if (isset($contents['error'])) { throw new Exception($contents['error']); @@ -163,6 +166,6 @@ public function getRows(): array protected function sushiShouldCache(): bool { - return false; + return !is_null(self::$searchTerm); } }