Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

'column.name' => 'Name',
'column.guard_name' => 'Guard Name',
'column.team' => 'Team',
'column.team' => 'Site',
'column.roles' => 'Roles',
'column.permissions' => 'Permissions',
'column.updated_at' => 'Updated At',
Expand Down
19 changes: 17 additions & 2 deletions src/EclipseServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use Eclipse\Core\Providers\HorizonServiceProvider;
use Eclipse\Core\Providers\TelescopeServiceProvider;
use Eclipse\Core\Services\Registry;
use Filament\Forms\Components\Field;
use Filament\Infolists\Components\Entry;
use Filament\Resources\Resource;
use Filament\Tables\Columns\Column;
use Illuminate\Auth\Events\Login;
Expand Down Expand Up @@ -70,7 +72,7 @@ public function register(): self
{
parent::register();

require_once __DIR__.'/Helpers/helpers.php';
require_once __DIR__ . '/Helpers/helpers.php';
Comment thread
SlimDeluxe marked this conversation as resolved.
Outdated

Event::listen(Login::class, function ($event) {
if ($event->user instanceof User) {
Expand Down Expand Up @@ -105,7 +107,7 @@ public function boot(): void
}

// Enable Model strictness when not in production
Model::shouldBeStrict(! app()->isProduction());
Model::shouldBeStrict(!app()->isProduction());

// Do not allow destructive DB commands in production
DB::prohibitDestructiveCommands(app()->isProduction());
Expand All @@ -121,9 +123,22 @@ public function boot(): void
// Register policies for classes that can't be guessed automatically
Gate::policy(Role::class, RolePolicy::class);

// Set common settings for Filament form
Field::configureUsing(function (Field $field) {
$field
->translateLabel();
});

// Set common settings for Filament infolist
Entry::configureUsing(function (Entry $entry) {
$entry
->translateLabel();
});

// Set common settings for Filament table columns
Column::configureUsing(function (Column $column) {
$column
->translateLabel()
->toggleable()
->sortable();
});
Expand Down
217 changes: 217 additions & 0 deletions src/Filament/Resources/RoleResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
<?php

namespace Eclipse\Core\Filament\Resources;

use BezhanSalleh\FilamentShield\Contracts\HasShieldPermissions;
use BezhanSalleh\FilamentShield\Forms\ShieldSelectAllToggle;
use Eclipse\Core\Filament\Resources\RoleResource\Pages;
use BezhanSalleh\FilamentShield\Support\Utils;
use BezhanSalleh\FilamentShield\Traits\HasShieldFormComponents;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Pages\SubNavigationPosition;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules\Unique;

class RoleResource extends Resource implements HasShieldPermissions
{
use HasShieldFormComponents;

protected static ?string $recordTitleAttribute = 'name';

public static function getPermissionPrefixes(): array
{
return [
'view',
'view_any',
'create',
'update',
'delete',
'delete_any',
];
}

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Grid::make()
->schema([
Forms\Components\Section::make()
->schema([
Forms\Components\TextInput::make('name')
->label(__('filament-shield::filament-shield.field.name'))
->unique(
ignoreRecord: true, /** @phpstan-ignore-next-line */
modifyRuleUsing: fn (Unique $rule) => ! Utils::isTenancyEnabled() ? $rule : $rule->where(Utils::getTenantModelForeignKey(), Filament::getTenant()?->id)
)
->required()
->maxLength(255),

Forms\Components\TextInput::make('guard_name')
->label(__('filament-shield::filament-shield.field.guard_name'))
->default(Utils::getFilamentAuthGuard())
->nullable()
->maxLength(255),

Forms\Components\Select::make(config('permission.column_names.team_foreign_key'))
->label(__('filament-shield::filament-shield.field.team'))
->placeholder(__('filament-shield::filament-shield.field.team.placeholder'))
/** @phpstan-ignore-next-line */
->default([Filament::getTenant()?->id])
->options(fn (): Arrayable => Utils::getTenantModel() ? Utils::getTenantModel()::pluck('name', 'id') : collect())
->dehydrated(fn (): bool => ! (static::shield()->isCentralApp() && Utils::isTenancyEnabled())),
ShieldSelectAllToggle::make('select_all')
->onIcon('heroicon-s-shield-check')
->offIcon('heroicon-s-shield-exclamation')
->label(__('filament-shield::filament-shield.field.select_all.name'))
->helperText(fn (): HtmlString => new HtmlString(__('filament-shield::filament-shield.field.select_all.message')))
->dehydrated(fn (bool $state): bool => $state),

])
->columns([
'sm' => 2,
'lg' => 3,
]),
]),
static::getShieldFormComponents(),
]);
}

public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name')
->weight('font-medium')
->label(__('filament-shield::filament-shield.column.name'))
->formatStateUsing(fn ($state): string => Str::headline($state))
->searchable(),
Tables\Columns\TextColumn::make('guard_name')
->badge()
->color('warning')
->label(__('filament-shield::filament-shield.column.guard_name')),
Tables\Columns\TextColumn::make('site.name')
->default('Global')
->badge()
->color(fn (mixed $state): string => str($state)->contains('Global') ? 'gray' : 'primary')
->label(__('filament-shield::filament-shield.column.team'))
->searchable(),
Tables\Columns\TextColumn::make('permissions_count')
->badge()
->label(__('filament-shield::filament-shield.column.permissions'))
->counts('permissions')
->colors(['success']),
Tables\Columns\TextColumn::make('updated_at')
->label(__('filament-shield::filament-shield.column.updated_at'))
->dateTime(),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}

public static function getRelations(): array
{
return [
//
];
}

public static function getPages(): array
{
return [
'index' => Pages\ListRoles::route('/'),
'create' => Pages\CreateRole::route('/create'),
'view' => Pages\ViewRole::route('/{record}'),
'edit' => Pages\EditRole::route('/{record}/edit'),
];
}

public static function getCluster(): ?string
{
return Utils::getResourceCluster() ?? static::$cluster;
}

public static function getModel(): string
{
return Utils::getRoleModel();
}

public static function getModelLabel(): string
{
return __('filament-shield::filament-shield.resource.label.role');
}

public static function getPluralModelLabel(): string
{
return __('filament-shield::filament-shield.resource.label.roles');
}

public static function shouldRegisterNavigation(): bool
{
return Utils::isResourceNavigationRegistered();
}

public static function getNavigationGroup(): ?string
{
return Utils::isResourceNavigationGroupEnabled()
? __('filament-shield::filament-shield.nav.group')
: '';
}

public static function getNavigationLabel(): string
{
return __('filament-shield::filament-shield.nav.role.label');
}

public static function getNavigationIcon(): string
{
return __('filament-shield::filament-shield.nav.role.icon');
}

public static function getNavigationSort(): ?int
{
return Utils::getResourceNavigationSort();
}

public static function getSubNavigationPosition(): SubNavigationPosition
{
return Utils::getSubNavigationPosition() ?? static::$subNavigationPosition;
}

public static function getSlug(): string
{
return Utils::getResourceSlug();
}

public static function getNavigationBadge(): ?string
{
return Utils::isResourceNavigationBadgeEnabled()
? strval(static::getEloquentQuery()->count())
: null;
}

public static function isScopedToTenant(): bool
{
return Utils::isScopedToTenant();
}

public static function canGloballySearch(): bool
{
return Utils::isResourceGloballySearchable() && count(static::getGloballySearchableAttributes()) && static::canViewAny();
}
}
47 changes: 47 additions & 0 deletions src/Filament/Resources/RoleResource/Pages/CreateRole.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Eclipse\Core\Filament\Resources\RoleResource\Pages;

use Eclipse\Core\Filament\Resources\RoleResource;
use BezhanSalleh\FilamentShield\Support\Utils;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;

class CreateRole extends CreateRecord
{
protected static string $resource = RoleResource::class;

public Collection $permissions;

protected function mutateFormDataBeforeCreate(array $data): array
{
$this->permissions = collect($data)
->filter(function ($permission, $key) {
return ! in_array($key, ['name', 'guard_name', 'select_all', Utils::getTenantModelForeignKey()]);
})
->values()
->flatten()
->unique();

if (Arr::has($data, Utils::getTenantModelForeignKey())) {
return Arr::only($data, ['name', 'guard_name', Utils::getTenantModelForeignKey()]);
}

return Arr::only($data, ['name', 'guard_name']);
}

protected function afterCreate(): void
{
$permissionModels = collect();
$this->permissions->each(function ($permission) use ($permissionModels) {
$permissionModels->push(Utils::getPermissionModel()::firstOrCreate([
/** @phpstan-ignore-next-line */
'name' => $permission,
'guard_name' => $this->data['guard_name'],
]));
});

$this->record->syncPermissions($permissionModels);
}
}
54 changes: 54 additions & 0 deletions src/Filament/Resources/RoleResource/Pages/EditRole.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Eclipse\Core\Filament\Resources\RoleResource\Pages;

use Eclipse\Core\Filament\Resources\RoleResource;
use BezhanSalleh\FilamentShield\Support\Utils;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;

class EditRole extends EditRecord
{
protected static string $resource = RoleResource::class;

public Collection $permissions;

protected function getActions(): array
{
return [
Actions\DeleteAction::make(),
];
}

protected function mutateFormDataBeforeSave(array $data): array
{
$this->permissions = collect($data)
->filter(function ($permission, $key) {
return ! in_array($key, ['name', 'guard_name', 'select_all', Utils::getTenantModelForeignKey()]);
})
->values()
->flatten()
->unique();

if (Arr::has($data, Utils::getTenantModelForeignKey())) {
return Arr::only($data, ['name', 'guard_name', Utils::getTenantModelForeignKey()]);
}

return Arr::only($data, ['name', 'guard_name']);
}

protected function afterSave(): void
{
$permissionModels = collect();
$this->permissions->each(function ($permission) use ($permissionModels) {
$permissionModels->push(Utils::getPermissionModel()::firstOrCreate([
'name' => $permission,
'guard_name' => $this->data['guard_name'],
]));
});

$this->record->syncPermissions($permissionModels);
}
}
19 changes: 19 additions & 0 deletions src/Filament/Resources/RoleResource/Pages/ListRoles.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Eclipse\Core\Filament\Resources\RoleResource\Pages;

use Eclipse\Core\Filament\Resources\RoleResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

class ListRoles extends ListRecords
{
protected static string $resource = RoleResource::class;

protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}
Loading