mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-19 22:14:45 +02:00
185 lines
6.5 KiB
PHP
185 lines
6.5 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Server\Resources\FileResource\Pages;
|
|
|
|
use AbdelhamidErrahmouni\FilamentMonacoEditor\MonacoEditor;
|
|
use App\Enums\EditorLanguages;
|
|
use App\Facades\Activity;
|
|
use App\Filament\Server\Resources\FileResource;
|
|
use App\Models\File;
|
|
use App\Models\Permission;
|
|
use App\Models\Server;
|
|
use App\Repositories\Daemon\DaemonFileRepository;
|
|
use Filament\Facades\Filament;
|
|
use Filament\Forms\Components\Actions\Action;
|
|
use Filament\Forms\Components\Section;
|
|
use Filament\Forms\Components\Select;
|
|
use Filament\Forms\Concerns\InteractsWithForms;
|
|
use Filament\Forms\Form;
|
|
use Filament\Forms\Get;
|
|
use Filament\Notifications\Notification;
|
|
use Filament\Pages\Concerns\HasUnsavedDataChangesAlert;
|
|
use Filament\Pages\Concerns\InteractsWithFormActions;
|
|
use Filament\Panel;
|
|
use Filament\Resources\Pages\Page;
|
|
use Filament\Resources\Pages\PageRegistration;
|
|
use Filament\Support\Enums\Alignment;
|
|
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
|
use Illuminate\Routing\Route;
|
|
use Illuminate\Support\Facades\Route as RouteFacade;
|
|
use Livewire\Attributes\Locked;
|
|
|
|
/**
|
|
* @property Form $form
|
|
*/
|
|
class EditFiles extends Page
|
|
{
|
|
use HasUnsavedDataChangesAlert;
|
|
use InteractsWithFormActions;
|
|
use InteractsWithForms;
|
|
|
|
protected static string $resource = FileResource::class;
|
|
|
|
protected static string $view = 'filament.server.pages.edit-file';
|
|
|
|
#[Locked]
|
|
public string $path;
|
|
|
|
public ?array $data = [];
|
|
|
|
public function form(Form $form): Form
|
|
{
|
|
/** @var Server $server */
|
|
$server = Filament::getTenant();
|
|
|
|
File::get($server, dirname($this->path))->orderByDesc('is_directory')->orderBy('name');
|
|
|
|
return $form
|
|
->schema([
|
|
Select::make('lang')
|
|
->live()
|
|
->label('')
|
|
->placeholder('File Language')
|
|
->options(EditorLanguages::class)
|
|
->hidden() //TODO Fix Dis
|
|
->default(function () {
|
|
$split = explode('.', $this->path);
|
|
|
|
return end($split);
|
|
}),
|
|
Section::make('Editing: ' . $this->path)
|
|
->footerActions([
|
|
Action::make('save')
|
|
->label('Save')
|
|
->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_UPDATE, $server))
|
|
->icon('tabler-device-floppy')
|
|
->keyBindings('mod+s')
|
|
->action(function (DaemonFileRepository $fileRepository) use ($server) {
|
|
$data = $this->form->getState();
|
|
|
|
$fileRepository
|
|
->setServer($server)
|
|
->putContent($this->path, $data['editor'] ?? '');
|
|
|
|
Activity::event('server:file.write')
|
|
->property('file', $this->path)
|
|
->log();
|
|
|
|
Notification::make()
|
|
->success()
|
|
->duration(5000) // 5 seconds
|
|
->title('Saved File')
|
|
->body(fn () => $this->path)
|
|
->send();
|
|
|
|
$this->redirect(ListFiles::getUrl(['path' => dirname($this->path)]));
|
|
}),
|
|
Action::make('cancel')
|
|
->label('Cancel')
|
|
->color('danger')
|
|
->icon('tabler-x')
|
|
->url(fn () => ListFiles::getUrl(['path' => dirname($this->path)])),
|
|
])
|
|
->footerActionsAlignment(Alignment::End)
|
|
->schema([
|
|
MonacoEditor::make('editor')
|
|
->label('')
|
|
->placeholderText('')
|
|
->formatStateUsing(function (DaemonFileRepository $fileRepository) use ($server) {
|
|
try {
|
|
return $fileRepository
|
|
->setServer($server)
|
|
->getContent($this->path, config('panel.files.max_edit_size'));
|
|
} catch (FileNotFoundException) {
|
|
abort(404, $this->path . ' not found.');
|
|
}
|
|
})
|
|
->language(fn (Get $get) => $get('lang') ?? 'plaintext')
|
|
->view('filament.plugins.monaco-editor'),
|
|
]),
|
|
]);
|
|
}
|
|
|
|
public function mount(string $path): void
|
|
{
|
|
$this->authorizeAccess();
|
|
|
|
$this->path = $path;
|
|
|
|
$this->form->fill();
|
|
}
|
|
|
|
protected function authorizeAccess(): void
|
|
{
|
|
abort_unless(auth()->user()->can(Permission::ACTION_FILE_READ_CONTENT, Filament::getTenant()), 403);
|
|
}
|
|
|
|
/**
|
|
* @return array<int | string, string | Form>
|
|
*/
|
|
protected function getForms(): array
|
|
{
|
|
return [
|
|
'form' => $this->form(static::getResource()::form(
|
|
$this->makeForm()
|
|
->statePath($this->getFormStatePath())
|
|
->columns($this->hasInlineLabels() ? 1 : 2)
|
|
->inlineLabel($this->hasInlineLabels()),
|
|
)),
|
|
];
|
|
}
|
|
|
|
public function getFormStatePath(): ?string
|
|
{
|
|
return 'data';
|
|
}
|
|
|
|
public function getBreadcrumbs(): array
|
|
{
|
|
$resource = static::getResource();
|
|
|
|
$breadcrumbs = [
|
|
$resource::getUrl() => $resource::getBreadcrumb(),
|
|
];
|
|
|
|
$previousParts = '';
|
|
foreach (explode('/', $this->path) as $part) {
|
|
$previousParts = $previousParts . '/' . $part;
|
|
$breadcrumbs[self::getUrl(['path' => ltrim($previousParts, '/')])] = $part;
|
|
}
|
|
|
|
return $breadcrumbs;
|
|
}
|
|
|
|
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', '.*'),
|
|
);
|
|
}
|
|
}
|