Compare commits
4 Commits
d884ff4155
...
9d394c34f4
| Author | SHA1 | Date |
|---|---|---|
|
|
9d394c34f4 | |
|
|
04b8b26d65 | |
|
|
82c7c15068 | |
|
|
9d37a7c549 |
|
|
@ -34,10 +34,9 @@ export default class extends Controller {
|
|||
async connectToMercure() {
|
||||
try {
|
||||
// Fetch the JWT token and topic from the server
|
||||
const response = await fetch('/notifications/mercure-token');
|
||||
const response = await fetch('/mercure-token');
|
||||
const data = await response.json();
|
||||
|
||||
console.log('Mercure token data:', data);
|
||||
|
||||
// Use server-provided topic if available, otherwise fallback to default per-user topic
|
||||
const topic = data.topic || `http://portail.solutions-easy.moi/notifications/user/${this.userIdValue}`;
|
||||
|
|
@ -49,11 +48,6 @@ export default class extends Controller {
|
|||
url.searchParams.append('authorization', data.token);
|
||||
}
|
||||
|
||||
console.log('Connecting to Mercure...');
|
||||
console.log('Mercure URL:', this.mercureUrlValue);
|
||||
console.log('Topic:', topic);
|
||||
console.log('Full URL:', url.toString());
|
||||
|
||||
try {
|
||||
this.eventSource = new EventSource(url.toString());
|
||||
} catch (e) {
|
||||
|
|
@ -62,11 +56,9 @@ export default class extends Controller {
|
|||
}
|
||||
|
||||
this.eventSource.onopen = () => {
|
||||
console.log('✅ Mercure connection established successfully!');
|
||||
};
|
||||
|
||||
this.eventSource.onmessage = (event) => {
|
||||
console.log('📨 New notification received:', event.data);
|
||||
try {
|
||||
const notification = JSON.parse(event.data);
|
||||
this.handleNewNotification(notification);
|
||||
|
|
@ -76,7 +68,6 @@ export default class extends Controller {
|
|||
};
|
||||
|
||||
this.eventSource.onerror = (error) => {
|
||||
console.error('❌ Mercure connection error:', error);
|
||||
try {
|
||||
console.error('EventSource readyState:', this.eventSource.readyState);
|
||||
} catch (e) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Service\UserService;
|
||||
use Lcobucci\JWT\Configuration;
|
||||
use Lcobucci\JWT\Signer\Hmac\Sha256;
|
||||
use Lcobucci\JWT\Signer\Key\InMemory;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
class MercureController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly UserService $userService)
|
||||
{
|
||||
}
|
||||
#[Route(path: '/mercure-token', name: 'mercure_token', methods: ['GET'])]
|
||||
public function getMercureToken(): JsonResponse
|
||||
{
|
||||
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
|
||||
$user = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier());
|
||||
|
||||
$topic = sprintf('http://portail.solutions-easy.moi/notifications/user/%d', $user->getId());
|
||||
|
||||
// Generate JWT token for Mercure subscription
|
||||
$secret = $_ENV['MERCURE_JWT_SECRET'];
|
||||
|
||||
$config = Configuration::forSymmetricSigner(
|
||||
new Sha256(),
|
||||
InMemory::plainText($secret)
|
||||
);
|
||||
|
||||
$token = $config->builder()
|
||||
->withClaim('mercure', [
|
||||
'subscribe' => [$topic]
|
||||
])
|
||||
->getToken($config->signer(), $config->signingKey());
|
||||
|
||||
return new JsonResponse([
|
||||
'token' => $token->toString(),
|
||||
'topic' => $topic,
|
||||
'userId' => $user->getId(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -113,32 +113,5 @@ class NotificationController extends AbstractController
|
|||
return new JsonResponse(['success' => true]);
|
||||
}
|
||||
|
||||
#[Route(path: '/mercure-token', name: 'mercure_token', methods: ['GET'])]
|
||||
public function getMercureToken(): JsonResponse
|
||||
{
|
||||
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
|
||||
$user = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier());
|
||||
|
||||
$topic = sprintf('http://portail.solutions-easy.moi/notifications/user/%d', $user->getId());
|
||||
|
||||
// Generate JWT token for Mercure subscription
|
||||
$secret = $_ENV['MERCURE_JWT_SECRET'];
|
||||
|
||||
$config = Configuration::forSymmetricSigner(
|
||||
new Sha256(),
|
||||
InMemory::plainText($secret)
|
||||
);
|
||||
|
||||
$token = $config->builder()
|
||||
->withClaim('mercure', [
|
||||
'subscribe' => [$topic]
|
||||
])
|
||||
->getToken($config->signer(), $config->signingKey());
|
||||
|
||||
return new JsonResponse([
|
||||
'token' => $token->toString(),
|
||||
'topic' => $topic,
|
||||
'userId' => $user->getId(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,150 +57,105 @@ class UserController extends AbstractController
|
|||
{
|
||||
}
|
||||
|
||||
//TODO : REMOVE DEAD CODE due to the use of tabulator in the frontend
|
||||
|
||||
#[Route('/view/{id}', name: 'show', methods: ['GET'])]
|
||||
public function view(int $id, Request $request): Response
|
||||
{
|
||||
// Accès : uniquement utilisateur authentifié
|
||||
$this->denyAccessUnlessGranted('ROLE_USER');
|
||||
|
||||
// Utilisateur courant (acting user) via UserService
|
||||
$actingUser = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier());
|
||||
|
||||
// Vérification des droits d'accès supplémentaires
|
||||
if (!$this->userService->hasAccessTo($actingUser)) {
|
||||
throw $this->createAccessDeniedException(self::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
// Chargement de l'utilisateur cible à afficher
|
||||
$user = $this->userRepository->find($id);
|
||||
|
||||
try {
|
||||
// Paramètre optionnel de contexte organisationnel
|
||||
$orgId = $request->query->get('organizationId');
|
||||
$apps = $this->appsRepository->findAll();
|
||||
$roles = $this->rolesRepository->findAll();
|
||||
|
||||
$data = [
|
||||
'roles' => $roles,
|
||||
];
|
||||
// Liste de toutes les applications (pour créer des groupes même si vides)
|
||||
$apps = $this->appsRepository->findAll();
|
||||
|
||||
$uoList = [];
|
||||
// Initialisations pour la résolution des UsersOrganizations (UO)
|
||||
$singleUo = null;
|
||||
$uoActive = null;
|
||||
$orgs = [];
|
||||
|
||||
// get uo or uoS based on orgId
|
||||
if ($orgId) {
|
||||
// Specific organization context
|
||||
$orgs = $this->organizationRepository->findBy(['id' => $orgId]);
|
||||
// Contexte organisation précis : récupérer l'organisation et les liens UO
|
||||
$organization = $this->organizationRepository->findBy(['id' => $orgId]);
|
||||
$uoList = $this->uoRepository->findBy([
|
||||
'users' => $user,
|
||||
'organization' => $orgs,
|
||||
'users' => $user,
|
||||
'organization' => $organization,
|
||||
'isActive' => true,
|
||||
]);
|
||||
|
||||
if (!$uoList) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
|
||||
// Si contexte org donné, on retient la première UO (singleUo)
|
||||
$singleUo = $uoList[0];
|
||||
$data["singleUo"] = $singleUo;
|
||||
$uoActive = $singleUo->isActive();
|
||||
} else {
|
||||
// All active organizations
|
||||
// Pas de contexte org : récupérer toutes les UO actives de l'utilisateur
|
||||
$uoList = $this->uoRepository->findBy([
|
||||
'users' => $user,
|
||||
'isActive'=> true,
|
||||
'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;
|
||||
|
||||
// Charger les liens UserOrganizationApp (UOA) actifs pour les UO trouvées
|
||||
// Load user-organization-app roles (can be empty)
|
||||
$uoa = $this->entityManager
|
||||
->getRepository(UserOrganizatonApp::class)
|
||||
->findBy([
|
||||
'userOrganization' => $uoList,
|
||||
'isActive' => true,
|
||||
'isActive' => true,
|
||||
]);
|
||||
|
||||
// Group existing UOA per app
|
||||
$uoas = $this->userOrganizationAppService
|
||||
->groupUserOrganizationAppsByApplication($uoa);
|
||||
// Group UOA by app and ensure every app has a group
|
||||
$data['uoas'] = $this->userOrganizationAppService
|
||||
->groupUserOrganizationAppsByApplication(
|
||||
$uoa,
|
||||
$apps,
|
||||
$singleUo ? $singleUo->getId() : null
|
||||
);
|
||||
|
||||
// ---------- 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;
|
||||
//Build roles based on user permissions.
|
||||
//Admin can't see or edit a super admin user
|
||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||
$data['rolesArray'] = $this->rolesRepository->findAll();
|
||||
} elseif (!$orgId) {
|
||||
$data['rolesArray'] = $this->userService->getRolesArrayForUser($actingUser, true);
|
||||
} else {
|
||||
$data['rolesArray'] = $this->userService->getRolesArrayForUser($actingUser);
|
||||
}
|
||||
|
||||
// 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()
|
||||
);
|
||||
// Calcul du flag de modification : utilisateur admin ET exactement 1 UO
|
||||
$canEdit = $this->userService->canEditRolesCheck($actingUser, $user, $organization, $this->isGranted('ROLE_ADMIN'));
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$canEditRoles = false;
|
||||
// En cas d'erreur, désactiver l'édition et logger l'exception
|
||||
$canEdit = false;
|
||||
$this->logger->error($e->getMessage());
|
||||
}
|
||||
|
||||
return $this->render('user/show.html.twig', [
|
||||
'user' => $user,
|
||||
'uoas' => $uoas ?? null,
|
||||
'orgs' => $orgs ?? null,
|
||||
'user' => $user,
|
||||
'organizationId' => $orgId ?? null,
|
||||
'uoActive' => $uoActive ?? null,
|
||||
'apps' => $apps ?? [],
|
||||
'data' => $data ?? [],
|
||||
'canEditRoles' => $canEditRoles ?? false,
|
||||
'uoActive' => $uoActive ?? null,
|
||||
'apps' => $apps ?? [],
|
||||
'data' => $data ?? [],
|
||||
'canEdit' => $canEdit ?? false,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -510,9 +465,9 @@ class UserController extends AbstractController
|
|||
}
|
||||
|
||||
if (!empty($selectedRolesIds)) {
|
||||
if (!in_array((string)$roleUser->getId(), $selectedRolesIds, true)){
|
||||
if (!in_array((string)$roleUser->getId(), $selectedRolesIds, true)) {
|
||||
$this->userOrganizationAppService->deactivateAllUserOrganizationsAppLinks($uo, $application);
|
||||
}else{
|
||||
} else {
|
||||
$this->userOrganizationAppService->syncRolesForUserOrganizationApp(
|
||||
$uo,
|
||||
$application,
|
||||
|
|
|
|||
|
|
@ -19,18 +19,21 @@ class UserOrganizationAppService
|
|||
}
|
||||
|
||||
/**
|
||||
* Groups UserOrganizationApp entities by Application
|
||||
* and prepares data for Twig.
|
||||
* Groups UserOrganizationApp by application and ensures every app has a group (even if empty).
|
||||
*
|
||||
* @param UserOrganizatonApp[] $userOrgApps
|
||||
* @return array
|
||||
* @param array $userOrgApps Array of UserOrganizatonApp entities
|
||||
* @param array $allApps Array of all Application entities
|
||||
* @param int|null $defaultUoId The UserOrganization ID to use for apps with no UOA
|
||||
* @return array Indexed by app ID: ['uoId' => int|null, 'application' => App, 'selectedRoleIds' => int[]]
|
||||
*/
|
||||
public function groupUserOrganizationAppsByApplication(array $userOrgApps): array
|
||||
{
|
||||
public function groupUserOrganizationAppsByApplication(
|
||||
array $userOrgApps,
|
||||
array $allApps,
|
||||
?int $defaultUoId = null
|
||||
): array {
|
||||
$grouped = [];
|
||||
|
||||
foreach ($userOrgApps as $uoa) {
|
||||
|
||||
$app = $uoa->getApplication();
|
||||
$appId = $app->getId();
|
||||
$roleEntity = $uoa->getRole();
|
||||
|
|
@ -39,39 +42,27 @@ class UserOrganizationAppService
|
|||
$grouped[$appId] = [
|
||||
'uoId' => $uoa->getUserOrganization()->getId(),
|
||||
'application' => $app,
|
||||
'roles' => [],
|
||||
'rolesArray' => [],
|
||||
'selectedRoleIds' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$grouped[$appId]['roles'][] = [
|
||||
'id' => $roleEntity->getId(),
|
||||
'name' => $roleEntity->getName(),
|
||||
];
|
||||
$grouped[$appId]['selectedRoleIds'][] = $roleEntity->getId();
|
||||
}
|
||||
|
||||
// Load all possible roles once
|
||||
$allRoles = $this->entityManager->getRepository(Roles::class)->findAll();
|
||||
// Ensure every app has a group
|
||||
foreach ($allApps as $app) {
|
||||
$appId = $app->getId();
|
||||
|
||||
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')
|
||||
&& $role->getName() === 'SUPER ADMIN') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$appGroup['rolesArray'][] = [
|
||||
'id' => $role->getId(),
|
||||
'name' => $role->getName(),
|
||||
if (!isset($grouped[$appId])) {
|
||||
$grouped[$appId] = [
|
||||
'uoId' => $defaultUoId,
|
||||
'application' => $app,
|
||||
'selectedRoleIds' => [],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($grouped);
|
||||
return $grouped; // IMPORTANT: keep indexed by appId
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -261,21 +261,6 @@ class UserService
|
|||
throw new FileException('File upload failed: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// // Define upload directory
|
||||
// $uploadDirectory = $this->profileDirectory;
|
||||
// // Create directory if it doesn't exist
|
||||
// if (!is_dir($uploadDirectory) && !mkdir($uploadDirectory, 0755, true) && !is_dir($uploadDirectory)) {
|
||||
// throw new DirectoryCouldNotBeCreatedException(sprintf('Directory "%s" was not created', $uploadDirectory));
|
||||
// }
|
||||
// try {
|
||||
//
|
||||
// // Move the file to the upload directory
|
||||
// $picture->move($uploadDirectory, $customFilename);
|
||||
//
|
||||
// // Update user entity with the file path (relative to public directory)
|
||||
// $user->setPictureUrl('uploads/profile/' . $customFilename);
|
||||
//
|
||||
//
|
||||
}
|
||||
|
|
@ -471,4 +456,41 @@ class UserService
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get roles array for a user, optionally including super admin roles.
|
||||
* ViewSAdminRoles flag determines if super admin roles should be included.
|
||||
*
|
||||
* @param User $actingUser
|
||||
* @param bool $viewSAdminRoles
|
||||
* @return array
|
||||
*/
|
||||
public function getRolesArrayForUser(User $actingUser, bool $viewSAdminRoles = false): array
|
||||
{
|
||||
$roles = $this->entityManager->getRepository(Roles::class)->findAll();
|
||||
$rolesArray = [];
|
||||
foreach ($roles as $role) {
|
||||
if (!$viewSAdminRoles && $role->getName() === 'SUPER ADMIN') {
|
||||
continue;
|
||||
}
|
||||
$rolesArray[] = [
|
||||
'id' => $role->getId(),
|
||||
'name' => $role->getName(),
|
||||
];
|
||||
}
|
||||
|
||||
return $rolesArray;
|
||||
}
|
||||
|
||||
public function canEditRolesCheck(User $actingUser, User $user, $org, bool $isAdmin): bool
|
||||
{
|
||||
$userRoles = $user->getRoles();
|
||||
$actingUserRoles = $actingUser->getRoles();
|
||||
// if acting user is admin, he can´t edit super admin roles
|
||||
|
||||
if (in_array('ROLE_SUPER_ADMIN', $userRoles, true) && !in_array('ROLE_SUPER_ADMIN', $actingUserRoles, true)) {
|
||||
return false;
|
||||
}
|
||||
return $isAdmin && !empty($org);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,15 +33,9 @@
|
|||
|
||||
<div class="card border-0 no-header-bg ">
|
||||
<div class="card-header">
|
||||
{% if orgs|length >0 %}
|
||||
<div class="card-title">
|
||||
<h1>Vos applications</h1>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card-title">
|
||||
<h1>Aucune application</h1>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
|
|
@ -62,30 +56,23 @@
|
|||
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<p><b>Description
|
||||
:</b> {{ app.descriptionSmall|default('Aucune description disponible.')|raw }}
|
||||
<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 %}
|
||||
|
||||
{# find appGroup once, used in both editable and read-only branches #}
|
||||
{% set appGroup = data.uoas[app.id]|default(null) %}
|
||||
|
||||
{% if canEdit %}
|
||||
<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 %}
|
||||
{% for role in data.rolesArray %}
|
||||
<input class="form-check-input" type="checkbox"
|
||||
name="roles[]"
|
||||
value="{{ role.id }}"
|
||||
|
|
@ -100,12 +87,8 @@
|
|||
{% endif %}
|
||||
</label>
|
||||
{% endfor %}
|
||||
|
||||
{% else %}
|
||||
|
||||
<p class="text-muted">Aucun rôle défini pour cette
|
||||
application.</p>
|
||||
|
||||
<p class="text-muted">Aucun rôle défini pour cette application.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<button type="submit" name="appId" value="{{ app.id }}"
|
||||
|
|
@ -114,39 +97,30 @@
|
|||
</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 %}
|
||||
{% for role in data.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 %}>
|
||||
{% if role.id in appGroup.selectedRoleIds %}checked{% endif %}>
|
||||
<label class="form-check"
|
||||
for="role-{{ role.id }}-app-{{ app.id }}">
|
||||
{{ role.name }}
|
||||
{% 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>
|
||||
<p class="text-muted">Aucun rôle défini pour cette application.</p>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,25 @@
|
|||
{% block body %}
|
||||
<div class="card no-header-bg border-0 ">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex gap-2">
|
||||
{% if user.pictureUrl is not empty %}
|
||||
<img src="{{ aws_url ~ user.pictureUrl }}" alt="user" class="rounded-circle"
|
||||
style="width:40px; height:40px;">
|
||||
{% endif %}
|
||||
<div class="card-title ">
|
||||
<h2>{{ user.surname|capitalize }} {{ user.name|capitalize }}</h2>
|
||||
</div>
|
||||
<div class="card no-header-bg border-0 ">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex gap-2">
|
||||
{% if user.pictureUrl is not empty %}
|
||||
<img src="{{ aws_url ~ user.pictureUrl }}" alt="user" class="rounded-circle"
|
||||
style="width:40px; height:40px;">
|
||||
{% endif %}
|
||||
<div class="card-title ">
|
||||
<h2>{{ user.surname|capitalize }} {{ user.name|capitalize }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<div class="d-flex gap-2">
|
||||
{% if canEdit %}
|
||||
{% if organizationId is not null %}
|
||||
{% if uoActive %}
|
||||
<form method="post" action="{{ path('user_deactivate_organization', {'id': user.id}) }}"
|
||||
onsubmit="return confirm('Vous allez retirer l\'utilisateur de cette organisation, êtes vous sûre?');">
|
||||
<input type="hidden" name="organizationId" value="{{ organizationId }}">
|
||||
<button class="btn btn-secondary" type="submit">Désactiver l'utilisateur de l'organisation
|
||||
<button class="btn btn-secondary" type="submit">Désactiver l'utilisateur de
|
||||
l'organisation
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
|
|
@ -29,20 +31,23 @@
|
|||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
<a href="{{ path('user_edit', {'id': user.id, 'organizationId': organizationId}) }}"
|
||||
class="btn btn-primary">Modifier</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card-body ">
|
||||
<p><b>Email: </b>{{ user.email }}</p>
|
||||
<p><b>Dernière connection: </b>{{ user.lastConnection|date('d/m/Y') }}
|
||||
à {{ user.lastConnection|date('H:m:s') }} </p>
|
||||
<p><b>Compte crée le: </b>{{ user.createdAt|date('d/m/Y') }}</p>
|
||||
<p><b>Numéro de téléphone: </b>{{ user.phoneNumber ? user.phoneNumber : 'Non renseigné' }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card-body ">
|
||||
<p><b>Email: </b>{{ user.email }}</p>
|
||||
<p><b>Dernière connection: </b>{{ user.lastConnection|date('d/m/Y') }}
|
||||
à {{ user.lastConnection|date('H:m:s') }} </p>
|
||||
<p><b>Compte crée le: </b>{{ user.createdAt|date('d/m/Y') }}</p>
|
||||
<p><b>Numéro de téléphone: </b>{{ user.phoneNumber ? user.phoneNumber : 'Non renseigné' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Reference in New Issue