Initial commit: Pireon Admin — headless admin panel and public API
Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer collective, backed by the Pireon OAuth identity server. The public site is a separate, server-rendered application consuming /api/public/v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
85
app/Filament/Resources/Roles/Schemas/RoleForm.php
Normal file
85
app/Filament/Resources/Roles/Schemas/RoleForm.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Resources\Roles\Schemas;
|
||||
|
||||
use App\Support\Permissions;
|
||||
use Filament\Forms\Components\CheckboxList;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class RoleForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema->components([
|
||||
Section::make()->schema([
|
||||
TextInput::make('name')
|
||||
->label(__('panel.roles.fields.name'))
|
||||
->required()
|
||||
->maxLength(120)
|
||||
->rules(fn ($record) => [
|
||||
Rule::unique('roles', 'name')->ignore($record?->id),
|
||||
])
|
||||
// Renaming a structural role would break the code that
|
||||
// looks it up by name.
|
||||
->disabled(fn ($record) => $record && in_array($record->name, Permissions::protectedRoles(), true))
|
||||
->helperText(fn ($record) => $record && in_array($record->name, Permissions::protectedRoles(), true)
|
||||
? __('panel.roles.protected')
|
||||
: null),
|
||||
]),
|
||||
|
||||
// One collapsible section per resource, generated from
|
||||
// App\Support\Permissions — adding a permission there makes it
|
||||
// appear here with no further work.
|
||||
//
|
||||
// Each group writes to its own state path rather than binding the
|
||||
// `permissions` relationship directly: several components sharing
|
||||
// one relationship would overwrite each other on save. The page
|
||||
// classes flatten these back into a single syncPermissions() call
|
||||
// (see HandlesRolePermissions).
|
||||
...collect(Permissions::grouped())
|
||||
->map(fn (array $permissions, string $group) => Section::make(
|
||||
__("panel.permissions.groups.{$group}")
|
||||
)
|
||||
->collapsible()
|
||||
->collapsed($group !== 'general')
|
||||
->schema([
|
||||
CheckboxList::make("permission_groups.{$group}")
|
||||
->hiddenLabel()
|
||||
->options(collect($permissions)
|
||||
->mapWithKeys(fn (string $name) => [$name => self::abilityLabel($name)])
|
||||
->all())
|
||||
->bulkToggleable()
|
||||
->columns(3),
|
||||
]))
|
||||
->values()
|
||||
->all(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Human label for a permission, e.g. "pages.force_delete" becomes
|
||||
* "Eliminar definitivamente".
|
||||
*/
|
||||
public static function abilityLabel(string $permission): string
|
||||
{
|
||||
if ($permission === Permissions::PANEL_ACCESS) {
|
||||
return __('panel.permissions.abilities.panel_access');
|
||||
}
|
||||
|
||||
$ability = str_contains($permission, '.')
|
||||
? substr($permission, strpos($permission, '.') + 1)
|
||||
: $permission;
|
||||
|
||||
$key = "panel.permissions.abilities.{$ability}";
|
||||
$label = __($key);
|
||||
|
||||
// Fall back to the raw name if the catalogue grows a permission that
|
||||
// has no translation yet, rather than printing the missing key.
|
||||
return $label === $key ? $permission : $label;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user