add own CopyAction

This commit is contained in:
Boy132 2025-07-01 08:47:30 +02:00
parent f40e125d2f
commit 9da52c24c0
12 changed files with 91 additions and 31 deletions

View File

@ -42,7 +42,7 @@ final class DiscordProvider extends OAuthProvider
->label('Redirect URL')
->dehydrated()
->disabled()
//TODO ->hintAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->hintCopy()
->formatStateUsing(fn () => url('/auth/oauth/callback/discord')),
]),
], parent::getSetupSteps());

View File

@ -8,7 +8,6 @@ use Filament\Forms\Components\TextInput;
use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\HtmlString;
use Webbingbrasil\FilamentCopyActions\Forms\Actions\CopyAction;
final class GithubProvider extends OAuthProvider
{
@ -34,7 +33,7 @@ final class GithubProvider extends OAuthProvider
->label('Authorization callback URL')
->dehydrated()
->disabled()
//TODO ->hintAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->hintCopy()
->default(fn () => url('/auth/oauth/callback/github')),
TextEntry::make('register_application')
->hiddenLabel()

View File

@ -8,7 +8,6 @@ use Filament\Forms\Components\TextInput;
use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\HtmlString;
use Webbingbrasil\FilamentCopyActions\Forms\Actions\CopyAction;
final class GitlabProvider extends OAuthProvider
{
@ -54,7 +53,7 @@ final class GitlabProvider extends OAuthProvider
->label('Redirect URI')
->dehydrated()
->disabled()
//TODO ->hintAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->hintCopy()
->default(fn () => url('/auth/oauth/callback/gitlab')),
]),
], parent::getSetupSteps());

View File

@ -97,14 +97,14 @@ class CreateDatabaseHost extends CreateRecord
->default(fn (Get $get) => "CREATE USER '{$get('username')}'@'{$get('panel_ip')}' IDENTIFIED BY '{$get('password')}';")
->disabled()
->dehydrated(false)
// TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->suffixCopy()
->columnSpanFull(),
TextInput::make('assign_permissions')
->label(trans('admin/databasehost.setup.command_assign_permissions'))
->default(fn (Get $get) => "GRANT ALL PRIVILEGES ON *.* TO '{$get('username')}'@'{$get('panel_ip')}' WITH GRANT OPTION;")
->disabled()
->dehydrated(false)
// TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->suffixCopy()
->columnSpanFull(),
TextEntry::make('cli_exit')
->hiddenLabel()

View File

@ -293,7 +293,7 @@ class EditNode extends EditRecord
'lg' => 2,
])
->label(trans('admin/node.node_uuid'))
// TODO ->hintAction(fn () => request()->isSecure() ? CopyAction::make() : null)
->hintCopy()
->disabled(),
TagsInput::make('tags')
->label(trans('admin/node.tags'))
@ -554,7 +554,7 @@ class EditNode extends EditRecord
->label('/etc/pelican/config.yml')
->disabled()
->rows(19)
//TODO ->hintAction(fn () => request()->isSecure() ? CopyAction::make() : null)
->hintCopy()
->columnSpanFull(),
Grid::make()
->columns()
@ -591,7 +591,7 @@ class EditNode extends EditRecord
->label(trans('admin/node.auto_command'))
->readOnly()
->autosize()
//TODO ->hintAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->hintCopy()
->formatStateUsing(fn (NodeAutoDeployService $service, Node $node, Set $set, Get $get) => $set('generatedToken', $service->handle(request(), $node, $get('docker')))),
])
->mountUsing(function (Schema $schema) {

View File

@ -180,7 +180,7 @@ class EditServer extends EditRecord
TextInput::make('uuid')
->label(trans('admin/server.uuid'))
//TODO ->suffixAction(fn () => request()->isSecure() ? CopyAction::make() : null)
->suffixCopy()
->columnSpan([
'default' => 2,
'sm' => 1,
@ -191,7 +191,7 @@ class EditServer extends EditRecord
->dehydrated(false),
TextInput::make('uuid_short')
->label(trans('admin/server.short_uuid'))
//TODO ->suffixAction(fn () => request()->isSecure() ? CopyAction::make() : null)
->suffixCopy()
->columnSpan([
'default' => 2,
'sm' => 1,
@ -620,7 +620,7 @@ class EditServer extends EditRecord
->hintAction(PreviewStartupAction::make('preview')),
Textarea::make('defaultStartup')
//TODO ->hintAction(fn () => request()->isSecure() ? CopyAction::make() : null)
->hintCopy()
->label(trans('admin/server.default_startup'))
->disabled()
->autosize()
@ -719,13 +719,13 @@ class EditServer extends EditRecord
->label(trans('admin/databasehost.table.host'))
->disabled()
->formatStateUsing(fn ($record) => $record->address())
//TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->suffixCopy()
->columnSpan(1),
TextInput::make('database')
->label(trans('admin/databasehost.table.database'))
->disabled()
->formatStateUsing(fn ($record) => $record->database)
//TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->suffixCopy()
->hintAction(
Action::make('Delete')
->label(trans('filament-actions::delete.single.modal.actions.delete.label'))
@ -746,7 +746,7 @@ class EditServer extends EditRecord
->label(trans('admin/databasehost.table.username'))
->disabled()
->formatStateUsing(fn ($record) => $record->username)
//TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->suffixCopy()
->columnSpan(1),
TextInput::make('password')
->label(trans('admin/databasehost.table.password'))
@ -755,7 +755,7 @@ class EditServer extends EditRecord
->revealable()
->columnSpan(1)
->hintAction(RotateDatabasePasswordAction::make())
//TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->suffixCopy()
->formatStateUsing(fn (Database $database) => $database->password),
TextInput::make('remote')
->disabled()
@ -773,8 +773,8 @@ class EditServer extends EditRecord
->revealable()
->label(trans('admin/databasehost.table.connection_string'))
->columnSpan(2)
->formatStateUsing(fn (Database $record) => $record->jdbc),
//TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null),
->formatStateUsing(fn (Database $record) => $record->jdbc)
->suffixCopy(),
])
->relationship('databases')
->deletable(false)

View File

@ -0,0 +1,46 @@
<?php
namespace App\Filament\Components\Actions;
use Closure;
use Filament\Actions\Action;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Js;
use Livewire\Features\SupportJsEvaluation\HandlesJsEvaluation;
class CopyAction extends Action
{
use HandlesJsEvaluation;
protected Closure|string|null $copyable = null;
public static function getDefaultName(): ?string
{
return 'copy';
}
public function setUp(): void
{
parent::setUp();
$this->icon('tabler-clipboard-copy');
$this->successNotificationTitle(trans('filament::components/copyable.messages.copied'));
$this->extraAttributes(fn () => [
'x-on:click' => new HtmlString('window.navigator.clipboard.writeText('.$this->getCopyable().'); $tooltip('.Js::from($this->getSuccessNotificationTitle()).');'),
]);
}
public function copyable(Closure|string|null $copyable): self
{
$this->copyable = $copyable;
return $this;
}
public function getCopyable(): ?string
{
return Js::from($this->evaluate($this->copyable));
}
}

View File

@ -165,7 +165,7 @@ class Settings extends ServerFormPage
->label('Connection')
->columnSpan(1)
->disabled()
//TODO ->suffixAction(fn () => request()->isSecure() ? CopyAction::make() : null)
->suffixCopy()
->hintAction(
Action::make('connect_sftp')
->label('Connect to SFTP')
@ -185,7 +185,7 @@ class Settings extends ServerFormPage
TextInput::make('username')
->label('Username')
->columnSpan(1)
//TODO ->suffixAction(fn () => request()->isSecure() ? CopyAction::make() : null)
->suffixCopy()
->disabled()
->formatStateUsing(fn (Server $server) => auth()->user()->username . '.' . $server->uuid_short),
TextEntry::make('password')

View File

@ -69,12 +69,12 @@ class DatabaseResource extends Resource
return $schema
->components([
TextInput::make('host')
->formatStateUsing(fn (Database $database) => $database->address()),
// TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null),
TextInput::make('database'),
//TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null),
TextInput::make('username'),
//TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null),
->formatStateUsing(fn (Database $database) => $database->address())
->suffixCopy(),
TextInput::make('database')
->suffixCopy(),
TextInput::make('username')
->suffixCopy(),
TextInput::make('password')
->password()->revealable()
->hidden(fn () => !auth()->user()->can(Permission::ACTION_DATABASE_VIEW_PASSWORD, $server))
@ -82,7 +82,7 @@ class DatabaseResource extends Resource
RotateDatabasePasswordAction::make()
->authorize(fn () => auth()->user()->can(Permission::ACTION_DATABASE_UPDATE, $server))
)
//TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->suffixCopy()
->formatStateUsing(fn (Database $database) => $database->password),
TextInput::make('remote')
->label('Connections From'),
@ -92,7 +92,7 @@ class DatabaseResource extends Resource
->label('JDBC Connection String')
->password()->revealable()
->hidden(!auth()->user()->can(Permission::ACTION_DATABASE_VIEW_PASSWORD, $server))
//TODO ->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null)
->suffixCopy()
->columnSpanFull()
->formatStateUsing(fn (Database $database) => $database->jdbc),
]);

View File

@ -48,14 +48,14 @@ class QueueStep
TextInput::make('crontab')
->label(new HtmlString('Run the following command to set up your crontab. Note that <code>www-data</code> is your webserver user. On some systems this username might be different!'))
->disabled()
//TODO ->hintAction(fn () => request()->isSecure() ? CopyAction::make() : null)
->hintCopy()
->default('(crontab -l -u www-data 2>/dev/null; echo "* * * * * php ' . base_path() . '/artisan schedule:run >> /dev/null 2>&1") | crontab -u www-data -')
->hidden(fn () => @file_exists('/.dockerenv'))
->columnSpanFull(),
TextInput::make('queueService')
->label(new HtmlString('To setup the queue worker service you simply have to run the following command.'))
->disabled()
//TODO ->hintAction(fn () => request()->isSecure() ? CopyAction::make() : null)
->hintCopy()
->default('sudo php ' . base_path() . '/artisan p:environment:queue-service')
->hidden(fn () => @file_exists('/.dockerenv'))
->columnSpanFull(),

View File

@ -36,10 +36,13 @@ use App\Extensions\OAuth\Providers\CommonProvider;
use App\Extensions\OAuth\Providers\DiscordProvider;
use App\Extensions\OAuth\Providers\GithubProvider;
use App\Extensions\OAuth\Providers\SteamProvider;
use App\Filament\Components\Actions\CopyAction;
use App\Services\Helpers\SoftwareVersionService;
use Dedoc\Scramble\Scramble;
use Dedoc\Scramble\Support\Generator\OpenApi;
use Dedoc\Scramble\Support\Generator\SecurityScheme;
use Filament\Forms\Components\Field;
use Filament\Forms\Components\TextInput;
use Filament\Support\Colors\Color;
use Filament\Support\Facades\FilamentColor;
use Filament\Support\Facades\FilamentView;
@ -190,6 +193,16 @@ class AppServiceProvider extends ServiceProvider
$component->dispatch('alertBannerSent');
});
Field::macro('suffixCopy', function () {
/** @var TextInput $this */
return $this->suffixAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null); // @phpstan-ignore varTag.nativeType
});
Field::macro('hintCopy', function () {
/** @var Field $this */
return $this->hintAction(fn (string $state) => request()->isSecure() ? CopyAction::make()->copyable($state) : null); // @phpstan-ignore varTag.nativeType
});
// Don't run any health checks during tests
if (!$app->runningUnitTests()) {
Health::checks([

View File

@ -14,6 +14,9 @@ parameters:
ignoreErrors:
- identifier: argument.templateType
- identifier: missingType.generics
- '#Call to an undefined method Filament\\Forms\\Components\\TextInput::suffixCopy\(\)#'
- '#Call to an undefined method Filament\\Forms\\Components\\TextInput::hintCopy\(\)#'
- '#Call to an undefined method Filament\\Forms\\Components\\Textarea::hintCopy\(\)#'
# We are getting and setting environment variables directly
-