mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-19 18:44:46 +02:00
Improve file error handling (#1314)
* improve file error handling * small cleanup * fix typo
This commit is contained in:
parent
2046fa453a
commit
92c23451af
@ -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('<code>' . $this->path . '</code> Max is ' . convert_bytes_to_readable(config('panel.files.max_edit_size')))
|
||||
->title('<code>' . basename($this->path) . '</code> 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('<code>' . $this->path . '</code>')
|
||||
->title('<code>' . basename($this->path) . '</code> 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('<code>' . $this->path . '</code>')
|
||||
->title('<code>' . basename($this->path) . '</code> 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'))
|
||||
|
@ -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([
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user