mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-05 07:52:34 +00:00
Add phpstan level 7(#544)
This commit is contained in:
@ -24,11 +24,17 @@ class Index extends Page
|
||||
|
||||
public string $token = '';
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()?->can('viewAny', PersonalAccessToken::class) ?? false;
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $user->can('viewAny', PersonalAccessToken::class);
|
||||
}
|
||||
|
||||
public function getWidgets(): array
|
||||
@ -47,6 +53,9 @@ public function unmountAction(bool $shouldCancelParentActions = true, bool $shou
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return [
|
||||
Action::make('read-the-docs')
|
||||
->label('Read the Docs')
|
||||
@ -59,8 +68,8 @@ protected function getHeaderActions(): array
|
||||
->icon('heroicon-o-plus')
|
||||
->modalHeading('Create a new Key')
|
||||
->modalSubmitActionLabel('Create')
|
||||
->form(function () {
|
||||
if ($this->token) {
|
||||
->form(function (): array {
|
||||
if ($this->token !== '' && $this->token !== '0') {
|
||||
return [];
|
||||
}
|
||||
|
||||
@ -76,8 +85,8 @@ protected function getHeaderActions(): array
|
||||
->required(),
|
||||
];
|
||||
})
|
||||
->infolist(function () {
|
||||
if ($this->token) {
|
||||
->infolist(function (): array {
|
||||
if ($this->token !== '' && $this->token !== '0') {
|
||||
return [
|
||||
TextEntry::make('token')
|
||||
->state($this->token)
|
||||
@ -91,12 +100,12 @@ protected function getHeaderActions(): array
|
||||
})
|
||||
->authorize('create', PersonalAccessToken::class)
|
||||
->modalWidth(MaxWidth::Large)
|
||||
->action(function (array $data) {
|
||||
->action(function (array $data) use ($user): void {
|
||||
$permissions = ['read'];
|
||||
if ($data['permission'] === 'write') {
|
||||
$permissions[] = 'write';
|
||||
}
|
||||
$token = auth()->user()->createToken($data['name'], $permissions);
|
||||
$token = $user->createToken($data['name'], $permissions);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
|
||||
@ -105,11 +114,11 @@ protected function getHeaderActions(): array
|
||||
$this->halt();
|
||||
})
|
||||
->modalSubmitAction(function () {
|
||||
if ($this->token) {
|
||||
if ($this->token !== '' && $this->token !== '0') {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
->closeModalByClickingAway(fn () => ! $this->token),
|
||||
->closeModalByClickingAway(fn (): bool => $this->token === '' || $this->token === '0'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,23 @@
|
||||
|
||||
class ApiKeysList extends Widget
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<PersonalAccessToken>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return auth()->user()->tokens()->getQuery();
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var Builder<PersonalAccessToken> $query */
|
||||
$query = $user->tokens()->getQuery();
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected function getTableColumns(): array
|
||||
@ -35,7 +47,7 @@ protected function getTableColumns(): array
|
||||
->sortable(),
|
||||
TextColumn::make('last_used_at')
|
||||
->label('Last Used At')
|
||||
->formatStateUsing(fn (PersonalAccessToken $record) => $record->getDateTimeByTimezone($record->last_used_at))
|
||||
->formatStateUsing(fn (PersonalAccessToken $record): string => $record->getDateTimeByTimezone($record->last_used_at))
|
||||
->searchable()
|
||||
->sortable(),
|
||||
];
|
||||
@ -43,6 +55,9 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->heading(null)
|
||||
->query($this->getTableQuery())
|
||||
@ -50,15 +65,15 @@ public function table(Table $table): Table
|
||||
->actions([
|
||||
DeleteAction::make('delete')
|
||||
->modalHeading('Delete Token')
|
||||
->authorize(fn (PersonalAccessToken $record) => auth()->user()->can('delete', $record))
|
||||
->using(function (array $data, PersonalAccessToken $record) {
|
||||
->authorize(fn (PersonalAccessToken $record) => $user->can('delete', $record))
|
||||
->using(function (array $data, PersonalAccessToken $record): void {
|
||||
$record->delete();
|
||||
}),
|
||||
])
|
||||
->bulkActions([
|
||||
DeleteBulkAction::make()
|
||||
->requiresConfirmation()
|
||||
->authorize(auth()->user()->can('deleteMany', PersonalAccessToken::class)),
|
||||
->authorize($user->can('deleteMany', PersonalAccessToken::class)),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,15 @@
|
||||
|
||||
class Create
|
||||
{
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function form(): array
|
||||
{
|
||||
return [
|
||||
Select::make('provider')
|
||||
->options(
|
||||
collect(config('core.notification_channels_providers'))
|
||||
collect((array) config('core.notification_channels_providers'))
|
||||
->mapWithKeys(fn ($provider) => [$provider => $provider])
|
||||
)
|
||||
->live()
|
||||
@ -47,12 +50,16 @@ public static function form(): array
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function action(array $data): void
|
||||
{
|
||||
try {
|
||||
app(AddChannel::class)->add(auth()->user(), $data);
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
app(AddChannel::class)->add($user, $data);
|
||||
} catch (Exception $e) {
|
||||
Notification::make()
|
||||
->title($e->getMessage())
|
||||
|
@ -10,6 +10,9 @@
|
||||
|
||||
class Edit
|
||||
{
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function form(): array
|
||||
{
|
||||
return [
|
||||
@ -20,8 +23,13 @@ public static function form(): array
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public static function action(NotificationChannel $channel, array $data): void
|
||||
{
|
||||
app(EditChannel::class)->edit($channel, auth()->user(), $data);
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
app(EditChannel::class)->edit($channel, $user, $data);
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ protected function getHeaderActions(): array
|
||||
->form(Actions\Create::form())
|
||||
->authorize('create', NotificationChannel::class)
|
||||
->modalWidth(MaxWidth::Large)
|
||||
->action(function (array $data) {
|
||||
->action(function (array $data): void {
|
||||
try {
|
||||
Actions\Create::action($data);
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Web\Pages\Settings\NotificationChannels\Widgets;
|
||||
|
||||
use App\Models\NotificationChannel;
|
||||
use App\Models\User;
|
||||
use App\Web\Pages\Settings\NotificationChannels\Actions\Edit;
|
||||
use Filament\Support\Enums\MaxWidth;
|
||||
use Filament\Tables\Actions\DeleteAction;
|
||||
@ -15,18 +16,27 @@
|
||||
|
||||
class NotificationChannelsList extends Widget
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<NotificationChannel>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return NotificationChannel::getByProjectId(auth()->user()->current_project_id);
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return NotificationChannel::getByProjectId($user->current_project_id);
|
||||
}
|
||||
|
||||
protected function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
IconColumn::make('provider')
|
||||
->icon(fn (NotificationChannel $record) => 'icon-'.$record->provider)
|
||||
->icon(fn (NotificationChannel $record): string => 'icon-'.$record->provider)
|
||||
->width(24),
|
||||
TextColumn::make('label')
|
||||
->default(fn (NotificationChannel $record) => $record->label)
|
||||
@ -35,10 +45,8 @@ protected function getTableColumns(): array
|
||||
TextColumn::make('id')
|
||||
->label('Global')
|
||||
->badge()
|
||||
->color(fn (NotificationChannel $record) => $record->project_id ? 'gray' : 'success')
|
||||
->formatStateUsing(function (NotificationChannel $record) {
|
||||
return $record->project_id ? 'No' : 'Yes';
|
||||
}),
|
||||
->color(fn (NotificationChannel $record): string => $record->project_id ? 'gray' : 'success')
|
||||
->formatStateUsing(fn (NotificationChannel $record): string => $record->project_id ? 'No' : 'Yes'),
|
||||
TextColumn::make('created_at')
|
||||
->label('Created At')
|
||||
->formatStateUsing(fn (NotificationChannel $record) => $record->created_at_by_timezone)
|
||||
@ -49,6 +57,9 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->heading(null)
|
||||
->query($this->getTableQuery())
|
||||
@ -56,20 +67,18 @@ public function table(Table $table): Table
|
||||
->actions([
|
||||
EditAction::make('edit')
|
||||
->modalHeading('Edit Notification Channel')
|
||||
->mutateRecordDataUsing(function (array $data, NotificationChannel $record) {
|
||||
return [
|
||||
'label' => $record->label,
|
||||
'global' => ! $record->project_id,
|
||||
];
|
||||
})
|
||||
->mutateRecordDataUsing(fn (array $data, NotificationChannel $record): array => [
|
||||
'label' => $record->label,
|
||||
'global' => ! $record->project_id,
|
||||
])
|
||||
->form(Edit::form())
|
||||
->authorize(fn (NotificationChannel $record) => auth()->user()->can('update', $record))
|
||||
->authorize(fn (NotificationChannel $record) => $user->can('update', $record))
|
||||
->using(fn (array $data, NotificationChannel $record) => Edit::action($record, $data))
|
||||
->modalWidth(MaxWidth::Medium),
|
||||
DeleteAction::make('delete')
|
||||
->modalHeading('Delete Notification Channel')
|
||||
->authorize(fn (NotificationChannel $record) => auth()->user()->can('delete', $record))
|
||||
->using(function (array $data, NotificationChannel $record) {
|
||||
->authorize(fn (NotificationChannel $record) => $user->can('delete', $record))
|
||||
->using(function (array $data, NotificationChannel $record): void {
|
||||
$record->delete();
|
||||
}),
|
||||
]);
|
||||
|
@ -54,7 +54,7 @@ public function infolist(Infolist $infolist): Infolist
|
||||
->label('Password')
|
||||
->required(),
|
||||
])
|
||||
->action(function (array $data) {
|
||||
->action(function (array $data): void {
|
||||
self::logoutOtherBrowserSessions($data['password']);
|
||||
})
|
||||
->modalWidth('2xl'),
|
||||
@ -62,6 +62,9 @@ public function infolist(Infolist $infolist): Infolist
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
private function getDynamicSchema(): array
|
||||
{
|
||||
$sections = [];
|
||||
@ -71,8 +74,8 @@ private function getDynamicSchema(): array
|
||||
->schema([
|
||||
TextEntry::make('device')
|
||||
->hiddenLabel()
|
||||
->icon($session->device['desktop'] ? 'heroicon-o-computer-desktop' : 'heroicon-o-device-phone-mobile')
|
||||
->state($session->device['platform'].' - '.$session->device['browser']),
|
||||
->icon(isset($session->device['desktop']) ? 'heroicon-o-computer-desktop' : 'heroicon-o-device-phone-mobile')
|
||||
->state(($session->device['platform'] ?? 'Platform').' - '.($session->device['browser'] ?? 'Browser')),
|
||||
TextEntry::make('browser')
|
||||
->hiddenLabel()
|
||||
->icon('heroicon-o-map-pin')
|
||||
@ -92,15 +95,32 @@ private function getDynamicSchema(): array
|
||||
return $sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, object{
|
||||
* device: array{
|
||||
* browser: string,
|
||||
* desktop: bool,
|
||||
* mobile: bool,
|
||||
* tablet: bool,
|
||||
* platform: string
|
||||
* },
|
||||
* ip_address: string|null,
|
||||
* is_current_device: bool,
|
||||
* last_active: string
|
||||
* }>
|
||||
*/
|
||||
private function getSessions(): array
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = Auth::user();
|
||||
|
||||
if (config(key: 'session.driver') !== 'database') {
|
||||
return [];
|
||||
}
|
||||
|
||||
return collect(
|
||||
value: DB::connection(config(key: 'session.connection'))->table(table: config(key: 'session.table', default: 'sessions'))
|
||||
->where(column: 'user_id', operator: Auth::user()->getAuthIdentifier())
|
||||
->where(column: 'user_id', operator: $user->getAuthIdentifier())
|
||||
->latest(column: 'last_activity')
|
||||
->get()
|
||||
)->map(callback: function ($session): object {
|
||||
@ -121,17 +141,20 @@ private function getSessions(): array
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
private function createAgent(mixed $session)
|
||||
private function createAgent(mixed $session): Agent
|
||||
{
|
||||
return tap(
|
||||
value: new Agent,
|
||||
callback: fn ($agent) => $agent->setUserAgent(userAgent: $session->user_agent)
|
||||
callback: fn ($agent): string => $agent->setUserAgent(userAgent: $session->user_agent)
|
||||
);
|
||||
}
|
||||
|
||||
private function logoutOtherBrowserSessions($password): void
|
||||
private function logoutOtherBrowserSessions(string $password): void
|
||||
{
|
||||
if (! Hash::check($password, Auth::user()->password)) {
|
||||
/** @var \App\Models\User $user */
|
||||
$user = Auth::user();
|
||||
|
||||
if (! Hash::check($password, $user->password)) {
|
||||
Notification::make()
|
||||
->danger()
|
||||
->title('The password you entered was incorrect. Please try again.')
|
||||
@ -143,7 +166,7 @@ private function logoutOtherBrowserSessions($password): void
|
||||
Auth::guard()->logoutOtherDevices($password);
|
||||
|
||||
request()->session()->put([
|
||||
'password_hash_'.Auth::getDefaultDriver() => Auth::user()->getAuthPassword(),
|
||||
'password_hash_'.Auth::getDefaultDriver() => $user->getAuthPassword(),
|
||||
]);
|
||||
|
||||
$this->deleteOtherSessionRecords();
|
||||
@ -156,12 +179,15 @@ private function logoutOtherBrowserSessions($password): void
|
||||
|
||||
private function deleteOtherSessionRecords(): void
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = Auth::user();
|
||||
|
||||
if (config(key: 'session.driver') !== 'database') {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::connection(config(key: 'session.connection'))->table(table: config(key: 'session.table', default: 'sessions'))
|
||||
->where('user_id', Auth::user()->getAuthIdentifier())
|
||||
->where('user_id', $user->getAuthIdentifier())
|
||||
->where('id', '!=', request()->session()->getId())
|
||||
->delete();
|
||||
}
|
||||
|
@ -29,14 +29,19 @@ class ProfileInformation extends Widget implements HasForms
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->name = auth()->user()->name;
|
||||
$this->email = auth()->user()->email;
|
||||
$this->timezone = auth()->user()->timezone;
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
$this->name = $user->name;
|
||||
$this->email = $user->email;
|
||||
$this->timezone = $user->timezone;
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
$rules = UpdateUserProfileInformation::rules(auth()->user());
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$rules = UpdateUserProfileInformation::rules($user);
|
||||
|
||||
return $form
|
||||
->schema([
|
||||
@ -69,9 +74,12 @@ public function form(Form $form): Form
|
||||
|
||||
public function submit(): void
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$this->validate();
|
||||
|
||||
app(UpdateUserProfileInformation::class)->update(auth()->user(), $this->all());
|
||||
app(UpdateUserProfileInformation::class)->update($user, $this->all());
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
|
@ -22,6 +22,9 @@ class TwoFactor extends Widget implements HasForms, HasInfolists
|
||||
use InteractsWithForms;
|
||||
use InteractsWithInfolists;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
protected static bool $isLazy = false;
|
||||
@ -34,13 +37,19 @@ class TwoFactor extends Widget implements HasForms, HasInfolists
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
if (auth()->user()->two_factor_secret) {
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
if ($user->two_factor_secret) {
|
||||
$this->enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function infolist(Infolist $infolist): Infolist
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $infolist->schema([
|
||||
Section::make()
|
||||
->heading('Two Factor Authentication')
|
||||
@ -53,12 +62,12 @@ public function infolist(Infolist $infolist): Infolist
|
||||
ViewEntry::make('qr_code')
|
||||
->hiddenLabel()
|
||||
->view('components.container', [
|
||||
'content' => $this->enabled ? auth()->user()->twoFactorQrCodeSvg() : null,
|
||||
'content' => $this->enabled ? $user->twoFactorQrCodeSvg() : null,
|
||||
])
|
||||
->visible($this->enabled && $this->showCodes),
|
||||
TextEntry::make('qr_code_manual')
|
||||
->label('If you are unable to scan the QR code, please use the 2FA secret instead.')
|
||||
->state($this->enabled ? decrypt(auth()->user()->two_factor_secret) : null)
|
||||
->state($this->enabled ? decrypt($user->two_factor_secret) : null)
|
||||
->copyable()
|
||||
->visible($this->enabled && $this->showCodes),
|
||||
TextEntry::make('recovery_codes_text')
|
||||
@ -70,7 +79,7 @@ public function infolist(Infolist $infolist): Infolist
|
||||
->hiddenLabel()
|
||||
->extraAttributes(['class' => 'rounded-lg border border-gray-100 p-2 dark:border-gray-700'])
|
||||
->view('components.container', [
|
||||
'content' => $this->enabled ? implode('</br>', json_decode(decrypt(auth()->user()->two_factor_recovery_codes), true)) : null,
|
||||
'content' => $this->enabled ? implode('</br>', json_decode((string) decrypt($user->two_factor_recovery_codes), true)) : null,
|
||||
])
|
||||
->visible($this->enabled),
|
||||
])
|
||||
@ -78,7 +87,7 @@ public function infolist(Infolist $infolist): Infolist
|
||||
Action::make('two-factor')
|
||||
->color($this->enabled ? 'danger' : 'primary')
|
||||
->label($this->enabled ? 'Disable' : 'Enable')
|
||||
->action(function () {
|
||||
->action(function (): void {
|
||||
if ($this->enabled) {
|
||||
$this->disableTwoFactor();
|
||||
} else {
|
||||
@ -96,7 +105,10 @@ public function infolist(Infolist $infolist): Infolist
|
||||
|
||||
public function enableTwoFactor(): void
|
||||
{
|
||||
app(EnableTwoFactorAuthentication::class)(auth()->user());
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
app(EnableTwoFactorAuthentication::class)($user);
|
||||
|
||||
$this->enabled = true;
|
||||
$this->showCodes = true;
|
||||
@ -111,7 +123,10 @@ public function enableTwoFactor(): void
|
||||
|
||||
public function disableTwoFactor(): void
|
||||
{
|
||||
app(DisableTwoFactorAuthentication::class)(auth()->user());
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
app(DisableTwoFactorAuthentication::class)($user);
|
||||
|
||||
$this->enabled = false;
|
||||
$this->showCodes = false;
|
||||
@ -126,7 +141,10 @@ public function disableTwoFactor(): void
|
||||
|
||||
public function regenerateRecoveryCodes(): void
|
||||
{
|
||||
app(GenerateNewRecoveryCodes::class)(auth()->user());
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
app(GenerateNewRecoveryCodes::class)($user);
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
|
@ -29,7 +29,10 @@ public static function getNavigationItemActiveRoutePattern(): string
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()?->can('viewAny', Project::class) ?? false;
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $user->can('viewAny', Project::class);
|
||||
}
|
||||
|
||||
public function getWidgets(): array
|
||||
@ -47,15 +50,13 @@ protected function getHeaderActions(): array
|
||||
->icon('heroicon-o-plus')
|
||||
->authorize('create', Project::class)
|
||||
->modalWidth(MaxWidth::Large)
|
||||
->form(function (Form $form) {
|
||||
return $form->schema([
|
||||
TextInput::make('name')
|
||||
->name('name')
|
||||
->rules(CreateProject::rules()['name']),
|
||||
])->columns(1);
|
||||
})
|
||||
->action(function (array $data) {
|
||||
app(CreateProject::class)->create(auth()->user(), $data);
|
||||
->form(fn (Form $form): \Filament\Forms\Form => $form->schema([
|
||||
TextInput::make('name')
|
||||
->name('name')
|
||||
->rules(CreateProject::rules()['name']),
|
||||
])->columns(1))
|
||||
->action(function (array $data): void {
|
||||
app(CreateProject::class)->create($this->getUser(), $data);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
}),
|
||||
|
@ -62,9 +62,9 @@ protected function getHeaderActions(): array
|
||||
->modalHeading('Delete Project')
|
||||
->modalDescription('Are you sure you want to delete this project? This action will delete all associated data and cannot be undone.')
|
||||
->requiresConfirmation()
|
||||
->action(function (Project $record) {
|
||||
->action(function (Project $record): void {
|
||||
try {
|
||||
app(DeleteProject::class)->delete(auth()->user(), $record);
|
||||
app(DeleteProject::class)->delete($this->getUser(), $record);
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
|
@ -21,7 +21,7 @@ class AddUser extends Widget implements HasForms
|
||||
|
||||
public Project $project;
|
||||
|
||||
public ?int $user;
|
||||
public ?int $user = null;
|
||||
|
||||
public function mount(Project $project): void
|
||||
{
|
||||
@ -38,7 +38,7 @@ public function form(Form $form): Form
|
||||
Select::make('user')
|
||||
->name('user')
|
||||
->options(fn () => User::query()
|
||||
->whereNotExists(function ($query) {
|
||||
->whereNotExists(function ($query): void {
|
||||
$query->select('user_id')
|
||||
->from('user_project')
|
||||
->whereColumn('users.id', 'user_project.user_id')
|
||||
|
@ -11,6 +11,9 @@
|
||||
|
||||
class ProjectUsersList extends Widget
|
||||
{
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $listeners = ['userAdded' => '$refresh'];
|
||||
|
||||
public Project $project;
|
||||
@ -20,9 +23,12 @@ public function mount(Project $project): void
|
||||
$this->project = $project;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Builder<User>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return User::query()->whereHas('projects', function (Builder $query) {
|
||||
return User::query()->whereHas('projects', function (Builder $query): void {
|
||||
$query->where('project_id', $this->project->id);
|
||||
});
|
||||
}
|
||||
@ -46,10 +52,8 @@ public function table(Table $table): Table
|
||||
Tables\Actions\DeleteAction::make()
|
||||
->label('Remove')
|
||||
->modalHeading('Remove user from project')
|
||||
->visible(function ($record) {
|
||||
return $this->authorize('update', $this->project)->allowed() && $record->id !== auth()->id();
|
||||
})
|
||||
->using(function ($record) {
|
||||
->visible(fn ($record): bool => $this->authorize('update', $this->project)->allowed() && $record->id !== auth()->id())
|
||||
->using(function ($record): void {
|
||||
$this->project->users()->detach($record);
|
||||
}),
|
||||
])
|
||||
|
@ -12,8 +12,14 @@
|
||||
|
||||
class ProjectsList extends Widget
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<Project>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return Project::query();
|
||||
@ -35,17 +41,20 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->heading(null)
|
||||
->query($this->getTableQuery())
|
||||
->columns($this->getTableColumns())
|
||||
->recordUrl(fn (Project $record) => Settings::getUrl(['project' => $record]))
|
||||
->recordUrl(fn (Project $record): string => Settings::getUrl(['project' => $record]))
|
||||
->actions([
|
||||
Action::make('settings')
|
||||
->label('Settings')
|
||||
->icon('heroicon-o-cog-6-tooth')
|
||||
->authorize(fn ($record) => auth()->user()->can('update', $record))
|
||||
->url(fn (Project $record) => Settings::getUrl(['project' => $record])),
|
||||
->authorize(fn ($record) => $user->can('update', $record))
|
||||
->url(fn (Project $record): string => Settings::getUrl(['project' => $record])),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -10,22 +10,31 @@ class SelectProject extends Widget
|
||||
{
|
||||
protected static string $view = 'widgets.select-project';
|
||||
|
||||
public ?Project $currentProject;
|
||||
public ?Project $currentProject = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Project>
|
||||
*/
|
||||
public Collection $projects;
|
||||
|
||||
public int|string|null $project;
|
||||
public int|string|null $project = null;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->currentProject = auth()->user()->currentProject;
|
||||
$this->projects = auth()->user()->allProjects()->get();
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$this->currentProject = $user->currentProject;
|
||||
$this->projects = $user->allProjects()->get();
|
||||
}
|
||||
|
||||
public function updateProject(Project $project): void
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$this->authorize('view', $project);
|
||||
auth()->user()->update(['current_project_id' => $project->id]);
|
||||
$user->update(['current_project_id' => $project->id]);
|
||||
|
||||
$this->redirect('/');
|
||||
}
|
||||
|
@ -24,7 +24,10 @@ class Index extends Page
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()?->can('viewAny', SshKey::class) ?? false;
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $user->can('viewAny', SshKey::class);
|
||||
}
|
||||
|
||||
public function getWidgets(): array
|
||||
@ -36,6 +39,9 @@ public function getWidgets(): array
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return [
|
||||
CreateAction::make('add')
|
||||
->label('Add Key')
|
||||
@ -53,8 +59,8 @@ protected function getHeaderActions(): array
|
||||
])
|
||||
->authorize('create', SshKey::class)
|
||||
->modalWidth(MaxWidth::Large)
|
||||
->using(function (array $data) {
|
||||
app(CreateSshKey::class)->create(auth()->user(), $data);
|
||||
->using(function (array $data) use ($user): void {
|
||||
app(CreateSshKey::class)->create($user, $data);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
}),
|
||||
|
@ -11,8 +11,14 @@
|
||||
|
||||
class SshKeysList extends TableWidget
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<SshKey>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return SshKey::query()->where('user_id', auth()->id());
|
||||
@ -35,6 +41,9 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->heading(null)
|
||||
->query($this->getTableQuery())
|
||||
@ -42,9 +51,9 @@ public function table(Table $table): Table
|
||||
->actions([
|
||||
DeleteAction::make('delete')
|
||||
->requiresConfirmation()
|
||||
->authorize(fn (SshKey $record) => auth()->user()->can('delete', $record))
|
||||
->action(function (SshKey $record) {
|
||||
run_action($this, function () use ($record) {
|
||||
->authorize(fn (SshKey $record) => $user->can('delete', $record))
|
||||
->action(function (SshKey $record): void {
|
||||
run_action($this, function () use ($record): void {
|
||||
$record->delete();
|
||||
$this->dispatch('$refresh');
|
||||
});
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Actions\ServerProvider\CreateServerProvider;
|
||||
use App\Enums\ServerProvider;
|
||||
use App\Models\User;
|
||||
use Exception;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\Select;
|
||||
@ -13,13 +14,16 @@
|
||||
|
||||
class Create
|
||||
{
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function form(): array
|
||||
{
|
||||
return [
|
||||
Select::make('provider')
|
||||
->options(
|
||||
collect(config('core.server_providers'))
|
||||
->filter(fn ($provider) => $provider != ServerProvider::CUSTOM)
|
||||
collect((array) config('core.server_providers'))
|
||||
->filter(fn ($provider): bool => $provider != ServerProvider::CUSTOM)
|
||||
->mapWithKeys(fn ($provider) => [$provider => $provider])
|
||||
)
|
||||
->live()
|
||||
@ -30,15 +34,15 @@ public static function form(): array
|
||||
TextInput::make('token')
|
||||
->label('API Key')
|
||||
->validationAttribute('API Key')
|
||||
->visible(fn ($get) => isset(CreateServerProvider::rules($get())['token']))
|
||||
->visible(fn ($get): bool => isset(CreateServerProvider::rules($get())['token']))
|
||||
->rules(fn (Get $get) => CreateServerProvider::rules($get())['token']),
|
||||
TextInput::make('key')
|
||||
->label('Access Key')
|
||||
->visible(fn ($get) => isset(CreateServerProvider::rules($get())['key']))
|
||||
->visible(fn ($get): bool => isset(CreateServerProvider::rules($get())['key']))
|
||||
->rules(fn (Get $get) => CreateServerProvider::rules($get())['key']),
|
||||
TextInput::make('secret')
|
||||
->label('Secret')
|
||||
->visible(fn ($get) => isset(CreateServerProvider::rules($get())['secret']))
|
||||
->visible(fn ($get): bool => isset(CreateServerProvider::rules($get())['secret']))
|
||||
->rules(fn (Get $get) => CreateServerProvider::rules($get())['secret']),
|
||||
Checkbox::make('global')
|
||||
->label('Is Global (Accessible in all projects)'),
|
||||
@ -46,12 +50,17 @@ public static function form(): array
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function action(array $data): void
|
||||
{
|
||||
try {
|
||||
app(CreateServerProvider::class)->create(auth()->user(), auth()->user()->currentProject, $data);
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
app(CreateServerProvider::class)->create($user, $user->currentProject, $data);
|
||||
} catch (Exception $e) {
|
||||
Notification::make()
|
||||
->title($e->getMessage())
|
||||
|
@ -4,11 +4,15 @@
|
||||
|
||||
use App\Actions\ServerProvider\EditServerProvider;
|
||||
use App\Models\ServerProvider;
|
||||
use App\Models\User;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
|
||||
class Edit
|
||||
{
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function form(): array
|
||||
{
|
||||
return [
|
||||
@ -20,8 +24,14 @@ public static function form(): array
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public static function action(ServerProvider $provider, array $data): void
|
||||
{
|
||||
app(EditServerProvider::class)->edit($provider, auth()->user()->currentProject, $data);
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
app(EditServerProvider::class)->edit($provider, $user->currentProject, $data);
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ protected function getHeaderActions(): array
|
||||
->form(Actions\Create::form())
|
||||
->authorize('create', ServerProvider::class)
|
||||
->modalWidth(MaxWidth::Medium)
|
||||
->using(function (array $data) {
|
||||
->using(function (array $data): void {
|
||||
Actions\Create::action($data);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Actions\ServerProvider\DeleteServerProvider;
|
||||
use App\Models\ServerProvider;
|
||||
use App\Models\User;
|
||||
use App\Web\Pages\Settings\ServerProviders\Actions\Edit;
|
||||
use Exception;
|
||||
use Filament\Notifications\Notification;
|
||||
@ -18,18 +19,27 @@
|
||||
|
||||
class ServerProvidersList extends Widget
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<ServerProvider>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return ServerProvider::getByProjectId(auth()->user()->current_project_id);
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return ServerProvider::getByProjectId($user->current_project_id);
|
||||
}
|
||||
|
||||
protected function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
IconColumn::make('provider')
|
||||
->icon(fn (ServerProvider $record) => 'icon-'.$record->provider)
|
||||
->icon(fn (ServerProvider $record): string => 'icon-'.$record->provider)
|
||||
->width(24),
|
||||
TextColumn::make('name')
|
||||
->default(fn ($record) => $record->profile)
|
||||
@ -39,10 +49,8 @@ protected function getTableColumns(): array
|
||||
TextColumn::make('id')
|
||||
->label('Global')
|
||||
->badge()
|
||||
->color(fn ($record) => $record->project_id ? 'gray' : 'success')
|
||||
->formatStateUsing(function (ServerProvider $record) {
|
||||
return $record->project_id ? 'No' : 'Yes';
|
||||
}),
|
||||
->color(fn ($record): string => $record->project_id ? 'gray' : 'success')
|
||||
->formatStateUsing(fn (ServerProvider $record): string => $record->project_id ? 'No' : 'Yes'),
|
||||
TextColumn::make('created_at')
|
||||
->label('Created At')
|
||||
->formatStateUsing(fn ($record) => $record->created_at_by_timezone)
|
||||
@ -53,6 +61,9 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->heading(null)
|
||||
->query($this->getTableQuery())
|
||||
@ -61,21 +72,19 @@ public function table(Table $table): Table
|
||||
EditAction::make('edit')
|
||||
->label('Edit')
|
||||
->modalHeading('Edit Server Provider')
|
||||
->mutateRecordDataUsing(function (array $data, ServerProvider $record) {
|
||||
return [
|
||||
'name' => $record->profile,
|
||||
'global' => $record->project_id === null,
|
||||
];
|
||||
})
|
||||
->mutateRecordDataUsing(fn (array $data, ServerProvider $record): array => [
|
||||
'name' => $record->profile,
|
||||
'global' => $record->project_id === null,
|
||||
])
|
||||
->form(Edit::form())
|
||||
->authorize(fn (ServerProvider $record) => auth()->user()->can('update', $record))
|
||||
->authorize(fn (ServerProvider $record) => $user->can('update', $record))
|
||||
->using(fn (array $data, ServerProvider $record) => Edit::action($record, $data))
|
||||
->modalWidth(MaxWidth::Medium),
|
||||
DeleteAction::make('delete')
|
||||
->label('Delete')
|
||||
->modalHeading('Delete Server Provider')
|
||||
->authorize(fn (ServerProvider $record) => auth()->user()->can('delete', $record))
|
||||
->using(function (array $data, ServerProvider $record) {
|
||||
->authorize(fn (ServerProvider $record) => $user->can('delete', $record))
|
||||
->using(function (array $data, ServerProvider $record): void {
|
||||
try {
|
||||
app(DeleteServerProvider::class)->delete($record);
|
||||
} catch (Exception $e) {
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Actions\SourceControl\ConnectSourceControl;
|
||||
use App\Enums\SourceControl;
|
||||
use App\Models\User;
|
||||
use Exception;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\Select;
|
||||
@ -13,12 +14,15 @@
|
||||
|
||||
class Create
|
||||
{
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function form(): array
|
||||
{
|
||||
return [
|
||||
Select::make('provider')
|
||||
->options(
|
||||
collect(config('core.source_control_providers'))
|
||||
collect((array) config('core.source_control_providers'))
|
||||
->mapWithKeys(fn ($provider) => [$provider => $provider])
|
||||
)
|
||||
->live()
|
||||
@ -29,21 +33,21 @@ public static function form(): array
|
||||
TextInput::make('token')
|
||||
->label('API Key')
|
||||
->validationAttribute('API Key')
|
||||
->visible(fn ($get) => in_array($get('provider'), [
|
||||
->visible(fn ($get): bool => in_array($get('provider'), [
|
||||
SourceControl::GITHUB,
|
||||
SourceControl::GITLAB,
|
||||
]))
|
||||
->rules(fn (Get $get) => ConnectSourceControl::rules($get())['token']),
|
||||
TextInput::make('url')
|
||||
->label('URL (optional)')
|
||||
->visible(fn ($get) => $get('provider') == SourceControl::GITLAB)
|
||||
->visible(fn ($get): bool => $get('provider') == SourceControl::GITLAB)
|
||||
->rules(fn (Get $get) => ConnectSourceControl::rules($get())['url'])
|
||||
->helperText('If you run a self-managed gitlab enter the url here, leave empty to use gitlab.com'),
|
||||
TextInput::make('username')
|
||||
->visible(fn ($get) => $get('provider') == SourceControl::BITBUCKET)
|
||||
->visible(fn ($get): bool => $get('provider') == SourceControl::BITBUCKET)
|
||||
->rules(fn (Get $get) => ConnectSourceControl::rules($get())['username']),
|
||||
TextInput::make('password')
|
||||
->visible(fn ($get) => $get('provider') == SourceControl::BITBUCKET)
|
||||
->visible(fn ($get): bool => $get('provider') == SourceControl::BITBUCKET)
|
||||
->rules(fn (Get $get) => ConnectSourceControl::rules($get())['password']),
|
||||
Checkbox::make('global')
|
||||
->label('Is Global (Accessible in all projects)'),
|
||||
@ -51,12 +55,17 @@ public static function form(): array
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function action(array $data): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
try {
|
||||
app(ConnectSourceControl::class)->connect(auth()->user(), auth()->user()->currentProject, $data);
|
||||
app(ConnectSourceControl::class)->connect($user->currentProject, $data);
|
||||
} catch (Exception $e) {
|
||||
Notification::make()
|
||||
->title($e->getMessage())
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Actions\SourceControl\EditSourceControl;
|
||||
use App\Models\SourceControl;
|
||||
use App\Models\User;
|
||||
use Exception;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
@ -12,6 +13,9 @@
|
||||
|
||||
class Edit
|
||||
{
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function form(SourceControl $sourceControl): array
|
||||
{
|
||||
return [
|
||||
@ -39,12 +43,17 @@ public static function form(SourceControl $sourceControl): array
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function action(SourceControl $sourceControl, array $data): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
try {
|
||||
app(EditSourceControl::class)->edit($sourceControl, auth()->user()->currentProject, $data);
|
||||
app(EditSourceControl::class)->edit($sourceControl, $user->currentProject, $data);
|
||||
} catch (Exception $e) {
|
||||
Notification::make()
|
||||
->title($e->getMessage())
|
||||
|
@ -42,7 +42,7 @@ protected function getHeaderActions(): array
|
||||
->form(Actions\Create::form())
|
||||
->authorize('create', SourceControl::class)
|
||||
->modalWidth(MaxWidth::Large)
|
||||
->action(function (array $data) {
|
||||
->action(function (array $data): void {
|
||||
Actions\Create::action($data);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Actions\SourceControl\DeleteSourceControl;
|
||||
use App\Models\SourceControl;
|
||||
use App\Models\User;
|
||||
use App\Web\Pages\Settings\SourceControls\Actions\Edit;
|
||||
use Exception;
|
||||
use Filament\Notifications\Notification;
|
||||
@ -18,18 +19,27 @@
|
||||
|
||||
class SourceControlsList extends Widget
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<SourceControl>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return SourceControl::getByProjectId(auth()->user()->current_project_id);
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return SourceControl::getByProjectId($user->current_project_id);
|
||||
}
|
||||
|
||||
protected function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
IconColumn::make('provider')
|
||||
->icon(fn (SourceControl $record) => 'icon-'.$record->provider)
|
||||
->icon(fn (SourceControl $record): string => 'icon-'.$record->provider)
|
||||
->width(24),
|
||||
TextColumn::make('name')
|
||||
->default(fn (SourceControl $record) => $record->profile)
|
||||
@ -39,10 +49,8 @@ protected function getTableColumns(): array
|
||||
TextColumn::make('id')
|
||||
->label('Global')
|
||||
->badge()
|
||||
->color(fn (SourceControl $record) => $record->project_id ? 'gray' : 'success')
|
||||
->formatStateUsing(function (SourceControl $record) {
|
||||
return $record->project_id ? 'No' : 'Yes';
|
||||
}),
|
||||
->color(fn (SourceControl $record): string => $record->project_id ? 'gray' : 'success')
|
||||
->formatStateUsing(fn (SourceControl $record): string => $record->project_id ? 'No' : 'Yes'),
|
||||
TextColumn::make('created_at')
|
||||
->label('Created At')
|
||||
->formatStateUsing(fn (SourceControl $record) => $record->created_at_by_timezone)
|
||||
@ -53,6 +61,9 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->heading(null)
|
||||
->query($this->getTableQuery())
|
||||
@ -61,18 +72,16 @@ public function table(Table $table): Table
|
||||
EditAction::make('edit')
|
||||
->label('Edit')
|
||||
->modalHeading('Edit Source Control')
|
||||
->fillForm(function (array $data, SourceControl $record) {
|
||||
return [
|
||||
'provider' => $record->provider,
|
||||
'name' => $record->profile,
|
||||
'token' => $record->provider_data['token'] ?? null,
|
||||
'username' => $record->provider_data['username'] ?? null,
|
||||
'password' => $record->provider_data['password'] ?? null,
|
||||
'global' => $record->project_id === null,
|
||||
];
|
||||
})
|
||||
->form(fn (SourceControl $record) => Edit::form($record))
|
||||
->authorize(fn (SourceControl $record) => auth()->user()->can('update', $record))
|
||||
->fillForm(fn (array $data, SourceControl $record): array => [
|
||||
'provider' => $record->provider,
|
||||
'name' => $record->profile,
|
||||
'token' => $record->provider_data['token'] ?? null,
|
||||
'username' => $record->provider_data['username'] ?? null,
|
||||
'password' => $record->provider_data['password'] ?? null,
|
||||
'global' => $record->project_id === null,
|
||||
])
|
||||
->form(fn (SourceControl $record): array => Edit::form($record))
|
||||
->authorize(fn (SourceControl $record) => $user->can('update', $record))
|
||||
->using(fn (array $data, SourceControl $record) => Edit::action($record, $data))
|
||||
->modalWidth(MaxWidth::Medium),
|
||||
Action::make('delete')
|
||||
@ -81,8 +90,8 @@ public function table(Table $table): Table
|
||||
->color('danger')
|
||||
->requiresConfirmation()
|
||||
->modalHeading('Delete Source Control')
|
||||
->authorize(fn (SourceControl $record) => auth()->user()->can('delete', $record))
|
||||
->action(function (array $data, SourceControl $record) {
|
||||
->authorize(fn (SourceControl $record) => $user->can('delete', $record))
|
||||
->action(function (array $data, SourceControl $record): void {
|
||||
try {
|
||||
app(DeleteSourceControl::class)->delete($record);
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Actions\StorageProvider\CreateStorageProvider;
|
||||
use App\Enums\StorageProvider;
|
||||
use App\Models\User;
|
||||
use App\Web\Components\Link;
|
||||
use Exception;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
@ -14,12 +15,15 @@
|
||||
|
||||
class Create
|
||||
{
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function form(): array
|
||||
{
|
||||
return [
|
||||
Select::make('provider')
|
||||
->options(
|
||||
collect(config('core.storage_providers'))
|
||||
collect((array) config('core.storage_providers'))
|
||||
->mapWithKeys(fn ($provider) => [$provider => $provider])
|
||||
)
|
||||
->live()
|
||||
@ -31,62 +35,58 @@ public static function form(): array
|
||||
TextInput::make('token')
|
||||
->label('API Token')
|
||||
->validationAttribute('API Token')
|
||||
->visible(fn ($get) => $get('provider') == StorageProvider::DROPBOX)
|
||||
->visible(fn ($get): bool => $get('provider') == StorageProvider::DROPBOX)
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['token']),
|
||||
Grid::make()
|
||||
->visible(fn ($get) => $get('provider') == StorageProvider::FTP)
|
||||
->visible(fn ($get): bool => $get('provider') == StorageProvider::FTP)
|
||||
->schema([
|
||||
TextInput::make('host')
|
||||
->visible(fn ($get) => $get('provider') == StorageProvider::FTP)
|
||||
->visible(fn ($get): bool => $get('provider') == StorageProvider::FTP)
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['host']),
|
||||
TextInput::make('port')
|
||||
->visible(fn ($get) => $get('provider') == StorageProvider::FTP)
|
||||
->visible(fn ($get): bool => $get('provider') == StorageProvider::FTP)
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['port']),
|
||||
TextInput::make('username')
|
||||
->visible(fn ($get) => $get('provider') == StorageProvider::FTP)
|
||||
->visible(fn ($get): bool => $get('provider') == StorageProvider::FTP)
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['username']),
|
||||
TextInput::make('password')
|
||||
->visible(fn ($get) => $get('provider') == StorageProvider::FTP)
|
||||
->visible(fn ($get): bool => $get('provider') == StorageProvider::FTP)
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['password']),
|
||||
Checkbox::make('ssl')
|
||||
->visible(fn ($get) => $get('provider') == StorageProvider::FTP)
|
||||
->visible(fn ($get): bool => $get('provider') == StorageProvider::FTP)
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['ssl']),
|
||||
Checkbox::make('passive')
|
||||
->visible(fn ($get) => $get('provider') == StorageProvider::FTP)
|
||||
->visible(fn ($get): bool => $get('provider') == StorageProvider::FTP)
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['passive']),
|
||||
]),
|
||||
TextInput::make('api_url')
|
||||
->label('API URL')
|
||||
->visible(fn ($get) => $get('provider') == StorageProvider::S3)
|
||||
->visible(fn ($get): bool => $get('provider') == StorageProvider::S3)
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['api_url'])
|
||||
->helperText('Required if you are using an S3 compatible provider like Cloudflare R2'),
|
||||
TextInput::make('path')
|
||||
->visible(fn ($get) => in_array($get('provider'), [
|
||||
->visible(fn ($get): bool => in_array($get('provider'), [
|
||||
StorageProvider::S3,
|
||||
StorageProvider::FTP,
|
||||
StorageProvider::LOCAL,
|
||||
]))
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['path'])
|
||||
->helperText(function ($get) {
|
||||
return match ($get('provider')) {
|
||||
StorageProvider::LOCAL => 'The absolute path on your server that the database exists. like `/home/vito/db-backups`',
|
||||
default => '',
|
||||
};
|
||||
->helperText(fn ($get): string => match ($get('provider')) {
|
||||
StorageProvider::LOCAL => 'The absolute path on your server that the database exists. like `/home/vito/db-backups`',
|
||||
default => '',
|
||||
}),
|
||||
Grid::make()
|
||||
->visible(fn ($get) => $get('provider') == StorageProvider::S3)
|
||||
->visible(fn ($get): bool => $get('provider') == StorageProvider::S3)
|
||||
->schema([
|
||||
TextInput::make('key')
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['key'])
|
||||
->helperText(function ($get) {
|
||||
return match ($get('provider')) {
|
||||
StorageProvider::S3 => new Link(
|
||||
href: 'https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html',
|
||||
text: 'How to generate?',
|
||||
external: true
|
||||
),
|
||||
default => '',
|
||||
};
|
||||
->helperText(fn ($get): Link|string => match ($get('provider')) {
|
||||
StorageProvider::S3 => new Link(
|
||||
href: 'https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html',
|
||||
text: 'How to generate?',
|
||||
external: true
|
||||
),
|
||||
default => '',
|
||||
}),
|
||||
TextInput::make('secret')
|
||||
->rules(fn ($get) => CreateStorageProvider::rules($get())['secret']),
|
||||
@ -101,12 +101,17 @@ public static function form(): array
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function action(array $data): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
try {
|
||||
app(CreateStorageProvider::class)->create(auth()->user(), auth()->user()->currentProject, $data);
|
||||
app(CreateStorageProvider::class)->create($user, $user->currentProject, $data);
|
||||
} catch (Exception $e) {
|
||||
Notification::make()
|
||||
->title($e->getMessage())
|
||||
|
@ -4,11 +4,15 @@
|
||||
|
||||
use App\Actions\StorageProvider\EditStorageProvider;
|
||||
use App\Models\StorageProvider;
|
||||
use App\Models\User;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
|
||||
class Edit
|
||||
{
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function form(): array
|
||||
{
|
||||
return [
|
||||
@ -20,8 +24,14 @@ public static function form(): array
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public static function action(StorageProvider $provider, array $data): void
|
||||
{
|
||||
app(EditStorageProvider::class)->edit($provider, auth()->user()->currentProject, $data);
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
app(EditStorageProvider::class)->edit($provider, $user->currentProject, $data);
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ protected function getHeaderActions(): array
|
||||
->form(Actions\Create::form())
|
||||
->authorize('create', StorageProvider::class)
|
||||
->modalWidth(MaxWidth::ExtraLarge)
|
||||
->action(function (array $data) {
|
||||
->action(function (array $data): void {
|
||||
Actions\Create::action($data);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
|
@ -4,7 +4,9 @@
|
||||
|
||||
use App\Actions\StorageProvider\DeleteStorageProvider;
|
||||
use App\Models\StorageProvider;
|
||||
use App\Models\User;
|
||||
use App\Web\Pages\Settings\StorageProviders\Actions\Edit;
|
||||
use Exception;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Support\Enums\MaxWidth;
|
||||
use Filament\Tables\Actions\DeleteAction;
|
||||
@ -17,18 +19,27 @@
|
||||
|
||||
class StorageProvidersList extends Widget
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<StorageProvider>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return StorageProvider::getByProjectId(auth()->user()->current_project_id);
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return StorageProvider::getByProjectId($user->current_project_id);
|
||||
}
|
||||
|
||||
protected function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
IconColumn::make('provider')
|
||||
->icon(fn (StorageProvider $record) => 'icon-'.$record->provider)
|
||||
->icon(fn (StorageProvider $record): string => 'icon-'.$record->provider)
|
||||
->tooltip(fn (StorageProvider $record) => $record->provider)
|
||||
->width(24),
|
||||
TextColumn::make('name')
|
||||
@ -39,10 +50,8 @@ protected function getTableColumns(): array
|
||||
TextColumn::make('id')
|
||||
->label('Global')
|
||||
->badge()
|
||||
->color(fn ($record) => $record->project_id ? 'gray' : 'success')
|
||||
->formatStateUsing(function (StorageProvider $record) {
|
||||
return $record->project_id ? 'No' : 'Yes';
|
||||
}),
|
||||
->color(fn ($record): string => $record->project_id ? 'gray' : 'success')
|
||||
->formatStateUsing(fn (StorageProvider $record): string => $record->project_id ? 'No' : 'Yes'),
|
||||
TextColumn::make('created_at')
|
||||
->label('Created At')
|
||||
->formatStateUsing(fn ($record) => $record->created_at_by_timezone)
|
||||
@ -53,6 +62,9 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->heading(null)
|
||||
->query($this->getTableQuery())
|
||||
@ -61,24 +73,22 @@ public function table(Table $table): Table
|
||||
EditAction::make('edit')
|
||||
->label('Edit')
|
||||
->modalHeading('Edit Storage Provider')
|
||||
->mutateRecordDataUsing(function (array $data, StorageProvider $record) {
|
||||
return [
|
||||
'name' => $record->profile,
|
||||
'global' => $record->project_id === null,
|
||||
];
|
||||
})
|
||||
->mutateRecordDataUsing(fn (array $data, StorageProvider $record): array => [
|
||||
'name' => $record->profile,
|
||||
'global' => $record->project_id === null,
|
||||
])
|
||||
->form(Edit::form())
|
||||
->authorize(fn (StorageProvider $record) => auth()->user()->can('update', $record))
|
||||
->authorize(fn (StorageProvider $record) => $user->can('update', $record))
|
||||
->using(fn (array $data, StorageProvider $record) => Edit::action($record, $data))
|
||||
->modalWidth(MaxWidth::Medium),
|
||||
DeleteAction::make('delete')
|
||||
->label('Delete')
|
||||
->modalHeading('Delete Storage Provider')
|
||||
->authorize(fn (StorageProvider $record) => auth()->user()->can('delete', $record))
|
||||
->using(function (array $data, StorageProvider $record) {
|
||||
->authorize(fn (StorageProvider $record) => $user->can('delete', $record))
|
||||
->using(function (array $data, StorageProvider $record): void {
|
||||
try {
|
||||
app(DeleteStorageProvider::class)->delete($record);
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
Notification::make()
|
||||
->danger()
|
||||
->title($e->getMessage())
|
||||
|
@ -12,6 +12,9 @@
|
||||
|
||||
class Create
|
||||
{
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function form(): array
|
||||
{
|
||||
return [
|
||||
@ -19,10 +22,10 @@ public static function form(): array
|
||||
->rules(fn ($get) => CreateTag::rules()['name']),
|
||||
Select::make('color')
|
||||
->prefixIcon('heroicon-s-tag')
|
||||
->prefixIconColor(fn (Get $get) => $get('color'))
|
||||
->prefixIconColor(fn (Get $get): mixed => $get('color'))
|
||||
->searchable()
|
||||
->options(
|
||||
collect(config('core.tag_colors'))
|
||||
collect((array) config('core.tag_colors'))
|
||||
->mapWithKeys(fn ($color) => [$color => $color])
|
||||
)
|
||||
->reactive()
|
||||
@ -31,12 +34,17 @@ public static function form(): array
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function action(array $data): Tag
|
||||
{
|
||||
try {
|
||||
return app(CreateTag::class)->create(auth()->user(), $data);
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return app(CreateTag::class)->create($user, $data);
|
||||
} catch (Exception $e) {
|
||||
Notification::make()
|
||||
->title($e->getMessage())
|
||||
|
@ -9,6 +9,9 @@
|
||||
|
||||
class Edit
|
||||
{
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function form(): array
|
||||
{
|
||||
return [
|
||||
@ -17,13 +20,16 @@ public static function form(): array
|
||||
Select::make('color')
|
||||
->searchable()
|
||||
->options(
|
||||
collect(config('core.tag_colors'))
|
||||
collect((array) config('core.tag_colors'))
|
||||
->mapWithKeys(fn ($color) => [$color => $color])
|
||||
)
|
||||
->rules(fn ($get) => EditTag::rules()['color']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public static function action(Tag $tag, array $data): void
|
||||
{
|
||||
app(EditTag::class)->edit($tag, $data);
|
||||
|
@ -5,6 +5,8 @@
|
||||
use App\Actions\Tag\SyncTags;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use App\Models\User;
|
||||
use Closure;
|
||||
use Filament\Forms\Components\Actions\Action as FormAction;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Infolists\Components\Actions\Action as InfolistAction;
|
||||
@ -26,8 +28,8 @@ public static function infolist(mixed $taggable): InfolistAction
|
||||
->modalSubmitActionLabel('Save')
|
||||
->modalHeading('Edit Tags')
|
||||
->modalWidth(MaxWidth::Medium)
|
||||
->form(static::form($taggable))
|
||||
->action(static::action($taggable));
|
||||
->form(self::form($taggable))
|
||||
->action(self::action($taggable));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,22 +44,23 @@ public static function table(mixed $taggable): TableAction
|
||||
->modalSubmitActionLabel('Save')
|
||||
->modalHeading('Edit Tags')
|
||||
->modalWidth(MaxWidth::Medium)
|
||||
->form(static::form($taggable))
|
||||
->action(static::action($taggable));
|
||||
->form(self::form($taggable))
|
||||
->action(self::action($taggable));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Site|Server $taggable
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
private static function form(mixed $taggable): array
|
||||
private static function form(Site|Server $taggable): array
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return [
|
||||
Select::make('tags')
|
||||
->default($taggable->tags()->pluck('tags.id')->toArray())
|
||||
->options(function () {
|
||||
return auth()->user()->currentProject->tags()->pluck('name', 'id')->toArray();
|
||||
})
|
||||
->nestedRecursiveRules(SyncTags::rules(auth()->user()->currentProject->id)['tags.*'])
|
||||
->options(fn () => $user->currentProject->tags()->pluck('name', 'id')->toArray())
|
||||
->nestedRecursiveRules(SyncTags::rules($user->currentProject->id)['tags.*'])
|
||||
->suffixAction(
|
||||
FormAction::make('create_tag')
|
||||
->icon('heroicon-o-plus')
|
||||
@ -66,7 +69,7 @@ private static function form(mixed $taggable): array
|
||||
->modalHeading('Create Tag')
|
||||
->modalWidth(MaxWidth::Medium)
|
||||
->form(Create::form())
|
||||
->action(function (array $data) {
|
||||
->action(function (array $data): void {
|
||||
Create::action($data);
|
||||
}),
|
||||
)
|
||||
@ -77,12 +80,12 @@ private static function form(mixed $taggable): array
|
||||
/**
|
||||
* @param Site|Server $taggable
|
||||
*/
|
||||
private static function action(mixed $taggable): \Closure
|
||||
private static function action(mixed $taggable): Closure
|
||||
{
|
||||
return function (array $data) use ($taggable) {
|
||||
app(SyncTags::class)->sync(auth()->user(), [
|
||||
return function (array $data) use ($taggable): void {
|
||||
app(SyncTags::class)->sync([
|
||||
'taggable_id' => $taggable->id,
|
||||
'taggable_type' => get_class($taggable),
|
||||
'taggable_type' => $taggable::class,
|
||||
'tags' => $data['tags'],
|
||||
]);
|
||||
|
||||
|
@ -25,6 +25,9 @@ public static function canAccess(): bool
|
||||
return auth()->user()?->can('viewAny', Tag::class) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<int, class-string>>
|
||||
*/
|
||||
public function getWidgets(): array
|
||||
{
|
||||
return [
|
||||
@ -44,7 +47,7 @@ protected function getHeaderActions(): array
|
||||
->form(Actions\Create::form())
|
||||
->authorize('create', Tag::class)
|
||||
->modalWidth(MaxWidth::ExtraLarge)
|
||||
->using(function (array $data) {
|
||||
->using(function (array $data): void {
|
||||
Actions\Create::action($data);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Actions\Tag\DeleteTag;
|
||||
use App\Models\Tag;
|
||||
use App\Models\User;
|
||||
use App\Web\Pages\Settings\Tags\Actions\Edit;
|
||||
use Filament\Support\Enums\MaxWidth;
|
||||
use Filament\Tables\Actions\Action;
|
||||
@ -17,11 +18,20 @@
|
||||
|
||||
class TagsList extends Widget
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<Tag>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return Tag::getByProjectId(auth()->user()->current_project_id);
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return Tag::getByProjectId($user->current_project_id);
|
||||
}
|
||||
|
||||
protected function getTableColumns(): array
|
||||
@ -53,25 +63,29 @@ public function table(Table $table): Table
|
||||
|
||||
private function editAction(): Action
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return EditAction::make('edit')
|
||||
->fillForm(function (Tag $record) {
|
||||
return [
|
||||
'name' => $record->name,
|
||||
'color' => $record->color,
|
||||
'global' => $record->project_id === null,
|
||||
];
|
||||
})
|
||||
->fillForm(fn (Tag $record): array => [
|
||||
'name' => $record->name,
|
||||
'color' => $record->color,
|
||||
'global' => $record->project_id === null,
|
||||
])
|
||||
->form(Edit::form())
|
||||
->authorize(fn (Tag $record) => auth()->user()->can('update', $record))
|
||||
->authorize(fn (Tag $record) => $user->can('update', $record))
|
||||
->using(fn (array $data, Tag $record) => Edit::action($record, $data))
|
||||
->modalWidth(MaxWidth::Medium);
|
||||
}
|
||||
|
||||
private function deleteAction(): Action
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return DeleteAction::make('delete')
|
||||
->authorize(fn (Tag $record) => auth()->user()->can('delete', $record))
|
||||
->using(function (Tag $record) {
|
||||
->authorize(fn (Tag $record) => $user->can('delete', $record))
|
||||
->using(function (Tag $record): void {
|
||||
app(DeleteTag::class)->delete($record);
|
||||
});
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ public static function canAccess(): bool
|
||||
return auth()->user()?->can('viewAny', User::class) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<int, class-string>>
|
||||
*/
|
||||
public function getWidgets(): array
|
||||
{
|
||||
return [
|
||||
@ -48,7 +51,7 @@ protected function getHeaderActions(): array
|
||||
|
||||
return $user;
|
||||
})
|
||||
->form(function (Form $form) {
|
||||
->form(function (Form $form): \Filament\Forms\Form {
|
||||
$rules = CreateUser::rules();
|
||||
|
||||
return $form
|
||||
@ -61,7 +64,7 @@ protected function getHeaderActions(): array
|
||||
->rules($rules['password']),
|
||||
Select::make('role')
|
||||
->rules($rules['role'])
|
||||
->options(collect(config('core.user_roles'))->mapWithKeys(fn ($role) => [$role => $role])),
|
||||
->options(collect((array) config('core.user_roles'))->mapWithKeys(fn ($role) => [$role => $role])),
|
||||
])
|
||||
->columns(1);
|
||||
})
|
||||
|
@ -18,17 +18,14 @@
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Filament\Widgets\TableWidget as Widget;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class UsersList extends Widget
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return User::query();
|
||||
}
|
||||
|
||||
protected function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
@ -50,56 +47,55 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->heading(null)
|
||||
->query($this->getTableQuery())
|
||||
->query(User::query())
|
||||
->columns($this->getTableColumns())
|
||||
->actions([
|
||||
EditAction::make('edit')
|
||||
->authorize(fn ($record) => auth()->user()->can('update', $record))
|
||||
->using(function ($record, array $data) {
|
||||
->authorize(fn ($record) => $user->can('update', $record))
|
||||
->using(function ($record, array $data): void {
|
||||
app(UpdateUser::class)->update($record, $data);
|
||||
})
|
||||
->form(function (Form $form, $record) {
|
||||
return $form
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->rules(UpdateUser::rules($record)['name']),
|
||||
TextInput::make('email')
|
||||
->rules(UpdateUser::rules($record)['email']),
|
||||
Select::make('timezone')
|
||||
->searchable()
|
||||
->options(
|
||||
collect(timezone_identifiers_list())
|
||||
->mapWithKeys(fn ($timezone) => [$timezone => $timezone])
|
||||
)
|
||||
->rules(UpdateUser::rules($record)['timezone']),
|
||||
Select::make('role')
|
||||
->options(
|
||||
collect(config('core.user_roles'))
|
||||
->mapWithKeys(fn ($role) => [$role => $role])
|
||||
)
|
||||
->rules(UpdateUser::rules($record)['role']),
|
||||
])
|
||||
->columns(1);
|
||||
})
|
||||
->form(fn (Form $form, $record): \Filament\Forms\Form => $form
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->rules(UpdateUser::rules($record)['name']),
|
||||
TextInput::make('email')
|
||||
->rules(UpdateUser::rules($record)['email']),
|
||||
Select::make('timezone')
|
||||
->searchable()
|
||||
->options(
|
||||
collect(timezone_identifiers_list())
|
||||
->mapWithKeys(fn ($timezone) => [$timezone => $timezone])
|
||||
)
|
||||
->rules(UpdateUser::rules($record)['timezone']),
|
||||
Select::make('role')
|
||||
->options(
|
||||
collect((array) config('core.user_roles'))
|
||||
->mapWithKeys(fn ($role) => [$role => $role])
|
||||
)
|
||||
->rules(UpdateUser::rules($record)['role']),
|
||||
])
|
||||
->columns(1))
|
||||
->modalWidth(MaxWidth::Large),
|
||||
Action::make('update-projects')
|
||||
->label('Projects')
|
||||
->icon('heroicon-o-rectangle-stack')
|
||||
->authorize(fn ($record) => auth()->user()->can('update', $record))
|
||||
->form(function (Form $form, $record) {
|
||||
return $form
|
||||
->schema([
|
||||
CheckboxList::make('projects')
|
||||
->options(Project::query()->pluck('name', 'id')->toArray())
|
||||
->searchable()
|
||||
->default($record->projects->pluck('id')->toArray())
|
||||
->rules(UpdateProjects::rules()['projects.*']),
|
||||
])
|
||||
->columns(1);
|
||||
})
|
||||
->action(function ($record, array $data) {
|
||||
->authorize(fn ($record) => $user->can('update', $record))
|
||||
->form(fn (Form $form, $record): \Filament\Forms\Form => $form
|
||||
->schema([
|
||||
CheckboxList::make('projects')
|
||||
->options(Project::query()->pluck('name', 'id')->toArray())
|
||||
->searchable()
|
||||
->default($record->projects->pluck('id')->toArray())
|
||||
->rules(UpdateProjects::rules()['projects.*']),
|
||||
])
|
||||
->columns(1))
|
||||
->action(function ($record, array $data): void {
|
||||
app(UpdateProjects::class)->update($record, $data);
|
||||
Notification::make()
|
||||
->title('Projects Updated')
|
||||
@ -109,7 +105,7 @@ public function table(Table $table): Table
|
||||
->modalSubmitActionLabel('Save')
|
||||
->modalWidth(MaxWidth::Large),
|
||||
DeleteAction::make('delete')
|
||||
->authorize(fn (User $record) => auth()->user()->can('delete', $record)),
|
||||
->authorize(fn (User $record) => $user->can('delete', $record)),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user