2025-09-05 12:18:23 +00:00

144 lines
7.0 KiB
PHP

<?php
namespace App\Filament\Admin\Resources\Servers\RelationManagers;
use Filament\Actions\DeleteAction;
use Filament\Actions\ViewAction;
use Filament\Schemas\Schema;
use App\Filament\Components\Actions\RotateDatabasePasswordAction;
use App\Filament\Components\Tables\Columns\DateTimeColumn;
use App\Models\Database;
use App\Models\DatabaseHost;
use App\Models\Server;
use App\Services\Databases\DatabaseManagementService;
use App\Services\Servers\RandomWordService;
use Exception;
use Filament\Actions\CreateAction;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Support\Exceptions\Halt;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
/**
* @method Server getOwnerRecord()
*/
class DatabasesRelationManager extends RelationManager
{
protected static string $relationship = 'databases';
public function form(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('database')
->columnSpanFull(),
TextInput::make('username')
->label(trans('admin/databasehost.table.username')),
TextInput::make('password')
->label(trans('admin/databasehost.table.password'))
->password()
->revealable()
->hintAction(RotateDatabasePasswordAction::make())
->formatStateUsing(fn (Database $database) => $database->password),
TextInput::make('remote')
->label(trans('admin/databasehost.table.remote'))
->formatStateUsing(fn (Database $record) => $record->remote === '%' ? trans('admin/databasehost.anywhere'). ' ( % )' : $record->remote),
TextInput::make('max_connections')
->label(trans('admin/databasehost.table.max_connections'))
->formatStateUsing(fn (Database $record) => $record->max_connections === 0 ? trans('admin/databasehost.unlimited') : $record->max_connections),
TextInput::make('jdbc')
->label(trans('admin/databasehost.table.connection_string'))
->columnSpanFull()
->password()
->revealable()
->formatStateUsing(fn (Database $database) => $database->jdbc),
]);
}
public function table(Table $table): Table
{
return $table
->recordTitleAttribute('database')
->columns([
TextColumn::make('database')
->icon('tabler-database'),
TextColumn::make('username')
->label(trans('admin/databasehost.table.username'))
->icon('tabler-user'),
TextColumn::make('remote')
->label(trans('admin/databasehost.table.remote'))
->formatStateUsing(fn (Database $record) => $record->remote === '%' ? trans('admin/databasehost.anywhere'). ' ( % )' : $record->remote),
TextColumn::make('server.name')
->icon('tabler-brand-docker')
->url(fn (Database $database) => route('filament.admin.resources.servers.edit', ['record' => $database->server_id])),
TextColumn::make('max_connections')
->label(trans('admin/databasehost.table.max_connections'))
->formatStateUsing(fn ($record) => $record->max_connections === 0 ? trans('admin/databasehost.unlimited') : $record->max_connections),
DateTimeColumn::make('created_at')
->label(trans('admin/databasehost.table.created_at')),
])
->recordActions([
ViewAction::make()
->color('primary'),
DeleteAction::make(),
])
->headerActions([
CreateAction::make()
->disabled(fn () => DatabaseHost::count() < 1)
->label(fn () => DatabaseHost::count() < 1 ? trans('admin/server.no_db_hosts') : trans('admin/server.create_database'))
->color(fn () => DatabaseHost::count() < 1 ? 'danger' : 'primary')
->createAnother(false)
->action(function (array $data, DatabaseManagementService $service, RandomWordService $randomWordService) {
if (empty($data['database'])) {
$data['database'] = $randomWordService->word() . random_int(1, 420);
}
if (empty($data['remote'])) {
$data['remote'] = '%';
}
$data['database'] = $service->generateUniqueDatabaseName($data['database'], $this->getOwnerRecord()->id);
try {
return $service->setValidateDatabaseLimit(false)->create($this->getOwnerRecord(), $data);
} catch (Exception $exception) {
Notification::make()
->title(trans('admin/server.failed_to_create'))
->body($exception->getMessage())
->danger()
->persistent()->send();
throw new Halt();
}
})
->schema([
Select::make('database_host_id')
->label(trans('admin/databasehost.model_label'))
->required()
->placeholder(trans('admin/databasehost.table.select_placeholder'))
->options(fn () => DatabaseHost::query()
->whereHas('nodes', fn ($query) => $query->where('nodes.id', $this->getOwnerRecord()->node_id))
->pluck('name', 'id')
)
->default(fn () => (DatabaseHost::query()->first())?->id)
->selectablePlaceholder(false),
TextInput::make('database')
->label(trans('admin/server.name'))
->alphaDash()
->prefix(fn () => 's' . $this->getOwnerRecord()->id . '_')
->hintIcon('tabler-question-mark')
->hintIconTooltip(trans('admin/databasehost.table.name_helper')),
TextInput::make('remote')
->columnSpan(1)
->regex('/^[\w\-\/.%:]+$/')
->label(trans('admin/databasehost.table.remote'))
->default('%')
->hintIcon('tabler-question-mark')
->hintIconTooltip(trans('admin/databasehost.table.remote_helper')),
]),
]);
}
}