Add Egg copy from & ReplicateAction (#1013)

* Add `Egg` `copy from` for Process & Install Script

* Add builtin `ReplicateAction`

* Use `CopyFrom` for less duplicated code

* Hide label & add tooltip to `ReplicateAction`

* use `iconButton()` instead of `hiddenLabel()`

* use `iconButton()` for every Actions

* Use our translation instead

* Copy egg_variables aswell

* remove `get()`

Co-authored-by: Boy132 <Boy132@users.noreply.github.com>

---------
Co-authored-by: Boy132 <Boy132@users.noreply.github.com>
This commit is contained in:
MartinOscar 2025-02-19 19:52:10 +01:00 committed by GitHub
parent 5be4e22a0c
commit 324fc4b7d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 112 additions and 27 deletions

View File

@ -4,6 +4,7 @@ namespace App\Filament\Admin\Resources\EggResource\Pages;
use AbdelhamidErrahmouni\FilamentMonacoEditor\MonacoEditor;
use App\Filament\Admin\Resources\EggResource;
use App\Filament\Components\Forms\Fields\CopyFrom;
use App\Models\EggVariable;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Fieldset;
@ -117,12 +118,8 @@ class CreateEgg extends CreateRecord
Tab::make(trans('admin/egg.tabs.process_management'))
->columns()
->schema([
Hidden::make('config_from')
->default(null)
->label('Copy Settings From')
// ->placeholder('None')
// ->relationship('configFrom', 'name', ignoreRecord: true)
->helperText('If you would like to default to settings from another Egg select it from the menu above.'),
CopyFrom::make('copy_process_from')
->process(),
TextInput::make('config_stop')
->label(trans('admin/egg.stop_command'))
->required()
@ -237,10 +234,8 @@ class CreateEgg extends CreateRecord
Tab::make(trans('admin/egg.tabs.install_script'))
->columns(3)
->schema([
Hidden::make('copy_script_from'),
//->placeholder('None')
//->relationship('scriptFrom', 'name', ignoreRecord: true),
CopyFrom::make('copy_script_from')
->script(),
TextInput::make('script_container')
->label(trans('admin/egg.script_container'))
->required()

View File

@ -7,6 +7,7 @@ use App\Filament\Admin\Resources\EggResource;
use App\Filament\Admin\Resources\EggResource\RelationManagers\ServersRelationManager;
use App\Filament\Components\Actions\ExportEggAction;
use App\Filament\Components\Actions\ImportEggAction;
use App\Filament\Components\Forms\Fields\CopyFrom;
use App\Models\Egg;
use App\Models\EggVariable;
use Filament\Actions\DeleteAction;
@ -112,11 +113,8 @@ class EditEgg extends EditRecord
->columns()
->icon('tabler-server-cog')
->schema([
Select::make('config_from')
->label(trans('admin/egg.copy_from'))
->placeholder(trans('admin/egg.none'))
->relationship('configFrom', 'name', ignoreRecord: true)
->helperText(trans('admin/egg.copy_from_help')),
CopyFrom::make('copy_process_from')
->process(),
TextInput::make('config_stop')
->label(trans('admin/egg.stop_command'))
->maxLength(255)
@ -228,20 +226,18 @@ class EditEgg extends EditRecord
->columns(3)
->icon('tabler-file-download')
->schema([
Select::make('copy_script_from')
->label(trans('admin/egg.script_from'))
->placeholder(trans('admin/egg.none'))
->relationship('scriptFrom', 'name', ignoreRecord: true),
CopyFrom::make('copy_script_from')
->script(),
TextInput::make('script_container')
->label(trans('admin/egg.script_container'))
->required()
->maxLength(255)
->default('alpine:3.4'),
TextInput::make('script_entry')
->placeholder('ghcr.io/pelican-eggs/installers:debian'),
Select::make('script_entry')
->label(trans('admin/egg.script_entry'))
->required()
->maxLength(255)
->default('ash'),
->selectablePlaceholder(false)
->options(['bash', 'ash', '/bin/bash'])
->required(),
MonacoEditor::make('script_install')
->label(trans('admin/egg.script_install'))
->placeholderText('')

View File

@ -14,8 +14,10 @@ use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\CreateAction;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Actions\ReplicateAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Support\Str;
class ListEggs extends ListRecords
{
@ -44,9 +46,28 @@ class ListEggs extends ListRecords
->label(trans('admin/egg.servers')),
])
->actions([
EditAction::make(),
ExportEggAction::make(),
UpdateEggAction::make(),
EditAction::make()
->iconButton()
->tooltip(trans('filament-actions::edit.single.label')),
ExportEggAction::make()
->iconButton()
->tooltip(trans('filament-actions::export.modal.actions.export.label')),
UpdateEggAction::make()
->iconButton()
->tooltip(trans('admin/egg.update')),
ReplicateAction::make()
->iconButton()
->tooltip(trans('filament-actions::replicate.single.label'))
->modal(false)
->excludeAttributes(['author', 'uuid', 'update_url', 'servers_count', 'created_at', 'updated_at'])
->beforeReplicaSaved(function (Egg $replica) {
$replica->author = auth()->user()->email;
$replica->name .= ' Copy';
$replica->uuid = Str::uuid()->toString();
})
->after(fn (Egg $record, Egg $replica) => $record->variables->each(fn ($variable) => $variable->replicate()->fill(['egg_id' => $replica->id])->save()))
->successRedirectUrl(fn (Egg $replica) => EditEgg::getUrl(['record' => $replica]))
->authorize(fn () => auth()->user()->can('create egg')),
])
->bulkActions([
BulkActionGroup::make([

View File

@ -0,0 +1,69 @@
<?php
namespace App\Filament\Components\Forms\Fields;
use App\Models\Egg;
use Filament\Forms\Components\Select;
use Filament\Forms\Set;
use Livewire\Component;
class CopyFrom extends Select
{
protected function setUp(): void
{
parent::setUp();
$this->label(trans('admin/egg.copy_from'));
$this->placeholder(trans('admin/egg.none'));
$this->live();
}
public function process(): static
{
$this->helperText(trans('admin/egg.copy_from_help'));
$this->relationship('configFrom', 'name', ignoreRecord: true);
$this->afterStateUpdated(function ($state, Set $set) {
$set('copy_script_from', $state);
if ($state === null) {
$set('config_stop', '');
$set('config_startup', '{}');
$set('config_files', '{}');
$set('config_logs', '{}');
return;
}
$egg = Egg::find($state);
$set('config_stop', $egg->config_stop);
$set('config_startup', $egg->config_startup);
$set('config_files', $egg->config_files);
$set('config_logs', $egg->config_logs);
});
return $this;
}
public function script(): static
{
$this->relationship('scriptFrom', 'name', ignoreRecord: true);
$this->afterStateUpdated(function ($state, Set $set, Component $livewire) {
if ($state === null) {
$set('script_container', 'ghcr.io/pelican-eggs/installers:debian');
$set('script_entry', 'bash');
$livewire->dispatch('setContent', content: '');
return;
}
$egg = Egg::find($state);
$set('script_container', $egg->script_container);
$set('script_entry', $egg->script_entry);
$livewire->dispatch('setContent', content: $egg->script_install);
});
return $this;
}
}

View File

@ -1,5 +1,9 @@
@script
<script>
$wire.on('setContent', ({ content }) => {
document.getElementById('{{ $getId() }}').editor.getModel().setValue(content);
});
$wire.on('setLanguage', ({ lang }) => {
monaco.editor.setModelLanguage(document.getElementById('{{ $getId() }}').editor.getModel(), lang);
});