gestion des roles et applications
This commit is contained in:
parent
8c9a5da604
commit
7e08998005
|
|
@ -8,7 +8,9 @@ use App\Entity\User;
|
|||
use App\Entity\UserOrganizatonApp;
|
||||
use App\Entity\UsersOrganizations;
|
||||
use App\Form\UserForm;
|
||||
use App\Repository\AppsRepository;
|
||||
use App\Repository\OrganizationsRepository;
|
||||
use App\Repository\RolesRepository;
|
||||
use App\Repository\UserRepository;
|
||||
use App\Repository\UsersOrganizationsRepository;
|
||||
use App\Service\ActionService;
|
||||
|
|
@ -44,7 +46,13 @@ class UserController extends AbstractController
|
|||
private readonly UserOrganizationService $userOrganizationService,
|
||||
private readonly UserRepository $userRepository,
|
||||
private readonly UsersOrganizationsRepository $uoRepository,
|
||||
private readonly OrganizationsRepository $organizationRepository, private readonly LoggerInterface $logger, private readonly EmailService $emailService, private readonly AwsService $awsService, private readonly OrganizationsService $organizationsService,
|
||||
private readonly OrganizationsRepository $organizationRepository,
|
||||
private readonly LoggerInterface $logger,
|
||||
private readonly EmailService $emailService,
|
||||
private readonly AwsService $awsService,
|
||||
private readonly OrganizationsService $organizationsService,
|
||||
private readonly AppsRepository $appsRepository,
|
||||
private readonly RolesRepository $rolesRepository,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
|
@ -54,41 +62,148 @@ class UserController extends AbstractController
|
|||
public function view(int $id, Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_USER');
|
||||
|
||||
$actingUser = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier());
|
||||
if ($this->userService->hasAccessTo($actingUser)) {
|
||||
$user = $this->userRepository->find($id);
|
||||
try {
|
||||
$orgId = $request->query->get('organizationId');
|
||||
if ($orgId) {
|
||||
$orgs = $this->organizationRepository->findBy(['id' => $orgId]);
|
||||
$uo = $this->uoRepository->findBy(['users' => $user, 'organization' => $orgs]);
|
||||
if (!$uo) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
$uoActive = $uo[0]->isActive();
|
||||
} else {
|
||||
$uo = $this->uoRepository->findBy(['users' => $user, 'isActive' => true]);
|
||||
foreach ($uo as $u) {
|
||||
$orgs[] = $u->getOrganization();
|
||||
}
|
||||
}
|
||||
$uoa = $this->entityManager->getRepository(UserOrganizatonApp::class)->findBy(['userOrganization' => $uo, 'isActive' => true]);
|
||||
$uoas = $this->userOrganizationAppService->groupUserOrganizationAppsByApplication($uoa);
|
||||
$this->actionService->createAction("View user information", $actingUser, null, $user->getUserIdentifier());
|
||||
} catch (\Exception $e) {
|
||||
//ignore
|
||||
}
|
||||
} else {
|
||||
|
||||
if (!$this->userService->hasAccessTo($actingUser)) {
|
||||
throw $this->createAccessDeniedException(self::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
$user = $this->userRepository->find($id);
|
||||
|
||||
try {
|
||||
$orgId = $request->query->get('organizationId');
|
||||
$apps = $this->appsRepository->findAll();
|
||||
$roles = $this->rolesRepository->findAll();
|
||||
|
||||
$data = [
|
||||
'roles' => $roles,
|
||||
];
|
||||
|
||||
$uoList = [];
|
||||
$singleUo = null;
|
||||
$uoActive = null;
|
||||
$orgs = [];
|
||||
|
||||
if ($orgId) {
|
||||
// Specific organization context
|
||||
$orgs = $this->organizationRepository->findBy(['id' => $orgId]);
|
||||
$uoList = $this->uoRepository->findBy([
|
||||
'users' => $user,
|
||||
'organization' => $orgs,
|
||||
]);
|
||||
|
||||
if (!$uoList) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
|
||||
$singleUo = $uoList[0];
|
||||
$uoActive = $singleUo->isActive();
|
||||
} else {
|
||||
// All active organizations
|
||||
$uoList = $this->uoRepository->findBy([
|
||||
'users' => $user,
|
||||
'isActive'=> true,
|
||||
]);
|
||||
|
||||
foreach ($uoList as $u) {
|
||||
$orgs[] = $u->getOrganization();
|
||||
}
|
||||
|
||||
if (count($uoList) === 1) {
|
||||
$singleUo = $uoList[0];
|
||||
$uoActive = $singleUo->isActive();
|
||||
}
|
||||
}
|
||||
|
||||
$data['uoList'] = $uoList;
|
||||
$data['singleUo'] = $singleUo;
|
||||
|
||||
// Load user-organization-app roles (can be empty)
|
||||
$uoa = $this->entityManager
|
||||
->getRepository(UserOrganizatonApp::class)
|
||||
->findBy([
|
||||
'userOrganization' => $uoList,
|
||||
'isActive' => true,
|
||||
]);
|
||||
|
||||
// Group existing UOA per app
|
||||
$uoas = $this->userOrganizationAppService
|
||||
->groupUserOrganizationAppsByApplication($uoa);
|
||||
|
||||
// ---------- HERE: create empty groups for apps with no UOA ----------
|
||||
// Index existing groups by app id
|
||||
$indexedUoas = [];
|
||||
foreach ($uoas as $group) {
|
||||
$indexedUoas[$group['application']->getId()] = $group;
|
||||
}
|
||||
|
||||
// Load all possible roles once
|
||||
$allRoles = $this->entityManager->getRepository(Roles::class)->findAll();
|
||||
|
||||
foreach ($apps as $app) {
|
||||
$appId = $app->getId();
|
||||
|
||||
if (!isset($indexedUoas[$appId])) {
|
||||
// No UOA for this app yet: create an empty group
|
||||
$indexedUoas[$appId] = [
|
||||
'uoId' => $singleUo ? $singleUo->getId() : null,
|
||||
'application' => $app,
|
||||
'roles' => [],
|
||||
'rolesArray' => [],
|
||||
'selectedRoleIds' => [],
|
||||
];
|
||||
|
||||
foreach ($allRoles as $role) {
|
||||
// Same security logic: ADMIN cannot assign SUPER ADMIN
|
||||
if ($this->isGranted('ROLE_ADMIN')
|
||||
&& !$this->isGranted('ROLE_SUPER_ADMIN')
|
||||
&& $role->getName() === 'SUPER ADMIN') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$indexedUoas[$appId]['rolesArray'][] = [
|
||||
'id' => $role->getId(),
|
||||
'name' => $role->getName(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!$orgId){
|
||||
$data['singleUo'] = null;
|
||||
}
|
||||
// Overwrite $uoas to include groups for *all* apps
|
||||
$uoas = array_values($indexedUoas);
|
||||
$data['uoas'] = $uoas;
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Compute "can edit" flag: admin AND exactly one UO
|
||||
$canEditRoles = $this->isGranted('ROLE_ADMIN') && count($uoList) === 1;
|
||||
|
||||
$this->actionService->createAction(
|
||||
"View user information",
|
||||
$actingUser,
|
||||
null,
|
||||
$user->getUserIdentifier()
|
||||
);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$canEditRoles = false;
|
||||
$this->logger->error($e->getMessage());
|
||||
}
|
||||
|
||||
return $this->render('user/show.html.twig', [
|
||||
'user' => $user,
|
||||
'uoas' => $uoas ?? null,
|
||||
'orgs' => $orgs ?? null,
|
||||
'user' => $user,
|
||||
'uoas' => $uoas ?? null,
|
||||
'orgs' => $orgs ?? null,
|
||||
'organizationId' => $orgId ?? null,
|
||||
'uoActive' => $uoActive ?? null// specific for single organization context and deactivate user from said org
|
||||
'uoActive' => $uoActive ?? null,
|
||||
'apps' => $apps ?? [],
|
||||
'data' => $data ?? [],
|
||||
'canEditRoles' => $canEditRoles ?? false,
|
||||
]);
|
||||
}
|
||||
|
||||
//TODO : MONOLOG
|
||||
#[Route('/edit/{id}', name: 'edit', methods: ['GET', 'POST'])]
|
||||
public function edit(int $id, Request $request): Response
|
||||
|
|
@ -162,8 +277,8 @@ class UserController extends AbstractController
|
|||
$this->logger->notice("User added to organization " . $org->getName());
|
||||
$this->emailService->sendExistingUserNotificationEmail($existingUser, $org);
|
||||
$this->logger->notice("Existing user notification email sent to " . $existingUser->getUserIdentifier());
|
||||
$data = ['user'=>$uo->getUsers(), 'organization'=>$uo->getOrganization()];
|
||||
$this->organizationsService->notifyOrganizationAdmins($data,'USER_INVITED');
|
||||
$data = ['user' => $uo->getUsers(), 'organization' => $uo->getOrganization()];
|
||||
$this->organizationsService->notifyOrganizationAdmins($data, 'USER_INVITED');
|
||||
|
||||
return $this->redirectToRoute('organization_show', ['id' => $orgId]);
|
||||
}
|
||||
|
|
@ -195,8 +310,8 @@ class UserController extends AbstractController
|
|||
$this->logger->notice("User added to organization " . $org->getName());
|
||||
$this->emailService->sendPasswordSetupEmail($user, $orgId);
|
||||
$this->logger->notice("Password setup email sent to " . $user->getUserIdentifier());
|
||||
$data = ['user'=>$uo->getUsers(), 'organization'=>$uo->getOrganization()];
|
||||
$this->organizationsService->notifyOrganizationAdmins($data,'USER_INVITED');
|
||||
$data = ['user' => $uo->getUsers(), 'organization' => $uo->getOrganization()];
|
||||
$this->organizationsService->notifyOrganizationAdmins($data, 'USER_INVITED');
|
||||
}
|
||||
}
|
||||
$this->actionService->createAction("Create new user", $actingUser, null, $user->getUserIdentifier());
|
||||
|
|
@ -204,7 +319,7 @@ class UserController extends AbstractController
|
|||
$this->entityManager->persist($user);
|
||||
$this->entityManager->flush();
|
||||
|
||||
if( $orgId) {
|
||||
if ($orgId) {
|
||||
return $this->redirectToRoute('organization_show', ['organizationId' => $orgId]);
|
||||
}
|
||||
return $this->redirectToRoute('user_index');
|
||||
|
|
@ -217,7 +332,7 @@ class UserController extends AbstractController
|
|||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error($e->getMessage());
|
||||
if( $orgId) {
|
||||
if ($orgId) {
|
||||
return $this->redirectToRoute('organization_show', ['id' => $orgId]);
|
||||
}
|
||||
return $this->redirectToRoute('user_index');
|
||||
|
|
@ -300,7 +415,7 @@ class UserController extends AbstractController
|
|||
$this->userOrganizationAppService->deactivateAllUserOrganizationsAppLinks($uo);
|
||||
$data = ['user' => $user,
|
||||
'organization' => $org];
|
||||
$this->organizationsService->notifyOrganizationAdmins($data,"USER_DEACTIVATED");
|
||||
$this->organizationsService->notifyOrganizationAdmins($data, "USER_DEACTIVATED");
|
||||
$this->entityManager->persist($uo);
|
||||
$this->entityManager->flush();
|
||||
$this->actionService->createAction("Deactivate user in organization", $actingUser, $org, $org->getName() . " for user " . $user->getUserIdentifier());
|
||||
|
|
@ -339,13 +454,14 @@ class UserController extends AbstractController
|
|||
$this->actionService->createAction("Activate user in organization", $actingUser, $org, $org->getName() . " for user " . $user->getUserIdentifier());
|
||||
$data = ['user' => $user,
|
||||
'organization' => $org];
|
||||
$this->organizationsService->notifyOrganizationAdmins($data,"USER_ACTIVATED");
|
||||
$this->organizationsService->notifyOrganizationAdmins($data, "USER_ACTIVATED");
|
||||
|
||||
return $this->redirectToRoute('user_index');
|
||||
}
|
||||
|
||||
throw $this->createAccessDeniedException(self::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
//TODO : MONOLOG + remove picture from bucket
|
||||
#[Route('/delete/{id}', name: 'delete', methods: ['GET', 'POST'])]
|
||||
public function delete(int $id, Request $request): Response
|
||||
|
|
@ -368,7 +484,7 @@ class UserController extends AbstractController
|
|||
$this->actionService->createAction("Delete user", $actingUser, null, $user->getUserIdentifier());
|
||||
$data = ['user' => $user,
|
||||
'organization' => null];
|
||||
$this->organizationsService->notifyOrganizationAdmins($data,"USER_DELETED");
|
||||
$this->organizationsService->notifyOrganizationAdmins($data, "USER_DELETED");
|
||||
|
||||
return new Response('', Response::HTTP_NO_CONTENT); //204
|
||||
}
|
||||
|
|
@ -382,8 +498,7 @@ class UserController extends AbstractController
|
|||
|
||||
if ($this->userService->hasAccessTo($actingUser, true)) {
|
||||
$uo = $this->userOrganizationService->getByIdOrFail($id);
|
||||
|
||||
$application = $this->entityManager->getRepository(Apps::class)->find($request->get('applicationId'));
|
||||
$application = $this->entityManager->getRepository(Apps::class)->find($request->get('appId'));
|
||||
if (!$application) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
|
|
@ -395,12 +510,17 @@ class UserController extends AbstractController
|
|||
}
|
||||
|
||||
if (!empty($selectedRolesIds)) {
|
||||
$this->userOrganizationAppService->syncRolesForUserOrganizationApp(
|
||||
$uo,
|
||||
$application,
|
||||
$selectedRolesIds,
|
||||
$actingUser
|
||||
);
|
||||
if (!in_array((string)$roleUser->getId(), $selectedRolesIds, true)){
|
||||
$this->userOrganizationAppService->deactivateAllUserOrganizationsAppLinks($uo, $application);
|
||||
}else{
|
||||
$this->userOrganizationAppService->syncRolesForUserOrganizationApp(
|
||||
$uo,
|
||||
$application,
|
||||
$selectedRolesIds,
|
||||
$actingUser
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->userOrganizationAppService->deactivateAllUserOrganizationsAppLinks($uo, $application);
|
||||
}
|
||||
|
|
@ -558,7 +678,7 @@ class UserController extends AbstractController
|
|||
$picture = $this->awsService->getPublicUrl($_ENV['S3_PORTAL_BUCKET']) . $user->getPictureUrl();
|
||||
$initials = $user->getName()[0] . $user->getSurname()[0];
|
||||
return [
|
||||
'pictureUrl' =>$picture,
|
||||
'pictureUrl' => $picture,
|
||||
'email' => $user->getEmail(),
|
||||
'isConnected' => $this->userService->isUserConnected($user->getUserIdentifier()),
|
||||
'showUrl' => $this->generateUrl('user_show', ['id' => $user->getId()]),
|
||||
|
|
@ -645,10 +765,10 @@ class UserController extends AbstractController
|
|||
}
|
||||
$uo->setModifiedAt(new \DateTimeImmutable());
|
||||
try {
|
||||
$data = ['user'=>$uo->getUsers(), 'organization'=>$uo->getOrganization()];
|
||||
$data = ['user' => $uo->getUsers(), 'organization' => $uo->getOrganization()];
|
||||
$this->emailService->sendPasswordSetupEmail($user, $orgId);
|
||||
$this->logger->info("Invitation email resent to user " . $user->getUserIdentifier() . " for organization " . $org->getName());
|
||||
$this->organizationsService->notifyOrganizationAdmins($data,'USER_INVITED');
|
||||
$this->organizationsService->notifyOrganizationAdmins($data, 'USER_INVITED');
|
||||
return $this->json(['message' => 'Invitation envoyée avec success.'], Response::HTTP_OK);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error resending invitation email to user " . $user->getUserIdentifier() . " for organization " . $org->getName() . ": " . $e->getMessage());
|
||||
|
|
|
|||
|
|
@ -30,20 +30,18 @@ class UserOrganizationAppService
|
|||
$grouped = [];
|
||||
|
||||
foreach ($userOrgApps as $uoa) {
|
||||
if(!$uoa->getRole()->getName() === 'USER') {
|
||||
continue; // Skip USER role
|
||||
}
|
||||
|
||||
$app = $uoa->getApplication();
|
||||
$appId = $app->getId();
|
||||
$roleEntity = $uoa->getRole();
|
||||
|
||||
if (!isset($grouped[$appId])) {
|
||||
$grouped[$appId] = [
|
||||
'uoId' => $uoa->getUserOrganization()->getId(),
|
||||
'application' => $app,
|
||||
'roles' => [],
|
||||
'rolesArray' => [],
|
||||
'selectedRoleIds' => [],
|
||||
'uoId' => $uoa->getUserOrganization()->getId(),
|
||||
'application' => $app,
|
||||
'roles' => [],
|
||||
'rolesArray' => [],
|
||||
'selectedRoleIds' => [],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -60,14 +58,11 @@ class UserOrganizationAppService
|
|||
foreach ($grouped as &$appGroup) {
|
||||
foreach ($allRoles as $role) {
|
||||
// exclude SUPER ADMIN from assignable roles if current user is just ADMIN
|
||||
if ($this->security->isGranted('ROLE_ADMIN') && !$this->security->isGranted('ROLE_SUPER_ADMIN')
|
||||
if ($this->security->isGranted('ROLE_ADMIN')
|
||||
&& !$this->security->isGranted('ROLE_SUPER_ADMIN')
|
||||
&& $role->getName() === 'SUPER ADMIN') {
|
||||
continue;
|
||||
}
|
||||
// exclude USER role from assignable roles
|
||||
if ($role->getName() === 'USER') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$appGroup['rolesArray'][] = [
|
||||
'id' => $role->getId(),
|
||||
|
|
|
|||
|
|
@ -1,57 +1,75 @@
|
|||
{% block body %}
|
||||
{% set roles = uoa.roles %}
|
||||
{# TODO: compare style with/without border#}
|
||||
<div class="card col-6">
|
||||
<div class="card-header d-flex gap-2">
|
||||
{% if uoa.application.logoUrl %}
|
||||
<img src="{{ asset(uoa.application.logoUrl) }}" alt="Logo {{ uoa.application.name }}"
|
||||
class="rounded-circle " style="width:50px; height:50px;">
|
||||
{% endif %}
|
||||
<div class="card-title">
|
||||
<h1>{{ uoa.application.name|title }}</h1>
|
||||
</div>
|
||||
{#{% block body %}#}
|
||||
{# #}{# TODO: compare style with/without border #}
|
||||
{# <div class="card col-6">#}
|
||||
{# <div class="card-header d-flex gap-2">#}
|
||||
{# {% if app.logoMiniUrl %}#}
|
||||
{# <img src="{{ aws_url ~ app.logoMiniUrl }}" alt="Logo {{ app.name }}"#}
|
||||
{# class="rounded-circle " style="width:50px; height:50px;">#}
|
||||
{# {% endif %}#}
|
||||
{# <div class="card-title">#}
|
||||
{# <h1>{{ app.name|title }}</h1>#}
|
||||
{# </div>#}
|
||||
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
{# TODO: pb avec le |raw retour à la ligne#}
|
||||
{# maybe remove Description label #}
|
||||
<p><b> Description : </b>{{ uoa.application.descriptionSmall|default('Aucune description disponible.')|raw }}</p>
|
||||
</div>
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
{# TODO: Can be turn into an ajax function#}
|
||||
<form method="POST"
|
||||
action="{{ path('user_application_role', { id : uoa.uoId }) }}"
|
||||
data-controller="user"
|
||||
data-user-roles-array-value="{{ uoa.rolesArray|json_encode }}"
|
||||
data-user-selected-role-ids-value="{{ uoa.selectedRoleIds|json_encode }}">
|
||||
<div class="form-group mb-3">
|
||||
<label for="roles-{{ uoa.application.id }}"><b>Rôles :</b></label>
|
||||
<select data-user-target="select"
|
||||
class="choices"
|
||||
id="roles-{{ uoa.application.id }}"
|
||||
name="roles[]"
|
||||
multiple>
|
||||
</select>
|
||||
</div>
|
||||
<input hidden type="text" value="{{ uoa.application.id }}" name="applicationId">
|
||||
<button type="submit" class="btn btn-primary">Sauvegarder</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<label for="roles-{{ uoa.application.id }}"><b>Rôles :</b></label>
|
||||
<select data-user-target="select"
|
||||
class="choices"
|
||||
id="roles-{{ uoa.application.id }}"
|
||||
name="roles[]"
|
||||
data-controller="user"
|
||||
data-user-roles-array-value="{{ uoa.rolesArray|json_encode }}"
|
||||
data-user-selected-role-ids-value="{{ uoa.selectedRoleIds|json_encode }}"
|
||||
multiple
|
||||
disabled>
|
||||
</select>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{# </div>#}
|
||||
{# <div class="card-body">#}
|
||||
{# <div class="row">#}
|
||||
{# <p><b> Description : </b>{{ app.descriptionSmall|default('Aucune description disponible.')|raw }}</p>#}
|
||||
{# </div>#}
|
||||
{# {% if is_granted("ROLE_ADMIN") %}#}
|
||||
{# <form method="POST"#}
|
||||
{# action="{{ path('user_application_role', { id : data.test1 }) }}">#}
|
||||
{# <div class="form-group mb-3">#}
|
||||
{# <label for="roles-{{ app.id }}"><b>Rôles :</b></label>#}
|
||||
{# <div class="form-check">#}
|
||||
{# {% for role in roles %}#}
|
||||
{# <input class="form-check"> #}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </form>#}
|
||||
{# {% endif %}#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# #}{# <div class="card-body"> #}
|
||||
{# #}{# <div class="row"> #}
|
||||
{# #}{# TODO: pb avec le |raw retour à la ligne #}
|
||||
{# #}{# maybe remove Description label #}
|
||||
{# #}{# <p><b> Description : </b>{{ uoa.application.descriptionSmall|default('Aucune description disponible.')|raw }}</p> #}
|
||||
{# #}{# </div> #}
|
||||
{# #}{# {% if is_granted('ROLE_ADMIN') %} #}
|
||||
|
||||
{# #}{# TODO: Can be turn into an ajax function #}
|
||||
{# #}{# <form method="POST" #}
|
||||
{# #}{# action="{{ path('user_application_role', { id : uoa.uoId }) }}" #}
|
||||
{# #}{# data-controller="user" #}
|
||||
{# #}{# data-user-roles-array-value="{{ uoa.rolesArray|json_encode }}" #}
|
||||
{# #}{# data-user-selected-role-ids-value="{{ uoa.selectedRoleIds|json_encode }}"> #}
|
||||
{# #}{# <div class="form-group mb-3"> #}
|
||||
{# #}{# <label for="roles-{{ uoa.application.id }}"><b>Rôles :</b></label> #}
|
||||
{# #}{# <select data-user-target="select" #}
|
||||
{# #}{# class="choices" #}
|
||||
{# #}{# id="roles-{{ uoa.application.id }}" #}
|
||||
{# #}{# name="roles[]" #}
|
||||
{# #}{# multiple> #}
|
||||
{# #}{# </select> #}
|
||||
{# #}{# </div> #}
|
||||
{# #}{# <input hidden type="text" value="{{ uoa.application.id }}" name="applicationId"> #}
|
||||
{# #}{# <button type="submit" class="btn btn-primary">Sauvegarder</button> #}
|
||||
{# #}{# </form> #}
|
||||
{# #}{# {% else %} #}
|
||||
{# #}{# <label for="roles-{{ uoa.application.id }}"><b>Rôles :</b></label> #}
|
||||
{# #}{# <select data-user-target="select" #}
|
||||
{# #}{# class="choices" #}
|
||||
{# #}{# id="roles-{{ uoa.application.id }}" #}
|
||||
{# #}{# name="roles[]" #}
|
||||
{# #}{# data-controller="user" #}
|
||||
{# #}{# data-user-roles-array-value="{{ uoa.rolesArray|json_encode }}" #}
|
||||
{# #}{# data-user-selected-role-ids-value="{{ uoa.selectedRoleIds|json_encode }}" #}
|
||||
{# #}{# multiple #}
|
||||
{# #}{# disabled> #}
|
||||
{# #}{# </select> #}
|
||||
{# #}{# {% endif %} #}
|
||||
{# #}{# </div> #}
|
||||
{# #}{# </div> #}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
{#{% endblock %}#}
|
||||
|
|
@ -45,10 +45,112 @@
|
|||
</div>
|
||||
|
||||
<div class="d-flex gap-2 card-body">
|
||||
{% for uoa in uoas %}
|
||||
{% include 'user/application/information.html.twig' %}
|
||||
{% for app in apps %}
|
||||
<div class="card col-6">
|
||||
<div class="card-header d-flex gap-2">
|
||||
{% if app.logoMiniUrl %}
|
||||
<img src="{{ aws_url ~ app.logoMiniUrl }}" alt="Logo {{ app.name }}"
|
||||
class="rounded-circle " style="width:50px; height:50px;">
|
||||
{% endif %}
|
||||
<div class="card-title">
|
||||
<h1>{{ app.name|title }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<p><b>Description
|
||||
:</b> {{ app.descriptionSmall|default('Aucune description disponible.')|raw }}
|
||||
</p>
|
||||
</div>
|
||||
{# EDITABLE if admin and exactly one UO #}
|
||||
{% if canEditRoles and data.singleUo is not null %}
|
||||
<form method="POST"
|
||||
action="{{ path('user_application_role', { id: data.singleUo.id }) }}">
|
||||
{# for this app, find its grouped info #}
|
||||
{# Find the group for this specific app #}
|
||||
{% set appGroup = null %}
|
||||
{% for group in data.uoas|default([]) %}
|
||||
{% if group.application.id == app.id %}
|
||||
{% set appGroup = group %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="roles-{{ app.id }}"><b>Rôles :</b></label>
|
||||
<div class="form-check">
|
||||
|
||||
{% if appGroup %}
|
||||
{# Use rolesArray: filtered by current user's level (no SUPER ADMIN for plain ADMIN, etc.) #}
|
||||
{% for role in appGroup.rolesArray %}
|
||||
<input class="form-check-input" type="checkbox"
|
||||
name="roles[]"
|
||||
value="{{ role.id }}"
|
||||
id="role-{{ role.id }}-app-{{ app.id }}"
|
||||
{% if role.id in appGroup.selectedRoleIds %}checked{% endif %}>
|
||||
<label class="form-check"
|
||||
for="role-{{ role.id }}-app-{{ app.id }}">
|
||||
{% if role.name == 'USER' %}
|
||||
Accès
|
||||
{% else %}
|
||||
{{ role.name|capitalize }}
|
||||
{% endif %}
|
||||
</label>
|
||||
{% endfor %}
|
||||
|
||||
{% else %}
|
||||
|
||||
<p class="text-muted">Aucun rôle défini pour cette
|
||||
application.</p>
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
<button type="submit" name="appId" value="{{ app.id }}"
|
||||
class="btn btn-primary mt-2">
|
||||
Sauvegarder
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{# READ ONLY otherwise #}
|
||||
{% else %}
|
||||
{% set appGroup = null %}
|
||||
{% for group in data.uoas|default([]) %}
|
||||
{% if group.application.id == app.id %}
|
||||
{% set appGroup = group %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="roles-{{ app.id }}"><b>Rôles :</b></label>
|
||||
<div class="form-check">
|
||||
|
||||
{% if appGroup %}
|
||||
{# Use rolesArray: filtered by current user's level (no SUPER ADMIN for plain ADMIN, etc.) #}
|
||||
{% for role in appGroup.rolesArray %}
|
||||
<input class="form-check-input" type="checkbox"
|
||||
disabled
|
||||
name="roles[]"
|
||||
value="{{ role.id }}"
|
||||
id="role-{{ role.id }}-app-{{ app.id }}"
|
||||
{% if appGroup and role.id in appGroup.selectedRoleIds %}checked{% endif %}>
|
||||
<label class="form-check"
|
||||
for="role-{{ role.id }}-app-{{ app.id }}">
|
||||
{{ role.name }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p class="text-muted">Aucun rôle défini pour cette
|
||||
application.</p>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -59,7 +161,7 @@
|
|||
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
{% block title %}
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue