Admin and super admin

We have admin and super admins. For some resources super admin has access to some additional columns which regular admins don't have. Super admins also have a few resources which admin don't have at all. Currently we're controlling this with if statements inside the resources which checks what kind of user it is. However this becomes clutterly with lots of if statements and also has a high risk of accidentally putting a super admin column visible for a regular user since it's all in same file. We want to somehow seperate the files completely so the code is more clear and no risk of mistakes. What is the best approach here? Is multi panel the best way to go? Is it possible in that case to have a base resource with the common columns and then extend that for the specific columns? Or how do we avoid duplicate code? Any help or guidance is highly appreciated!
14 Replies
Matthew
Matthew3mo ago
I always take the table columns and actions into their own class. From there you could have multiple classes or, if you're not concerned about the column order, you could do some array merging. You don't need multiple if statements for any solution though. Just have an isSuperAdmin function, and then something like: ->visible(fn use ($isSuperAdmin) => $isSuperAdmin)
victory365
victory3653mo ago
GitHub
GitHub - ManiruzzamanAkash/laravel-role: Laravel Role and Permissio...
Laravel Role and Permission Management With Beautiful Admin UI to starting a fresh project with basic role, permission management for Laravel 11.x - ManiruzzamanAkash/laravel-role
Povilas K
Povilas K3mo ago
In my personal opinion, by creating some other structure than default Filament, you would complicate the code which may INCREASE the risk of bugs and not decrease it. Maybe it's better to introduce automated tests for it? Not sure if it works but perhaps Livewire tests with assertSee should handle the job? https://livewire.laravel.com/docs/testing
Laravel
Testing | Laravel
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
krekas
krekas3mo ago
You can reuse fields. One example: https://youtu.be/8L-u2tyXw50?si=ODXuqIxXkwO7Lu6B
Filament Daily
YouTube
Filament: Reusable Fields as "Building Blocks" Class?
An example of repeatable and customizable CMS fields from an open-source project. Source: https://github.com/SabatinoMasala/filament-marketing-starter Related video "Splat Operator in PHP: Auto-Unpack Arrays" https://www.youtube.com/watch?v=Kopld21P7D0 More Filament examples on our website: https://filamentexamples.com
ChesterS
ChesterS3mo ago
There's no 'perfect' solution for what you're asking. My approach is that I have a resource for Admin and another for SuperAdmin that extends admin. The SuperAdmin resource just extends or overwrites some of the functionality of an Admin but a lot of the code is the same. Your milage may vary though ¯\_(ツ)_/¯ FWIW I created a custom collection
<?php

namespace App\Collections;

use Illuminate\Support\Collection;

class FilamentFieldCollection extends Collection
{
public function __construct($items = [])
{
$keys = array_map(fn ($col) => $col->getName(), $items);
parent::__construct(array_combine($keys, $items));
}
}
<?php

namespace App\Collections;

use Illuminate\Support\Collection;

class FilamentFieldCollection extends Collection
{
public function __construct($items = [])
{
$keys = array_map(fn ($col) => $col->getName(), $items);
parent::__construct(array_combine($keys, $items));
}
}
can be used like this
return new FilamentFieldCollection(
[
TextColumn::make('title')
->label(__('Title'))
->sortable()
->limit(50)
->visibleFrom('md'),
]
);
return new FilamentFieldCollection(
[
TextColumn::make('title')
->label(__('Title'))
->sortable()
->limit(50)
->visibleFrom('md'),
]
);
and then I access the fields like this
$fields = SomeResource::getFormFields();

$form->schema([
$fields['title'],
]);
$fields = SomeResource::getFormFields();

$form->schema([
$fields['title'],
]);
prouse_
prouse_OP3mo ago
The visible solution I don't like since it's easy for a new team member to add a new super admin field and then forget about the is visible since all is in the same class/file. So somehow I am looking for a solution that puts a clear seperation between the regular fields and super admin fields. Thanks for your reply. I definitely agree with you about not wanting to change to much structure. That's why I'm wondering what is the best way to achieve this in Filament. The tests is a good way to ensure of course. But it's still easy for a new team member to add a new field and forget to make it hidden for regular users and also write test for it. I'm looking for a way where we can put a clear seperation between the admin fields and super admin fields. Do you have any idea on the best way to achieve that?
Matthew
Matthew3mo ago
Two different classes to retrieve the columns. Have to repeat yourself though.
prouse_
prouse_OP3mo ago
This looks nice! But would you suggest to use multiple panels in this case and then reuse the fields in the super admin panel? Or what would you suggest? Do you also need to extend/overwrite the pages as well in this case? Such as Create, Edit and so on? It sounds like we have similar requirements. How has this solution worked for you? Any flaws so far?
Povilas K
Povilas K3mo ago
I think there's no SINGLE way to do it, would also depend on your app structure - tenancy, pages, etc. But it's mostly a typical coding question of "which level of abstration to choose". May be worth for me to dig deeper and shoot a video about it, but for now, I will just mention how to test it, something like:
test('slug visible only for admin', function () { actingAs(User::factory()->create([ 'is_admin' => true, ]));

livewire(CreatePost::class) ->assertFormFieldExists('slug'); });
test('slug visible only for admin', function () { actingAs(User::factory()->create([ 'is_admin' => true, ]));

livewire(CreatePost::class) ->assertFormFieldExists('slug'); });
prouse_
prouse_OP3mo ago
A video about this would be great! We have multi tenancy. My main concern is basically. Should we use multiple panels? And if yes, how do we best reuse the fields/logic. Extending the resources or making classes for the fields which we can reuse? And if we do not do multiple panels. How do we best make a clear seperation between regular fields and super admin fields.
Povilas K
Povilas K3mo ago
Exactly for that reason the video is tricky because in your case of multi-tenancy it becomes kinda more rare case, and I'm trying to shoot videos applicable for a broader audience. And all your questions are basically with the answer "ite depends", multiple panels usually depends on how different those fields and resources are, and how many common operations are planned, etc. Both may work.
ChesterS
ChesterS3mo ago
It works for us because we have 3 very distinct user groups (users/employees/admins) but it might not be great for you. No you don't have to re-write pages if they're the same, but you sometimes have to define which panel you want if you link to if it's different from the current user's. Eg if someone is a simple user but you want to link to admin, you'd do EditPage::getUrl(..., panel :'admin') Another issue is that if someone has access to both it kinda gets confusing. Let's say for example you are in the users table - You, as an admin, can edit users - but if you're not in the correct panel, you won't see that action. You have to switch panels,go to the super-admin user panel and then edit the users. There are other UX issues when having multiple panels - different login pages etc Also, let's say you someone links to a Profile page as a user - so /users/1 If you go to that page, you might not see all the actions available as an admin, you'd have to go to /admin/users/1 . Kinda annoying but also a bit safer in case you accidentally forget to add a policy to something 😂 Anyway, no magic bullets. Everything has its pros/cons. Good luck!
Matthew
Matthew3mo ago
Admin\Users\Employees is a common set up. I opt for 3 panels, each with its own auth guard and subdomain. Then a single person could potentially have an account on each.
ChesterS
ChesterS3mo ago
I wish... We need access to all 3 with one account and ... it's a struggle for some people to understand what's going on 🥲
Want results from more Discord servers?
Add your server