refactor: simplify data objects and improve role management components
- Removed redundant custom collections and `Wireable` trait from DTOs. - Replaced custom collection properties with `DataCollection`. - Updated role management views to use improved components, including avatars and toggle. - Refined Blade directives for scoped slots. - Minor cleanup in configuration and dependencies.
This commit is contained in:
parent
105123bb74
commit
ede0064b54
@ -4,19 +4,24 @@
|
||||
|
||||
namespace App\Data\Ui\ManageRoles;
|
||||
|
||||
use App\Data\Users\UsersData;
|
||||
use App\Data\Users\UserData;
|
||||
use App\Enums\RolesStatus;
|
||||
use Livewire\Wireable;
|
||||
use Spatie\LaravelData\Concerns\WireableData;
|
||||
use Spatie\LaravelData\Attributes\DataCollectionOf;
|
||||
use Spatie\LaravelData\Data;
|
||||
use Spatie\LaravelData\DataCollection;
|
||||
|
||||
final class RoleData extends Data implements Wireable
|
||||
final class RoleData extends Data
|
||||
{
|
||||
use WireableData;
|
||||
public function __construct(
|
||||
public string $name,
|
||||
public UsersData $users,
|
||||
public ServiceCollection $services,
|
||||
|
||||
/** @var DataCollection<int, UserData> */
|
||||
#[DataCollectionOf(class: UserData::class),]
|
||||
public DataCollection $users,
|
||||
|
||||
/** @var DataCollection<int, ServiceData> */
|
||||
#[DataCollectionOf(class: ServiceData::class),]
|
||||
public DataCollection $services,
|
||||
public RolesStatus $status,
|
||||
) {}
|
||||
}
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Data\Ui\ManageRoles;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @extends Collection<int, RoleData>
|
||||
*/
|
||||
final class RolesCollection extends Collection {}
|
||||
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Data\Ui\ManageRoles;
|
||||
|
||||
use Livewire\Wireable;
|
||||
use Spatie\LaravelData\Concerns\WireableData;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
final class RolesData extends Data implements Wireable
|
||||
{
|
||||
use WireableData;
|
||||
public function __construct(
|
||||
public RolesCollection $roles,
|
||||
) {}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Data\Ui\ManageRoles;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @extends Collection<int, ServiceData>
|
||||
*/
|
||||
final class ServiceCollection extends Collection {}
|
||||
@ -4,15 +4,9 @@
|
||||
|
||||
namespace App\Data\Ui\ManageRoles;
|
||||
|
||||
use Livewire\Wireable;
|
||||
use Spatie\LaravelData\Concerns\WireableData;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
final class ServiceData extends Data implements Wireable
|
||||
final class ServiceData extends Data
|
||||
{
|
||||
use WireableData;
|
||||
|
||||
public function __construct(
|
||||
public string $name,
|
||||
) {}
|
||||
public function __construct(public string $name) {}
|
||||
}
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Data\Users;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @extends Collection<int, UserData>
|
||||
*/
|
||||
final class UserCollection extends Collection {}
|
||||
@ -8,9 +8,5 @@
|
||||
|
||||
final class UserData extends Data
|
||||
{
|
||||
public function __construct(
|
||||
public string $name,
|
||||
public string $email,
|
||||
) {}
|
||||
|
||||
public function __construct(public string $name, public string $email) {}
|
||||
}
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Data\Users;
|
||||
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
final class UsersData extends Data
|
||||
{
|
||||
public function __construct(
|
||||
public UserCollection $users,
|
||||
) {}
|
||||
}
|
||||
@ -25,19 +25,18 @@ public function registerScopeDirective(): void
|
||||
*
|
||||
* https://github.com/konradkalemba/blade-components-scoped-slots
|
||||
*/
|
||||
Blade::directive('scope', function ($expression) {
|
||||
Blade::directive("scope", function ($expression) {
|
||||
// Split the expression by `top-level` commas (not in parentheses)
|
||||
$directiveArguments = preg_split("/,(?![^\(\(]*[\)\)])/", $expression);
|
||||
$directiveArguments = array_map('trim', $directiveArguments);
|
||||
$directiveArguments = array_map("trim", $directiveArguments);
|
||||
|
||||
[$name, $functionArguments] = $directiveArguments;
|
||||
|
||||
// Build function "uses" to inject extra external variables
|
||||
$uses = Arr::except(array_flip($directiveArguments), [$name, $functionArguments]);
|
||||
$uses = array_flip($uses);
|
||||
$uses[] = '$__env';
|
||||
$uses[] = '$__bladeCompiler';
|
||||
$uses = implode(',', $uses);
|
||||
$uses = implode(",", $uses);
|
||||
|
||||
/**
|
||||
* Slot names can`t contains dot , eg: `user.city`.
|
||||
@ -45,11 +44,11 @@ public function registerScopeDirective(): void
|
||||
*
|
||||
* Later, on component it will be replaced back.
|
||||
*/
|
||||
$name = str_replace('.', '___', $name);
|
||||
$name = str_replace(".", "___", $name);
|
||||
|
||||
return "<?php \$__bladeCompiler = \$__bladeCompiler ?? null; \$__env->slot({$name}, function({$functionArguments}) use ({$uses}) { \$loop = !empty(\$__env->getLoopStack()) ? (object) \$__env->getLoopStack()[0] : null; ?>";
|
||||
});
|
||||
|
||||
Blade::directive('endscope', fn() => '<?php }); ?>');
|
||||
Blade::directive("endscope", fn() => "<?php }); ?>");
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ public function render(): View|Closure|string
|
||||
|
||||
@if($actions)
|
||||
<th scope="col" class="px-6 py-3 w-1 whitespace-nowrap">
|
||||
<span class="sr-only">Actions</span>
|
||||
<span>Actions</span>
|
||||
</th>
|
||||
@endif
|
||||
</tr>
|
||||
@ -182,7 +182,8 @@ public function render(): View|Closure|string
|
||||
<tr
|
||||
wire:key="{{ $uuid }}-{{ $k }}"
|
||||
@class([
|
||||
'bg-white border-b',
|
||||
'bg-white',
|
||||
'border-b' => $k < $rows->count() - 1,
|
||||
$rowClasses($row),
|
||||
'even:bg-gray-50 ' => $striped,
|
||||
'hover:bg-gray-50' => !$noHover,
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
],
|
||||
"dev": [
|
||||
"Composer\\Config::disableProcessTimeout",
|
||||
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1 --timeout=0\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite --kill-others"
|
||||
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite --kill-others"
|
||||
],
|
||||
"lint": [
|
||||
"pint --parallel"
|
||||
|
||||
@ -26,36 +26,36 @@
|
||||
* is an array, it will try to convert from the first format that works,
|
||||
* and will serialize dates using the first format from the array.
|
||||
*/
|
||||
'date_format' => DATE_ATOM,
|
||||
"date_format" => DATE_ATOM,
|
||||
|
||||
/*
|
||||
* When transforming or casting dates, the following timezone will be used to
|
||||
* convert the date to the correct timezone. If set to null no timezone will
|
||||
* be passed.
|
||||
*/
|
||||
'date_timezone' => null,
|
||||
"date_timezone" => null,
|
||||
|
||||
/*
|
||||
* It is possible to enable certain features of the package, these would otherwise
|
||||
* be breaking changes, and thus they are disabled by default. In the next major
|
||||
* version of the package, these features will be enabled by default.
|
||||
*/
|
||||
'features' => [
|
||||
'cast_and_transform_iterables' => false,
|
||||
"features" => [
|
||||
"cast_and_transform_iterables" => false,
|
||||
|
||||
/*
|
||||
* When trying to set a computed property value, the package will throw an exception.
|
||||
* You can disable this behaviour by setting this option to true, which will then just
|
||||
* ignore the value being passed into the computed property and recalculate it.
|
||||
*/
|
||||
'ignore_exception_when_trying_to_set_computed_property_value' => false,
|
||||
"ignore_exception_when_trying_to_set_computed_property_value" => false,
|
||||
],
|
||||
|
||||
/*
|
||||
* Global transformers will take complex types and transform them into simple
|
||||
* types.
|
||||
*/
|
||||
'transformers' => [
|
||||
"transformers" => [
|
||||
DateTimeInterface::class => DateTimeInterfaceTransformer::class,
|
||||
Arrayable::class => ArrayableTransformer::class,
|
||||
BackedEnum::class => EnumTransformer::class,
|
||||
@ -65,7 +65,7 @@
|
||||
* Global casts will cast values into complex types when creating a data
|
||||
* object from simple types.
|
||||
*/
|
||||
'casts' => [
|
||||
"casts" => [
|
||||
DateTimeInterface::class => DateTimeInterfaceCast::class,
|
||||
BackedEnum::class => EnumCast::class,
|
||||
// Enumerable::class => Spatie\LaravelData\Casts\EnumerableCast::class,
|
||||
@ -76,7 +76,7 @@
|
||||
* validation rules to properties of a data object based upon
|
||||
* the type of the property.
|
||||
*/
|
||||
'rule_inferrers' => [
|
||||
"rule_inferrers" => [
|
||||
SometimesRuleInferrer::class,
|
||||
NullableRuleInferrer::class,
|
||||
RequiredRuleInferrer::class,
|
||||
@ -89,7 +89,7 @@
|
||||
* it cannot normalize the payload. The normalizers below are used for
|
||||
* every data object, unless overridden in a specific data object class.
|
||||
*/
|
||||
'normalizers' => [
|
||||
"normalizers" => [
|
||||
ModelNormalizer::class,
|
||||
// Spatie\LaravelData\Normalizers\FormRequestNormalizer::class,
|
||||
ArrayableNormalizer::class,
|
||||
@ -103,7 +103,7 @@
|
||||
* this key can be set globally here for all data objects. You can pass in
|
||||
* `null` if you want to disable wrapping.
|
||||
*/
|
||||
'wrap' => null,
|
||||
"wrap" => null,
|
||||
|
||||
/*
|
||||
* Adds a specific caster to the Symphony VarDumper component which hides
|
||||
@ -111,7 +111,7 @@
|
||||
* by `dump` or `dd`. Can be 'enabled', 'disabled' or 'development'
|
||||
* which will only enable the caster locally.
|
||||
*/
|
||||
'var_dumper_caster_mode' => 'development',
|
||||
"var_dumper_caster_mode" => "development",
|
||||
|
||||
/*
|
||||
* It is possible to skip the PHP reflection analysis of data objects
|
||||
@ -124,18 +124,18 @@
|
||||
* in seconds if you want the cache to clear after a certain
|
||||
* timeframe.
|
||||
*/
|
||||
'structure_caching' => [
|
||||
'enabled' => true,
|
||||
'directories' => [app_path('Data')],
|
||||
'cache' => [
|
||||
'store' => env('CACHE_STORE', env('CACHE_DRIVER', 'file')),
|
||||
'prefix' => 'laravel-data',
|
||||
'duration' => null,
|
||||
"structure_caching" => [
|
||||
"enabled" => true,
|
||||
"directories" => [app_path("Data")],
|
||||
"cache" => [
|
||||
"store" => env("CACHE_STORE", env("CACHE_DRIVER", "file")),
|
||||
"prefix" => "laravel-data",
|
||||
"duration" => null,
|
||||
],
|
||||
'reflection_discovery' => [
|
||||
'enabled' => true,
|
||||
'base_path' => base_path(),
|
||||
'root_namespace' => null,
|
||||
"reflection_discovery" => [
|
||||
"enabled" => true,
|
||||
"base_path" => base_path(),
|
||||
"root_namespace" => null,
|
||||
],
|
||||
],
|
||||
|
||||
@ -144,23 +144,23 @@
|
||||
* method. By default, only when a request is passed the data is being validated. This
|
||||
* behaviour can be changed to always validate or to completely disable validation.
|
||||
*/
|
||||
'validation_strategy' => ValidationStrategy::OnlyRequests->value,
|
||||
"validation_strategy" => ValidationStrategy::OnlyRequests->value,
|
||||
|
||||
/*
|
||||
* A data object can map the names of its properties when transforming (output) or when
|
||||
* creating (input). By default, the package will not map any names. You can set a
|
||||
* global strategy here, or override it on a specific data object.
|
||||
*/
|
||||
'name_mapping_strategy' => [
|
||||
'input' => null,
|
||||
'output' => null,
|
||||
"name_mapping_strategy" => [
|
||||
"input" => null,
|
||||
"output" => null,
|
||||
],
|
||||
|
||||
/*
|
||||
* When using an invalid include, exclude, only or except partial, the package will
|
||||
* throw an exception. You can disable this behaviour by setting this option to true.
|
||||
*/
|
||||
'ignore_invalid_partials' => false,
|
||||
"ignore_invalid_partials" => false,
|
||||
|
||||
/*
|
||||
* When transforming a nested chain of data objects, the package can end up in an infinite
|
||||
@ -168,41 +168,39 @@
|
||||
* set as a safety measure to prevent this from happening. When set to null, the
|
||||
* package will not enforce a maximum depth.
|
||||
*/
|
||||
'max_transformation_depth' => null,
|
||||
"max_transformation_depth" => null,
|
||||
|
||||
/*
|
||||
* When the maximum transformation depth is reached, the package will throw an exception.
|
||||
* You can disable this behaviour by setting this option to true which will return an
|
||||
* empty array.
|
||||
*/
|
||||
'throw_when_max_transformation_depth_reached' => true,
|
||||
"throw_when_max_transformation_depth_reached" => true,
|
||||
|
||||
/*
|
||||
* When using the `make:data` command, the package will use these settings to generate
|
||||
* the data classes. You can override these settings by passing options to the command.
|
||||
*/
|
||||
'commands' => [
|
||||
|
||||
"commands" => [
|
||||
/*
|
||||
* Provides default configuration for the `make:data` command. These settings can be overridden with options
|
||||
* passed directly to the `make:data` command for generating single Data classes, or if not set they will
|
||||
* automatically fall back to these defaults. See `php artisan make:data --help` for more information
|
||||
*/
|
||||
'make' => [
|
||||
|
||||
"make" => [
|
||||
/*
|
||||
* The default namespace for generated Data classes. This exists under the application's root namespace,
|
||||
* so the default 'Data` will end up as '\App\Data', and generated Data classes will be placed in the
|
||||
* app/Data/ folder. Data classes can live anywhere, but this is where `make:data` will put them.
|
||||
*/
|
||||
'namespace' => 'Data',
|
||||
"namespace" => "Data",
|
||||
|
||||
/*
|
||||
* This suffix will be appended to all data classes generated by make:data, so that they are less likely
|
||||
* to conflict with other related classes, controllers or models with a similar name without resorting
|
||||
* to adding an alias for the Data object. Set to a blank string (not null) to disable.
|
||||
*/
|
||||
'suffix' => 'Data',
|
||||
"suffix" => "Data",
|
||||
],
|
||||
],
|
||||
|
||||
@ -211,7 +209,7 @@
|
||||
* these synths will automatically handle the data objects and their
|
||||
* properties when used in a Livewire component.
|
||||
*/
|
||||
'livewire' => [
|
||||
'enable_synths' => false,
|
||||
"livewire" => [
|
||||
"enable_synths" => true,
|
||||
],
|
||||
];
|
||||
|
||||
45
package-lock.json
generated
45
package-lock.json
generated
@ -208,9 +208,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -227,9 +224,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -246,9 +240,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -265,9 +256,6 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -284,9 +272,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -303,9 +288,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -394,9 +376,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -528,9 +507,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -547,9 +523,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -566,9 +539,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -585,9 +555,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -1182,9 +1149,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -1205,9 +1169,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -1228,9 +1189,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -1251,9 +1209,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
||||
@ -8,7 +8,10 @@
|
||||
use App\Data\Users\UserCollection;
|
||||
use App\Data\Users\UserData;
|
||||
use App\Data\Users\UsersData;
|
||||
use App\Enums\RolesStatus;
|
||||
use Livewire\Component;
|
||||
use Spatie\LaravelData\Attributes\DataCollectionOf;
|
||||
use Spatie\LaravelData\DataCollection;
|
||||
|
||||
new class extends Component {
|
||||
/**
|
||||
@ -19,79 +22,61 @@
|
||||
* }>
|
||||
*/
|
||||
public array $header;
|
||||
public RolesData $rolesData;
|
||||
|
||||
#[DataCollectionOf(class: RoleData::class)]
|
||||
public DataCollection $roles;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->header = [
|
||||
[
|
||||
'key' => 'name',
|
||||
'label' => 'Role Name',
|
||||
"key" => "name",
|
||||
"label" => "Role Name",
|
||||
],
|
||||
[
|
||||
'key' => 'users',
|
||||
'label' => 'User Assigned',
|
||||
"key" => "users",
|
||||
"label" => "User Assigned",
|
||||
],
|
||||
[
|
||||
'key' => 'services',
|
||||
'label' => 'Services',
|
||||
"key" => "services",
|
||||
"label" => "Services",
|
||||
],
|
||||
[
|
||||
'key' => 'status',
|
||||
'label' => 'Status',
|
||||
]
|
||||
"key" => "status",
|
||||
"label" => "Status",
|
||||
],
|
||||
];
|
||||
$this->roles = RoleData::collect(
|
||||
[
|
||||
new RoleData(
|
||||
name: "Super Admin",
|
||||
|
||||
$this->rolesData = new RolesData(
|
||||
roles: new RolesCollection([
|
||||
new RoleData(
|
||||
name: 'Super Admin',
|
||||
users: new UsersData(
|
||||
users: new UserCollection([
|
||||
new UserData(
|
||||
name: 'Kushal Saha',
|
||||
email: 'kushal@example.com'
|
||||
),
|
||||
new UserData(
|
||||
name: 'Test Example',
|
||||
email: 'test@example.com'
|
||||
)
|
||||
]
|
||||
)
|
||||
),
|
||||
services: new ServiceCollection(
|
||||
users: UserData::collect(
|
||||
[
|
||||
new ServiceData(
|
||||
name: 'Teams'
|
||||
)
|
||||
]
|
||||
),
|
||||
status: \App\Enums\RolesStatus::Active
|
||||
),
|
||||
new RoleData(
|
||||
name: 'Super Admin',
|
||||
users: new UsersData(
|
||||
users: new UserCollection([
|
||||
new UserData(
|
||||
name: 'Kushal Saha',
|
||||
email: 'kushal@example.com'
|
||||
)
|
||||
]
|
||||
)
|
||||
name: "Kushal Saha",
|
||||
email: "kushal@example.com",
|
||||
),
|
||||
services: new ServiceCollection(
|
||||
new UserData(
|
||||
name: "Test Example",
|
||||
email: "test@example.com",
|
||||
),
|
||||
],
|
||||
DataCollection::class,
|
||||
),
|
||||
|
||||
services: ServiceData::collect(
|
||||
[
|
||||
new ServiceData(
|
||||
name: 'Teams'
|
||||
new ServiceData(name: "Teams"),
|
||||
new ServiceData(name: "Outlook"),
|
||||
],
|
||||
DataCollection::class,
|
||||
),
|
||||
new ServiceData(
|
||||
name: 'Outlook'
|
||||
)
|
||||
]
|
||||
|
||||
status: RolesStatus::Active,
|
||||
),
|
||||
status: \App\Enums\RolesStatus::Active
|
||||
),
|
||||
])
|
||||
],
|
||||
DataCollection::class,
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -101,34 +86,42 @@ public function mount(): void
|
||||
<div>
|
||||
<x-shared.card title="Roles" icon="lucide-shield-ellipsis" class="p-0">
|
||||
<x-slot:actions>
|
||||
<x-shared.button>
|
||||
<div class="flex items-center gap-x-2">
|
||||
<x-lucide-plus class="w-5 h-5"/>
|
||||
<x-shared.button icon="lucide-plus">
|
||||
{{ __('Add role') }}
|
||||
</div>
|
||||
</x-shared.button>
|
||||
</x-slot:actions>
|
||||
<x-table :headers="$header" :rows="$rolesData->roles">
|
||||
@scope('cell_users', $row)
|
||||
@foreach($row->users->users as $user)
|
||||
<span
|
||||
class="inline-flex items-center justify-center w-7 h-7 rounded-full bg-gray-200 text-gray-800 font-bold text-[10px] tracking-tight">
|
||||
|
||||
<x-table :headers="$header" :rows="$roles">
|
||||
@scope('cell_users', $role)
|
||||
@php /** @var RoleData $role */ @endphp
|
||||
<div class="flex -space-x-3">
|
||||
@foreach($role->users as $user)
|
||||
<x-shared.avatar>
|
||||
<span class="text-xs font-bold text-center text-blue-800">
|
||||
{{implode('', array_map(fn($w) => strtoupper($w[0]), explode(' ', $user->name)))}}
|
||||
</span>
|
||||
</x-shared.avatar>
|
||||
@endforeach
|
||||
</div>
|
||||
@endscope
|
||||
@scope('cell_status', $row)
|
||||
@scope('cell_status', $role)
|
||||
@php /** @var RoleData $role */ @endphp
|
||||
<x-shared.badge class="bg-lime-200 text-lime-800 font-bold">
|
||||
{{ ucfirst($row->status->name) }}
|
||||
{{ ucfirst($role->status->name) }}
|
||||
</x-shared.badge>
|
||||
@endscope
|
||||
@scope('cell_services', $row)
|
||||
@foreach($row->services as $service)
|
||||
@scope('cell_services', $role)
|
||||
@php /** @var RoleData $role */ @endphp
|
||||
@foreach($role->services as $service)
|
||||
<x-shared.badge class="bg-indigo-200 text-indigo-800 font-bold">
|
||||
{{$service->name}}
|
||||
</x-shared.badge>
|
||||
@endforeach
|
||||
@endscope
|
||||
|
||||
@scope('actions', $role)
|
||||
<x-shared.button icon="lucide-square-pen"/>
|
||||
@endscope
|
||||
</x-table>
|
||||
</x-shared.card>
|
||||
</div>
|
||||
|
||||
3
resources/views/components/shared/avatar.blade.php
Normal file
3
resources/views/components/shared/avatar.blade.php
Normal file
@ -0,0 +1,3 @@
|
||||
<span {{$attributes->twMerge(['class' => 'bg-blue-300 w-8 h-8 border border-white rounded-full flex items-center justify-center'])}}>
|
||||
{{$slot}}
|
||||
</span>
|
||||
@ -1,3 +1,11 @@
|
||||
<button class="rounded-lg border border-gray-300 px-6 py-2 text-gray-700">
|
||||
@props(['icon' => null])
|
||||
<button {{$attributes->twMerge(['class' => 'rounded-lg border border-gray-300 px-4 py-2 text-gray-700'])}}>
|
||||
<div class="gap-2 flex items-center">
|
||||
@if($icon)
|
||||
<span class="block">
|
||||
@svg($icon, 'w-4 h-4')
|
||||
</span>
|
||||
@endif
|
||||
{{$slot}}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
15
resources/views/components/shared/toggle.blade.php
Normal file
15
resources/views/components/shared/toggle.blade.php
Normal file
@ -0,0 +1,15 @@
|
||||
@props(['disabled' => false, 'label' => null])
|
||||
|
||||
<label class="relative inline-flex items-center cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
{{ $disabled ? 'disabled' : '' }}
|
||||
{!! $attributes->merge(['class' => 'sr-only peer']) !!}
|
||||
>
|
||||
|
||||
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
|
||||
|
||||
@if($label)
|
||||
<span class="ml-3 text-sm font-medium text-gray-900">{{ $label }}</span>
|
||||
@endif
|
||||
</label>
|
||||
Loading…
x
Reference in New Issue
Block a user