mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-29 15:34:44 +02:00
Fix EditProfile
This commit is contained in:
parent
cd88d23592
commit
779ee72ab5
@ -18,7 +18,6 @@ use chillerlan\QRCode\QRCode;
|
||||
use chillerlan\QRCode\QROptions;
|
||||
use DateTimeZone;
|
||||
use Exception;
|
||||
use Filament\Actions;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
@ -34,6 +33,8 @@ use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\ToggleButtons;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Schemas\Components\Actions;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Colors\Color;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Filament\Support\Exceptions\Halt;
|
||||
@ -64,170 +65,168 @@ class EditProfile extends \Filament\Auth\Pages\EditProfile
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getForms(): array
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
$oauthProviders = collect(OAuthProvider::get())->filter(fn (OAuthProvider $provider) => $provider->isEnabled())->all();
|
||||
|
||||
return [
|
||||
'form' => $this->form(
|
||||
$this->makeForm()
|
||||
return $schema
|
||||
->components([
|
||||
Tabs::make()->persistTabInQueryString()
|
||||
->schema([
|
||||
Tabs::make()->persistTabInQueryString()
|
||||
Tab::make(trans('profile.tabs.account'))
|
||||
->icon('tabler-user')
|
||||
->schema([
|
||||
Tab::make(trans('profile.tabs.account'))
|
||||
->icon('tabler-user')
|
||||
->schema([
|
||||
TextInput::make('username')
|
||||
->label(trans('profile.username'))
|
||||
->disabled()
|
||||
TextInput::make('username')
|
||||
->label(trans('profile.username'))
|
||||
->disabled()
|
||||
->readOnly()
|
||||
->dehydrated(false)
|
||||
->maxLength(255)
|
||||
->unique(ignoreRecord: true)
|
||||
->autofocus(),
|
||||
TextInput::make('email')
|
||||
->prefixIcon('tabler-mail')
|
||||
->label(trans('profile.email'))
|
||||
->email()
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->unique(ignoreRecord: true),
|
||||
TextInput::make('password')
|
||||
->label(trans('profile.password'))
|
||||
->password()
|
||||
->prefixIcon('tabler-password')
|
||||
->revealable(filament()->arePasswordsRevealable())
|
||||
->rule(Password::default())
|
||||
->autocomplete('new-password')
|
||||
->dehydrated(fn ($state): bool => filled($state))
|
||||
->dehydrateStateUsing(fn ($state): string => Hash::make($state))
|
||||
->live(debounce: 500)
|
||||
->same('passwordConfirmation'),
|
||||
TextInput::make('passwordConfirmation')
|
||||
->label(trans('profile.password_confirmation'))
|
||||
->password()
|
||||
->prefixIcon('tabler-password-fingerprint')
|
||||
->revealable(filament()->arePasswordsRevealable())
|
||||
->required()
|
||||
->visible(fn (Get $get): bool => filled($get('password')))
|
||||
->dehydrated(false),
|
||||
Select::make('timezone')
|
||||
->label(trans('profile.timezone'))
|
||||
->required()
|
||||
->prefixIcon('tabler-clock-pin')
|
||||
->default('UTC')
|
||||
->selectablePlaceholder(false)
|
||||
->options(fn () => collect(DateTimeZone::listIdentifiers())->mapWithKeys(fn ($tz) => [$tz => $tz]))
|
||||
->searchable()
|
||||
->native(false),
|
||||
Select::make('language')
|
||||
->label(trans('profile.language'))
|
||||
->required()
|
||||
->prefixIcon('tabler-flag')
|
||||
->live()
|
||||
->default('en')
|
||||
->selectablePlaceholder(false)
|
||||
->helperText(fn ($state, LanguageService $languageService) => new HtmlString($languageService->isLanguageTranslated($state) ? '' : trans('profile.language_help', ['state' => $state])))
|
||||
->options(fn (LanguageService $languageService) => $languageService->getAvailableLanguages())
|
||||
->native(false),
|
||||
FileUpload::make('avatar')
|
||||
->avatar()
|
||||
->acceptedFileTypes(['image/png'])
|
||||
->directory('avatars')
|
||||
->getUploadedFileNameForStorageUsing(fn () => $this->getUser()->id . '.png')
|
||||
/* TODO ->hintAction(function (FileUpload $fileUpload) {
|
||||
$path = $fileUpload->getDirectory() . '/' . $this->getUser()->id . '.png';
|
||||
|
||||
return Action::make('remove_avatar')
|
||||
->icon('tabler-photo-minus')
|
||||
->iconButton()
|
||||
->hidden(fn () => !$fileUpload->getDisk()->exists($path))
|
||||
->action(fn () => $fileUpload->getDisk()->delete($path))
|
||||
;
|
||||
}) */,
|
||||
]),
|
||||
|
||||
Tab::make(trans('profile.tabs.oauth'))
|
||||
->icon('tabler-brand-oauth')
|
||||
->visible(count($oauthProviders) > 0)
|
||||
->schema(function () use ($oauthProviders) {
|
||||
$actions = [];
|
||||
|
||||
foreach ($oauthProviders as $oauthProvider) {
|
||||
|
||||
$id = $oauthProvider->getId();
|
||||
$name = $oauthProvider->getName();
|
||||
|
||||
$unlink = array_key_exists($id, $this->getUser()->oauth ?? []);
|
||||
|
||||
$actions[] = Action::make("oauth_$id")
|
||||
->label(($unlink ? trans('profile.unlink') : trans('profile.link')) . $name)
|
||||
->icon($unlink ? 'tabler-unlink' : 'tabler-link')
|
||||
// TODO ->color(Color::hex($oauthProvider->getHexColor()))
|
||||
->action(function (UserUpdateService $updateService) use ($id, $name, $unlink) {
|
||||
if ($unlink) {
|
||||
$oauth = auth()->user()->oauth;
|
||||
unset($oauth[$id]);
|
||||
|
||||
$updateService->handle(auth()->user(), ['oauth' => $oauth]);
|
||||
|
||||
$this->fillForm();
|
||||
|
||||
Notification::make()
|
||||
->title(trans('profile.unlinked', ['name' => $name]))
|
||||
->success()
|
||||
->send();
|
||||
} else {
|
||||
redirect(Socialite::with($id)->redirect()->getTargetUrl());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return [Actions::make($actions)];
|
||||
}),
|
||||
|
||||
Tab::make(trans('profile.tabs.2fa'))
|
||||
->icon('tabler-shield-lock')
|
||||
->schema(function (TwoFactorSetupService $setupService) {
|
||||
if ($this->getUser()->use_totp) {
|
||||
return [
|
||||
TextEntry::make('2fa-already-enabled')
|
||||
->label(trans('profile.2fa_enabled')),
|
||||
Textarea::make('backup-tokens')
|
||||
->hidden(fn () => !cache()->get("users.{$this->getUser()->id}.2fa.tokens"))
|
||||
->rows(10)
|
||||
->readOnly()
|
||||
->dehydrated(false)
|
||||
->maxLength(255)
|
||||
->unique(ignoreRecord: true)
|
||||
->autofocus(),
|
||||
TextInput::make('email')
|
||||
->prefixIcon('tabler-mail')
|
||||
->label(trans('profile.email'))
|
||||
->email()
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->unique(ignoreRecord: true),
|
||||
TextInput::make('password')
|
||||
->label(trans('profile.password'))
|
||||
->password()
|
||||
->prefixIcon('tabler-password')
|
||||
->revealable(filament()->arePasswordsRevealable())
|
||||
->rule(Password::default())
|
||||
->autocomplete('new-password')
|
||||
->dehydrated(fn ($state): bool => filled($state))
|
||||
->dehydrateStateUsing(fn ($state): string => Hash::make($state))
|
||||
->live(debounce: 500)
|
||||
->same('passwordConfirmation'),
|
||||
TextInput::make('passwordConfirmation')
|
||||
->label(trans('profile.password_confirmation'))
|
||||
->password()
|
||||
->prefixIcon('tabler-password-fingerprint')
|
||||
->revealable(filament()->arePasswordsRevealable())
|
||||
->required()
|
||||
->visible(fn (Get $get): bool => filled($get('password')))
|
||||
->dehydrated(false),
|
||||
Select::make('timezone')
|
||||
->label(trans('profile.timezone'))
|
||||
->required()
|
||||
->prefixIcon('tabler-clock-pin')
|
||||
->default('UTC')
|
||||
->selectablePlaceholder(false)
|
||||
->options(fn () => collect(DateTimeZone::listIdentifiers())->mapWithKeys(fn ($tz) => [$tz => $tz]))
|
||||
->searchable()
|
||||
->native(false),
|
||||
Select::make('language')
|
||||
->label(trans('profile.language'))
|
||||
->required()
|
||||
->prefixIcon('tabler-flag')
|
||||
->live()
|
||||
->default('en')
|
||||
->selectablePlaceholder(false)
|
||||
->helperText(fn ($state, LanguageService $languageService) => new HtmlString($languageService->isLanguageTranslated($state) ? '' : trans('profile.language_help', ['state' => $state])))
|
||||
->options(fn (LanguageService $languageService) => $languageService->getAvailableLanguages())
|
||||
->native(false),
|
||||
FileUpload::make('avatar')
|
||||
->visible(fn () => config('panel.filament.uploadable-avatars'))
|
||||
->avatar()
|
||||
->acceptedFileTypes(['image/png'])
|
||||
->directory('avatars')
|
||||
->getUploadedFileNameForStorageUsing(fn () => $this->getUser()->id . '.png')
|
||||
->hintAction(function (FileUpload $fileUpload) {
|
||||
$path = $fileUpload->getDirectory() . '/' . $this->getUser()->id . '.png';
|
||||
->formatStateUsing(fn () => cache()->get("users.{$this->getUser()->id}.2fa.tokens"))
|
||||
->helperText(trans('profile.backup_help'))
|
||||
->label(trans('profile.backup_codes')),
|
||||
TextInput::make('2fa-disable-code')
|
||||
->label(trans('profile.disable_2fa'))
|
||||
->helperText(trans('profile.disable_2fa_help')),
|
||||
];
|
||||
}
|
||||
|
||||
return Action::make('remove_avatar')
|
||||
->icon('tabler-photo-minus')
|
||||
->iconButton()
|
||||
->hidden(fn () => !$fileUpload->getDisk()->exists($path))
|
||||
->action(fn () => $fileUpload->getDisk()->delete($path));
|
||||
}),
|
||||
]),
|
||||
['image_url_data' => $url, 'secret' => $secret] = cache()->remember(
|
||||
"users.{$this->getUser()->id}.2fa.state",
|
||||
now()->addMinutes(5), fn () => $setupService->handle($this->getUser())
|
||||
);
|
||||
|
||||
Tab::make(trans('profile.tabs.oauth'))
|
||||
->icon('tabler-brand-oauth')
|
||||
->visible(count($oauthProviders) > 0)
|
||||
->schema(function () use ($oauthProviders) {
|
||||
$actions = [];
|
||||
|
||||
foreach ($oauthProviders as $oauthProvider) {
|
||||
|
||||
$id = $oauthProvider->getId();
|
||||
$name = $oauthProvider->getName();
|
||||
|
||||
$unlink = array_key_exists($id, $this->getUser()->oauth ?? []);
|
||||
|
||||
$actions[] = Action::make("oauth_$id")
|
||||
->label(($unlink ? trans('profile.unlink') : trans('profile.link')) . $name)
|
||||
->icon($unlink ? 'tabler-unlink' : 'tabler-link')
|
||||
->color(Color::hex($oauthProvider->getHexColor()))
|
||||
->action(function (UserUpdateService $updateService) use ($id, $name, $unlink) {
|
||||
if ($unlink) {
|
||||
$oauth = auth()->user()->oauth;
|
||||
unset($oauth[$id]);
|
||||
|
||||
$updateService->handle(auth()->user(), ['oauth' => $oauth]);
|
||||
|
||||
$this->fillForm();
|
||||
|
||||
Notification::make()
|
||||
->title(trans('profile.unlinked', ['name' => $name]))
|
||||
->success()
|
||||
->send();
|
||||
} else {
|
||||
redirect(Socialite::with($id)->redirect()->getTargetUrl());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return [Actions::make($actions)];
|
||||
}),
|
||||
|
||||
Tab::make(trans('profile.tabs.2fa'))
|
||||
->icon('tabler-shield-lock')
|
||||
->schema(function (TwoFactorSetupService $setupService) {
|
||||
if ($this->getUser()->use_totp) {
|
||||
return [
|
||||
TextEntry::make('2fa-already-enabled')
|
||||
->label(trans('profile.2fa_enabled')),
|
||||
Textarea::make('backup-tokens')
|
||||
->hidden(fn () => !cache()->get("users.{$this->getUser()->id}.2fa.tokens"))
|
||||
->rows(10)
|
||||
->readOnly()
|
||||
->dehydrated(false)
|
||||
->formatStateUsing(fn () => cache()->get("users.{$this->getUser()->id}.2fa.tokens"))
|
||||
->helperText(trans('profile.backup_help'))
|
||||
->label(trans('profile.backup_codes')),
|
||||
TextInput::make('2fa-disable-code')
|
||||
->label(trans('profile.disable_2fa'))
|
||||
->helperText(trans('profile.disable_2fa_help')),
|
||||
];
|
||||
}
|
||||
|
||||
['image_url_data' => $url, 'secret' => $secret] = cache()->remember(
|
||||
"users.{$this->getUser()->id}.2fa.state",
|
||||
now()->addMinutes(5), fn () => $setupService->handle($this->getUser())
|
||||
);
|
||||
|
||||
$options = new QROptions([
|
||||
'svgLogo' => public_path('pelican.svg'),
|
||||
'svgLogoScale' => 0.05,
|
||||
'addLogoSpace' => true,
|
||||
'logoSpaceWidth' => 13,
|
||||
'logoSpaceHeight' => 13,
|
||||
'version' => Version::AUTO,
|
||||
// 'outputInterface' => QRSvgWithLogo::class,
|
||||
'outputBase64' => false,
|
||||
'eccLevel' => EccLevel::H, // ECC level H is necessary when using logos
|
||||
'addQuietzone' => true,
|
||||
// 'drawLightModules' => true,
|
||||
'connectPaths' => true,
|
||||
'drawCircularModules' => true,
|
||||
// 'circleRadius' => 0.45,
|
||||
'svgDefs' => '
|
||||
$options = new QROptions([
|
||||
'svgLogo' => public_path('pelican.svg'),
|
||||
'svgLogoScale' => 0.05,
|
||||
'addLogoSpace' => true,
|
||||
'logoSpaceWidth' => 13,
|
||||
'logoSpaceHeight' => 13,
|
||||
'version' => Version::AUTO,
|
||||
// 'outputInterface' => QRSvgWithLogo::class,
|
||||
'outputBase64' => false,
|
||||
'eccLevel' => EccLevel::H, // ECC level H is necessary when using logos
|
||||
'addQuietzone' => true,
|
||||
// 'drawLightModules' => true,
|
||||
'connectPaths' => true,
|
||||
'drawCircularModules' => true,
|
||||
// 'circleRadius' => 0.45,
|
||||
'svgDefs' => '
|
||||
<linearGradient id="gradient" x1="100%" y2="100%">
|
||||
<stop stop-color="#7dd4fc" offset="0"/>
|
||||
<stop stop-color="#38bdf8" offset="0.5"/>
|
||||
@ -238,165 +237,163 @@ class EditProfile extends \Filament\Auth\Pages\EditProfile
|
||||
.light{fill: #000;}
|
||||
]]></style>
|
||||
',
|
||||
]);
|
||||
]);
|
||||
|
||||
// https://github.com/chillerlan/php-qrcode/blob/main/examples/svgWithLogo.php
|
||||
// https://github.com/chillerlan/php-qrcode/blob/main/examples/svgWithLogo.php
|
||||
|
||||
$image = (new QRCode($options))->render($url);
|
||||
$image = (new QRCode($options))->render($url);
|
||||
|
||||
return [
|
||||
TextEntry::make('qr')
|
||||
->label(trans('profile.scan_qr'))
|
||||
->content(fn () => new HtmlString("
|
||||
return [
|
||||
TextEntry::make('qr')
|
||||
->label(trans('profile.scan_qr'))
|
||||
->state(fn () => new HtmlString("
|
||||
<div style='width: 300px; background-color: rgb(24, 24, 27);'>$image</div>
|
||||
"))
|
||||
->helperText(trans('profile.setup_key') .': '. $secret),
|
||||
TextInput::make('2facode')
|
||||
->label(trans('profile.code'))
|
||||
->requiredWith('2fapassword')
|
||||
->helperText(trans('profile.code_help')),
|
||||
TextInput::make('2fapassword')
|
||||
->label(trans('profile.current_password'))
|
||||
->requiredWith('2facode')
|
||||
->currentPassword()
|
||||
->password(),
|
||||
];
|
||||
}),
|
||||
->helperText(trans('profile.setup_key') .': '. $secret),
|
||||
TextInput::make('2facode')
|
||||
->label(trans('profile.code'))
|
||||
->requiredWith('2fapassword')
|
||||
->helperText(trans('profile.code_help')),
|
||||
TextInput::make('2fapassword')
|
||||
->label(trans('profile.current_password'))
|
||||
->requiredWith('2facode')
|
||||
->currentPassword()
|
||||
->password(),
|
||||
];
|
||||
}),
|
||||
|
||||
Tab::make(trans('profile.tabs.api_keys'))
|
||||
->icon('tabler-key')
|
||||
->schema([
|
||||
Grid::make('name')->columns(5)->schema([
|
||||
Section::make(trans('profile.create_key'))->columnSpan(3)->schema([
|
||||
TextInput::make('description')
|
||||
->label(trans('profile.description'))
|
||||
->live(),
|
||||
TagsInput::make('allowed_ips')
|
||||
->label(trans('profile.allowed_ips'))
|
||||
->live()
|
||||
->splitKeys([',', ' ', 'Tab'])
|
||||
->placeholder('127.0.0.1 or 192.168.1.1')
|
||||
->helperText(trans('profile.allowed_ips_help'))
|
||||
->columnSpanFull(),
|
||||
])->headerActions([
|
||||
Action::make('Create')
|
||||
->label(trans('filament-actions::create.single.modal.actions.create.label'))
|
||||
->disabled(fn (Get $get) => $get('description') === null)
|
||||
->successRedirectUrl(self::getUrl(['tab' => '-api-keys-tab'], panel: 'app'))
|
||||
->action(function (Get $get, Action $action, User $user) {
|
||||
$token = $user->createToken(
|
||||
$get('description'),
|
||||
$get('allowed_ips'),
|
||||
);
|
||||
Tab::make(trans('profile.tabs.api_keys'))
|
||||
->icon('tabler-key')
|
||||
->schema([
|
||||
Grid::make(5)->schema([
|
||||
Section::make(trans('profile.create_key'))->columnSpan(3)->schema([
|
||||
TextInput::make('description')
|
||||
->label(trans('profile.description'))
|
||||
->live(),
|
||||
TagsInput::make('allowed_ips')
|
||||
->label(trans('profile.allowed_ips'))
|
||||
->live()
|
||||
->splitKeys([',', ' ', 'Tab'])
|
||||
->placeholder('127.0.0.1 or 192.168.1.1')
|
||||
->helperText(trans('profile.allowed_ips_help'))
|
||||
->columnSpanFull(),
|
||||
])->headerActions([
|
||||
Action::make('Create')
|
||||
->label(trans('filament-actions::create.single.modal.actions.create.label'))
|
||||
->disabled(fn (Get $get) => $get('description') === null)
|
||||
->successRedirectUrl(self::getUrl(['tab' => '-api-keys-tab'], panel: 'app'))
|
||||
->action(function (Get $get, Action $action, User $user) {
|
||||
$token = $user->createToken(
|
||||
$get('description'),
|
||||
$get('allowed_ips'),
|
||||
);
|
||||
|
||||
Activity::event('user:api-key.create')
|
||||
->subject($token->accessToken)
|
||||
->property('identifier', $token->accessToken->identifier)
|
||||
->log();
|
||||
Activity::event('user:api-key.create')
|
||||
->subject($token->accessToken)
|
||||
->property('identifier', $token->accessToken->identifier)
|
||||
->log();
|
||||
|
||||
Notification::make()
|
||||
->title(trans('profile.key_created'))
|
||||
->body($token->accessToken->identifier . $token->plainTextToken)
|
||||
->persistent()
|
||||
->success()
|
||||
->send();
|
||||
Notification::make()
|
||||
->title(trans('profile.key_created'))
|
||||
->body($token->accessToken->identifier . $token->plainTextToken)
|
||||
->persistent()
|
||||
->success()
|
||||
->send();
|
||||
|
||||
$action->success();
|
||||
}),
|
||||
]),
|
||||
Section::make(trans('profile.keys'))->label(trans('profile.keys'))->columnSpan(2)->schema([
|
||||
Repeater::make('keys')
|
||||
->label('')
|
||||
->relationship('apiKeys')
|
||||
->addable(false)
|
||||
->itemLabel(fn ($state) => $state['identifier'])
|
||||
->deleteAction(function (Action $action) {
|
||||
$action->requiresConfirmation()->action(function (array $arguments, Repeater $component) {
|
||||
$items = $component->getState();
|
||||
$key = $items[$arguments['item']];
|
||||
ApiKey::find($key['id'] ?? null)?->delete();
|
||||
|
||||
unset($items[$arguments['item']]);
|
||||
|
||||
$component->state($items);
|
||||
|
||||
$component->callAfterStateUpdated();
|
||||
});
|
||||
})
|
||||
->schema(fn () => [
|
||||
TextEntry::make('adf')->label(fn (ApiKey $key) => $key->memo),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
$action->success();
|
||||
}),
|
||||
]),
|
||||
|
||||
Tab::make(trans('profile.tabs.ssh_keys'))
|
||||
->icon('tabler-lock-code')
|
||||
->hidden(),
|
||||
|
||||
Tab::make(trans('profile.tabs.activity'))
|
||||
->icon('tabler-history')
|
||||
->schema([
|
||||
Repeater::make('activity')
|
||||
Section::make(trans('profile.keys'))->label(trans('profile.keys'))->columnSpan(2)->schema([
|
||||
Repeater::make('keys')
|
||||
->label('')
|
||||
->deletable(false)
|
||||
->relationship('apiKeys')
|
||||
->addable(false)
|
||||
->relationship(null, function (Builder $query) {
|
||||
$query->orderBy('timestamp', 'desc');
|
||||
->itemLabel(fn ($state) => $state['identifier'])
|
||||
->deleteAction(function (Action $action) {
|
||||
$action->requiresConfirmation()->action(function (array $arguments, Repeater $component) {
|
||||
$items = $component->getState();
|
||||
$key = $items[$arguments['item']];
|
||||
ApiKey::find($key['id'] ?? null)?->delete();
|
||||
|
||||
unset($items[$arguments['item']]);
|
||||
|
||||
$component->state($items);
|
||||
|
||||
$component->callAfterStateUpdated();
|
||||
});
|
||||
})
|
||||
->schema([
|
||||
TextEntry::make('activity!')->label('')->content(fn (ActivityLog $log) => new HtmlString($log->htmlable())),
|
||||
TextEntry::make('adf')->label(fn (ApiKey $key) => $key->memo),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
|
||||
Tab::make(trans('profile.tabs.customization'))
|
||||
->icon('tabler-adjustments')
|
||||
Tab::make(trans('profile.tabs.ssh_keys'))
|
||||
->icon('tabler-lock-code')
|
||||
->hidden(),
|
||||
|
||||
Tab::make(trans('profile.tabs.activity'))
|
||||
->icon('tabler-history')
|
||||
->schema([
|
||||
Repeater::make('activity')
|
||||
->label('')
|
||||
->deletable(false)
|
||||
->addable(false)
|
||||
->relationship(null, function (Builder $query) {
|
||||
$query->orderBy('timestamp', 'desc');
|
||||
})
|
||||
->schema([
|
||||
Section::make(trans('profile.dashboard'))
|
||||
->collapsible()
|
||||
->icon('tabler-dashboard')
|
||||
->schema([
|
||||
ToggleButtons::make('dashboard_layout')
|
||||
->label(trans('profile.dashboard_layout'))
|
||||
->inline()
|
||||
->required()
|
||||
->options([
|
||||
'grid' => trans('profile.grid'),
|
||||
'table' => trans('profile.table'),
|
||||
]),
|
||||
]),
|
||||
Section::make(trans('profile.console'))
|
||||
->collapsible()
|
||||
->icon('tabler-brand-tabler')
|
||||
->schema([
|
||||
TextInput::make('console_rows')
|
||||
->label(trans('profile.rows'))
|
||||
->minValue(1)
|
||||
->numeric()
|
||||
->required()
|
||||
->columnSpan(1)
|
||||
->default(30),
|
||||
// Select::make('console_font')
|
||||
// ->label(trans('profile.font'))
|
||||
// ->hidden() //TODO
|
||||
// ->columnSpan(1),
|
||||
TextInput::make('console_font_size')
|
||||
->label(trans('profile.font_size'))
|
||||
->columnSpan(1)
|
||||
->minValue(1)
|
||||
->numeric()
|
||||
->required()
|
||||
->default(14),
|
||||
]),
|
||||
TextEntry::make('activity!')->label('')->state(fn (ActivityLog $log) => new HtmlString($log->htmlable())),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
->operation('edit')
|
||||
->model($this->getUser())
|
||||
->statePath('data')
|
||||
->inlineLabel(!static::isSimple()),
|
||||
),
|
||||
];
|
||||
|
||||
Tab::make(trans('profile.tabs.customization'))
|
||||
->icon('tabler-adjustments')
|
||||
->schema([
|
||||
Section::make(trans('profile.dashboard'))
|
||||
->collapsible()
|
||||
->icon('tabler-dashboard')
|
||||
->schema([
|
||||
ToggleButtons::make('dashboard_layout')
|
||||
->label(trans('profile.dashboard_layout'))
|
||||
->inline()
|
||||
->required()
|
||||
->options([
|
||||
'grid' => trans('profile.grid'),
|
||||
'table' => trans('profile.table'),
|
||||
]),
|
||||
]),
|
||||
Section::make(trans('profile.console'))
|
||||
->collapsible()
|
||||
->icon('tabler-brand-tabler')
|
||||
->schema([
|
||||
TextInput::make('console_rows')
|
||||
->label(trans('profile.rows'))
|
||||
->minValue(1)
|
||||
->numeric()
|
||||
->required()
|
||||
->columnSpan(1)
|
||||
->default(30),
|
||||
// Select::make('console_font')
|
||||
// ->label(trans('profile.font'))
|
||||
// ->hidden() //TODO
|
||||
// ->columnSpan(1),
|
||||
TextInput::make('console_font_size')
|
||||
->label(trans('profile.font_size'))
|
||||
->columnSpan(1)
|
||||
->minValue(1)
|
||||
->numeric()
|
||||
->required()
|
||||
->default(14),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
->operation('edit')
|
||||
->model($this->getUser())
|
||||
->statePath('data')
|
||||
->inlineLabel(!static::isSimple());
|
||||
}
|
||||
|
||||
protected function handleRecordUpdate(Model $record, array $data): Model
|
||||
|
Loading…
x
Reference in New Issue
Block a user