fix: 🐛 restrict user brands associated to conceptor users

This commit is contained in:
Alexis Gousseau 2025-10-07 10:12:23 +02:00
parent b36aa19028
commit aa8ac3fec5
No known key found for this signature in database
GPG key ID: 4A614CB3DBBA2406
5 changed files with 48 additions and 47 deletions

View file

@ -126,4 +126,17 @@ class UserPolicy
UserStaticRules::atLeastRole($authUser, RoleEnum::conceptor) and
UserStaticRules::atLeastRole($authUser, $user->role);
}
/**
* Determine whether the user can update associated brands to the model.
*
* @param \App\Models\User $authUser
* @param \App\Models\User $user
* @return booleanean
*/
public function changeBrands(User $authUser, User $user): bool
{
return UserStaticRules::atLeastRole($authUser, RoleEnum::conceptor) &&
$user->role->equals(RoleEnum::marketing);
}
}

View file

@ -7,7 +7,7 @@
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">
<div class="d-flex align-items-start flex-row">
<a class="btn btn-primary text-decoration-none m-0" data-bs-tooltip="tooltip" href="{{ route('bo.users.index') }}"
<a class="btn btn-primary text-decoration-none me-2" data-bs-tooltip="tooltip" href="{{ route('bo.users.index') }}"
title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.user')]) }}">
<i class="fa-solid fa-arrow-left"></i>
</a>

View file

@ -7,7 +7,7 @@
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">
<div class="d-flex align-items-start flex-row">
<a class="btn btn-primary text-decoration-none m-0" data-bs-tooltip="tooltip" href="{{ route('bo.users.index') }}"
<a class="btn btn-primary text-decoration-none me-2" data-bs-tooltip="tooltip" href="{{ route('bo.users.index') }}"
title="{{ __('crud.helpers.list_all', ['model' => Str::plural(__('models.classes.user'))]) }}">
<i class="fa-solid fa-arrow-left"></i>
</a>

View file

@ -108,35 +108,37 @@
</fieldset>
</div>
{{-- BRAND --}}
<div class="col-12 col-md-6 pb-3">
<fieldset class="h-100 border p-3" id="userRoleFieldset">
<legend>{{ str(__('models.classes.brands'))->ucfirst() }}</legend>
<div class="row">
@include('bo.partials.inputs.search-belongs-to-dropdown', [
'id' => 'questionBrand',
'label' => __(':model associées', [
'model' => str(__('models.classes.brands'))->ucfirst(),
]),
'name' => 'brand_id',
'relation' => 'brands',
'model' => $userModel,
'targetClass' => 'App\Models\Brand',
'modelListPaginate' => $brandModels ?? [],
'constructedRoute' => route('bo.brands.json-paginate'),
'fieldName' => 'name',
'multiple' => true,
'required' => true,
'disabled' => false,
'placeholder' => __('Rechercher une :model', [
'model' => str(__('models.classes.brands'))->singular(),
]),
'helper' => __('Sélectionner des :model qui seront associées parmis la liste.', [
'model' => __('models.classes.brands'),
]),
])
</div>
</fieldset>
</div>
@can('changeBrands', $userModel)
<div class="col-12 col-md-6 pb-3">
<fieldset class="h-100 border p-3">
<legend>{{ str(__('models.classes.brands'))->ucfirst() }}</legend>
<div class="row">
@include('bo.partials.inputs.search-belongs-to-dropdown', [
'id' => 'userBrand',
'label' => __(':model associées', [
'model' => str(__('models.classes.brands'))->ucfirst(),
]),
'name' => 'brand_id',
'relation' => 'brands',
'model' => $userModel,
'targetClass' => 'App\Models\Brand',
'modelListPaginate' => $brandModels ?? [],
'constructedRoute' => route('bo.brands.json-paginate'),
'fieldName' => 'name',
'multiple' => true,
'required' => true,
'disabled' => false,
'placeholder' => __('Rechercher une :model', [
'model' => str(__('models.classes.brands'))->singular(),
]),
'helper' => __('Sélectionner des :model qui seront associées parmis la liste.', [
'model' => __('models.classes.brands'),
]),
])
</div>
</fieldset>
</div>
@endcan
<div class="row">
<div class="col text-center">
<p><b>{{ __('* Champs obligatoires') }}</b></p>
@ -154,20 +156,6 @@
event.preventDefault();
submit.click();
});
// If the role is marketing, need brands associated.
const selectRole = document.getElementById('userRole');
const userRoleFieldset = document.getElementById('userRoleFieldset');
selectRole.addEventListener('change', (event) => {
updateBrandsFieldsetStatus(Number(event.target.value));
});
updateBrandsFieldsetStatus(Number("{{ $userModel->role?->value() ?? \App\Enums\Users\RoleEnum::conceptor->value() }}"));
function updateBrandsFieldsetStatus(value) {
const marketingValue = {{ \App\Enums\Users\RoleEnum::marketing->value() }};
const condition = value !== marketingValue;
userRoleFieldset.disabled = condition;
userRoleFieldset.className = `h-100 border p-3 ${condition ? 'd-none' : ''}`;
}
});
</script>
@endpush

View file

@ -22,9 +22,9 @@ Breadcrumbs::for('bo.users.edit', function (Generator $trail, User $user) {
$trail->parent('bo.users.index');
$trail->push(Str::ucfirst(trans('crud.actions.edit')), route('bo.users.edit', $user));
});
Breadcrumbs::for('bo.users.duplicate', function (Generator $trail, User $user) {
Breadcrumbs::for('bo.users.duplicate', function (Generator $trail) {
$trail->parent('bo.users.index');
$trail->push(Str::ucfirst(trans('crud.actions.duplicate')), route('bo.users.duplicate', $user));
$trail->push(Str::ucfirst(trans('crud.actions.duplicate')));
});
// * ACTIVITY_LOGS