Compare commits

...

10 Commits

Author SHA1 Message Date
Charles 307e615fb3 redirect on login 2025-09-05 11:08:27 +02:00
Charles 20bc6e92bc Display roles for user only 2025-09-05 10:34:09 +02:00
Charles 1788ec9062 Manage roles in application 2025-09-05 10:01:59 +02:00
Charles 3ef774d7e0 Refactor 2025-09-04 15:15:37 +02:00
Charles dc5eb702a3 Index des applications 2025-09-04 14:59:17 +02:00
Charles 346d89f42e Refactor 2025-09-04 12:24:01 +02:00
Charles ec29f42f90 Redirect to Organization Dashboard 2025-09-04 11:43:42 +02:00
Charles c75eda74a3 Display logic updated 2025-09-04 11:38:25 +02:00
Charles 633c255598 Add organization status 2025-09-04 10:18:40 +02:00
Charles 5e52386233 activate/deactivate organizations 2025-09-04 10:17:24 +02:00
20 changed files with 437 additions and 137 deletions

View File

@ -9,6 +9,7 @@ import 'bootstrap/dist/css/bootstrap.min.css';
import './styles/app.css'; import './styles/app.css';
import './styles/navbar.css'; import './styles/navbar.css';
import './styles/sidebar.css'; import './styles/sidebar.css';
import './styles/choices.css'
import 'bootstrap'; import 'bootstrap';
import './js/template.js'; import './js/template.js';

View File

@ -1,77 +1,32 @@
import {Controller} from '@hotwired/stimulus'; import { Controller } from '@hotwired/stimulus';
import Choices from 'choices.js'; import Choices from 'choices.js';
/*
* The following line makes this controller "lazy": it won't be downloaded until needed
* See https://symfony.com/bundles/StimulusBundle/current/index.html#lazy-stimulus-controllers
*/
/* stimulusFetch: 'lazy' */
export default class extends Controller { export default class extends Controller {
static values = { static values = {
rolesArray: Array, rolesArray: Array,
selectedRoleIds: Array, selectedRoleIds: Array,
applicationsArray: Array,
selectedApplicationIds: Array
} }
// {value: 'choice1', label: 'Choice 1'},
// {value: 'choice2', label: 'Choice 2'}, static targets = ["select"];
// {value: 'choice3', label: 'Choice 3'},
connect() {
this.roleSelect();
}
roleSelect() { roleSelect() {
const element = document.getElementById('roles'); if (this.hasSelectTarget) {
if (element) {
const choicesData = this.rolesArrayValue.map(role => ({ const choicesData = this.rolesArrayValue.map(role => ({
value: role.id, value: role.id,
label: role.name, label: role.name,
selected: this.selectedRoleIdsValue.includes(role.id) selected: this.selectedRoleIdsValue.includes(role.id)
})); }));
const choices = new Choices(element, { new Choices(this.selectTarget, {
choices: choicesData, choices: choicesData,
removeItemButton: true, removeItemButton: true,
placeholder: true, placeholder: true,
placeholderValue: 'Ajouter un ou plusieurs rôles' placeholderValue: 'Ajouter un ou plusieurs rôles',
}); });
} }
} }
appSelect() {
const element = document.getElementById('applications');
if (element) {
const choicesData = this.applicationsArrayValue.map(app => ({
value: app.id,
label: app.name,
customProperties: {icon: app.icon},
selected: this.selectedApplicationIdsValue.includes(app.id)
}));
const choices = new Choices(element, {
choices: choicesData,
removeItemButton: true,
placeholder: true,
placeholderValue: 'Ajouter une ou plusieurs applications',
});
}
}
connect() {
this.roleSelect();
this.appSelect();
// Set choices after initialization
// choices.setValue(choicesData);
}
// Add custom controller actions here
// fooBar() { this.fooTarget.classList.toggle(this.bazClass) }
disconnect() {
// Called anytime its element is disconnected from the DOM
// (on page change, when it's removed from or moved in the DOM, etc.)
// Here you should remove all event listeners added in "connect()"
// this.fooTarget.removeEventListener('click', this._fooBar)
}
} }

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M11 17h2l.3-1.5q.3-.125.563-.262t.537-.338l1.45.45l1-1.7l-1.15-1q.05-.35.05-.65t-.05-.65l1.15-1l-1-1.7l-1.45.45q-.275-.2-.537-.338T13.3 8.5L13 7h-2l-.3 1.5q-.3.125-.562.263T9.6 9.1l-1.45-.45l-1 1.7l1.15 1q-.05.35-.05.65t.05.65l-1.15 1l1 1.7l1.45-.45q.275.2.538.338t.562.262zm1-3q-.825 0-1.412-.587T10 12t.588-1.412T12 10t1.413.588T14 12t-.587 1.413T12 14m-7 7q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h14q.825 0 1.413.588T21 5v14q0 .825-.587 1.413T19 21zm0-2h14V5H5zM5 5v14z"/></svg>

After

Width:  |  Height:  |  Size: 577 B

View File

@ -129,3 +129,7 @@ body {
color : #FFFFFF; color : #FFFFFF;
border: var(--secondary); border: var(--secondary);
} }
.btn-warning{
border-radius: 1rem;
}

63
assets/styles/choices.css Normal file
View File

@ -0,0 +1,63 @@
.choices {
font-size: 0.9rem;
width: 100%;
}
/* Input style */
.choices__inner {
background: #fff;
border: 1px solid var(--primary-blue-light);
border-radius: 0.375rem; /* same as Bootstrap `.form-control` */
padding: 0.5rem;
min-height: 2.5rem;
box-shadow: none;
cursor: text;
}
/* Placeholder */
.choices__placeholder {
color: #6c757d; /* Bootstrap muted */
opacity: 0.9;
}
/* Selected items (tags) */
.choices__list--multiple .choices__item {
background-color: var(--primary-blue-light) !important;
color: #fff;
border: none;
border-radius: 0.25rem;
padding: 0.25rem 0.5rem;
margin: 0.15rem;
font-size: 0.85rem;
}
/* Remove "x" button */
.choices__list--multiple .choices__item .choices__button {
border-left: 1px solid rgba(255,255,255,0.3);
margin-left: 0.25rem;
color: #fff;
opacity: 0.9;
}
.choices__list--multiple .choices__item .choices__button:hover {
opacity: 1;
}
/* Dropdown list */
.choices__list--dropdown {
border: 1px solid var(--primary-blue-light);
border-radius: 0.25rem;
box-shadow: 0 3px 6px rgba(0,0,0,0.1);
margin-top: 0.2rem;
}
/* Dropdown options */
.choices__list--dropdown .choices__item {
padding: 0.5rem;
font-size: 0.9rem;
}
/* Hover/active in dropdown */
.choices__list--dropdown .choices__item--highlighted {
background-color: var(--primary-blue-light);
color: #fff;
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Controller;
use App\Entity\Apps;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
#[Route(path: '/application', name: 'application_')]
class ApplicationController extends AbstractController
{
public function __construct(private readonly EntityManagerInterface $entityManager)
{
}
#[Route(path: '/', name: 'index', methods: ['GET'])]
public function index(): Response
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$applications = $this->entityManager->getRepository(Apps::class)->findAll();
return $this->render('application/index.html.twig', [
'applications' => $applications,
]);
}
}

View File

@ -12,8 +12,15 @@ use Symfony\Component\Routing\Attribute\Route;
final class IndexController extends AbstractController final class IndexController extends AbstractController
{ {
#[Route('/', name: 'app_index')] #[Route('/', name: 'app_index')]
public function index(Request $request, LoggerInterface $logger): Response public function index(): Response
{ {
if ($this->isGranted('ROLE_ADMIN')) {
return $this->redirectToRoute('organization_index');
}
if($this->isGranted('ROLE_USER')) {
return $this->redirectToRoute('application_index');
}
return $this->render('index/index.html.twig', [ return $this->render('index/index.html.twig', [
'controller_name' => 'IndexController', 'controller_name' => 'IndexController',
]); ]);

View File

@ -52,6 +52,9 @@ class OrganizationController extends AbstractController
$organizations[] = $uo->getOrganization(); $organizations[] = $uo->getOrganization();
} }
} }
if(count($organizations) === 1 && $organizations[0]->isActive() === true){
return $this->redirectToRoute('organization_show', ['id' => $organizations[0]->getId()]);
}
} }
@ -177,6 +180,8 @@ class OrganizationController extends AbstractController
$actions = $this->entityManager->getRepository(Actions::class)->findBy(['Organization' => $organization]); $actions = $this->entityManager->getRepository(Actions::class)->findBy(['Organization' => $organization]);
$activities = $this->actionService->formatActivities($actions); $activities = $this->actionService->formatActivities($actions);
$this->actionService->createAction("View Organization", $actingUser, $organization, $organization->getName());
return $this->render('organization/show.html.twig', [ return $this->render('organization/show.html.twig', [
'organization' => $organization, 'organization' => $organization,
'newUsers' => $newUsers, 'newUsers' => $newUsers,
@ -206,5 +211,34 @@ class OrganizationController extends AbstractController
return $this->redirectToRoute('organization_index'); return $this->redirectToRoute('organization_index');
} }
#[Route(path: '/deactivate/{id}', name: 'deactivate', methods: ['POST'])]
public function deactivate($id){
$this->denyAccessUnlessGranted("ROLE_SUPER_ADMIN");
$actingUser = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier());
$organization = $this->entityManager->getRepository(Organizations::class)->find($id);
if (!$organization) {
throw $this->createNotFoundException(self::NOT_FOUND);
}
$organization->setIsActive(false);
$this->userOrganizationService->deactivateAllUserOrganizationLinks($actingUser, null, $organization);
$this->entityManager->persist($organization);
$this->actionService->createAction("Deactivate Organization", $actingUser, $organization, $organization->getName());
return $this->redirectToRoute('organization_index');
}
#[Route(path: '/activate/{id}', name: 'activate', methods: ['POST'])]
public function activate($id){
$this->denyAccessUnlessGranted("ROLE_SUPER_ADMIN");
$actingUser = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier());
$organization = $this->entityManager->getRepository(Organizations::class)->find($id);
if (!$organization) {
throw $this->createNotFoundException(self::NOT_FOUND);
}
$organization->setIsActive(true);
$this->entityManager->persist($organization);
$this->actionService->createAction("Activate Organization", $actingUser, $organization, $organization->getName());
return $this->redirectToRoute('organization_index');
}
} }

View File

@ -2,7 +2,9 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Apps;
use App\Entity\Organizations; use App\Entity\Organizations;
use App\Entity\Roles;
use App\Entity\User; use App\Entity\User;
use App\Entity\UserOrganizatonApp; use App\Entity\UserOrganizatonApp;
use App\Entity\UsersOrganizations; use App\Entity\UsersOrganizations;
@ -91,7 +93,7 @@ class UserController extends AbstractController
} }
} }
$uoa = $this->entityManager->getRepository(UserOrganizatonApp::class)->findBy(['userOrganization' => $uo, 'isActive' => true]); $uoa = $this->entityManager->getRepository(UserOrganizatonApp::class)->findBy(['userOrganization' => $uo, 'isActive' => true]);
$uoa = $this->userOrganizationAppService->groupUserOrganizationAppsByApplication($uoa); $uoas = $this->userOrganizationAppService->groupUserOrganizationAppsByApplication($uoa);
$this->actionService->createAction("View user information", $actingUser, null, $user->getUserIdentifier()); $this->actionService->createAction("View user information", $actingUser, null, $user->getUserIdentifier());
} catch (\Exception $e) { } catch (\Exception $e) {
//ignore //ignore
@ -99,10 +101,9 @@ class UserController extends AbstractController
} else { } else {
throw $this->createAccessDeniedException(self::ACCESS_DENIED); throw $this->createAccessDeniedException(self::ACCESS_DENIED);
} }
return $this->render('user/show.html.twig', [ return $this->render('user/show.html.twig', [
'user' => $user, 'user' => $user,
'uoas' => $uoa ?? null, 'uoas' => $uoas ?? null,
'orgs' => $orgs ?? null, 'orgs' => $orgs ?? null,
'organizationId' => $orgId ?? null, 'organizationId' => $orgId ?? null,
'uoActive' => $uoActive ?? null// specific for single organization context and deactivate user from said org 'uoActive' => $uoActive ?? null// specific for single organization context and deactivate user from said org
@ -332,4 +333,46 @@ class UserController extends AbstractController
$this->actionService->createAction("Delete user", $actingUser, null, $user->getUserIdentifier()); $this->actionService->createAction("Delete user", $actingUser, null, $user->getUserIdentifier());
return $this->redirectToRoute('user_index'); return $this->redirectToRoute('user_index');
} }
#[Route(path: '/application/roles/{id}', name: 'application_role', methods: ['GET', 'POST'])]
public function applicationRole(int $id, Request $request): Response
{
$this->denyAccessUnlessGranted("ROLE_ADMIN");
$actingUser = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier());
if ($this->userService->hasAccessTo($actingUser, true)) {
$uo = $this->userOrganizationService->getByIdOrFail($id);
$application = $this->entityManager->getRepository(Apps::class)->find($request->get('applicationId'));
if (!$application) {
throw $this->createNotFoundException(self::NOT_FOUND);
}
$selectedRolesIds = $request->get('roles', []);
$roleUser = $this->entityManager->getRepository(Roles::class)->findOneBy(['name' => 'USER']);
if (!$roleUser) {
throw $this->createNotFoundException('Default role not found');
}
if (in_array($roleUser->getId(), $selectedRolesIds)) {
$this->userOrganizationAppService->syncRolesForUserOrganizationApp(
$uo,
$application,
$selectedRolesIds,
$actingUser
);
} else {
$this->userOrganizationAppService->deactivateAllUserOrganizationsAppLinks($uo, $application);
}
$user = $uo->getUsers();
return $this->redirectToRoute('user_show', [
'user' => $user,
'id' => $user->getId(),
'organizationId'=> $uo->getOrganization()->getId()
]);
}
throw $this->createAccessDeniedException();
}
} }

View File

@ -2,6 +2,9 @@
namespace App\Service; namespace App\Service;
use App\Entity\Apps;
use App\Entity\Roles;
use App\Entity\User;
use App\Entity\UserOrganizatonApp; use App\Entity\UserOrganizatonApp;
use App\Entity\UsersOrganizations; use App\Entity\UsersOrganizations;
use App\Service\ActionService; use App\Service\ActionService;
@ -14,7 +17,8 @@ class UserOrganizationAppService
} }
/** /**
* Groups UserOrganizationApp entities by their associated Application. * Groups UserOrganizationApp entities by Application
* and prepares data for Twig.
* *
* @param UserOrganizatonApp[] $userOrgApps * @param UserOrganizatonApp[] $userOrgApps
* @return array * @return array
@ -30,19 +34,33 @@ class UserOrganizationAppService
if (!isset($grouped[$appId])) { if (!isset($grouped[$appId])) {
$grouped[$appId] = [ $grouped[$appId] = [
'userOrganization'=> $uoa->getUserOrganization(), 'uoId' => $uoa->getUserOrganization()->getId(),
'application' => $app, 'application' => $app, // you can still pass entity here
'roles' => [], 'roles' => [], // selected roles for display
'rolesArray' => [], // all possible roles
'selectedRoleIds' => [],
]; ];
} }
$grouped[$appId]['roles'][] = [ $grouped[$appId]['roles'][] = [
'id' => $roleEntity->getId(), 'id' => $roleEntity->getId(),
'name' => $roleEntity->getName(), // adjust to your Role entity fields 'name' => $roleEntity->getName(),
]; ];
$grouped[$appId]['selectedRoleIds'][] = $roleEntity->getId();
}
// roles are the same for all apps → load once, inject into each appGroup
$allRoles = $this->entityManager->getRepository(Roles::class)->findAll();
foreach ($grouped as &$appGroup) {
foreach ($allRoles as $role) {
$appGroup['rolesArray'][] = [
'id' => $role->getId(),
'name' => $role->getName(),
];
}
} }
// if you want a simple indexed array instead of associative keyed by appId
return array_values($grouped); return array_values($grouped);
} }
@ -52,9 +70,13 @@ class UserOrganizationAppService
* @param UsersOrganizations $userOrganization * @param UsersOrganizations $userOrganization
* @return void * @return void
*/ */
public function deactivateAllUserOrganizationsAppLinks(UsersOrganizations $userOrganization): void public function deactivateAllUserOrganizationsAppLinks(UsersOrganizations $userOrganization, Apps $app = null): void
{ {
$uoas = $this->entityManager->getRepository(UserOrganizatonApp::class)->findBy(['userOrganization' => $userOrganization, 'isActive' => true]); if($app) {
$uoas = $this->entityManager->getRepository(UserOrganizatonApp::class)->findBy(['userOrganization' => $userOrganization, 'application' => $app, 'isActive' => true]);
} else {
$uoas = $this->entityManager->getRepository(UserOrganizatonApp::class)->findBy(['userOrganization' => $userOrganization, 'isActive' => true]);
}
foreach ($uoas as $uoa) { foreach ($uoas as $uoa) {
$uoa->setIsActive(false); $uoa->setIsActive(false);
$this->actionService->createAction("Deactivate UOA link", $userOrganization->getUsers(), $this->actionService->createAction("Deactivate UOA link", $userOrganization->getUsers(),
@ -62,4 +84,71 @@ class UserOrganizationAppService
$this->entityManager->persist($uoa); $this->entityManager->persist($uoa);
} }
} }
public function syncRolesForUserOrganizationApp(
UsersOrganizations $uo,
Apps $application,
array $selectedRoleIds,
User $actingUser
): void {
$repo = $this->entityManager->getRepository(UserOrganizatonApp::class);
$currentLinks = $repo->findBy([
'userOrganization' => $uo,
'application' => $application,
]);
$currentRoleIds = [];
foreach ($currentLinks as $uoa) {
$roleId = $uoa->getRole()->getId();
$currentRoleIds[] = $roleId;
if (in_array($roleId, $selectedRoleIds)) {
if (!$uoa->isActive()) {
$uoa->setIsActive(true);
$this->entityManager->persist($uoa);
$this->actionService->createAction(
"Re-activate user role for application",
$actingUser,
$uo->getOrganization(),
"App: {$application->getName()}, Role: {$uoa->getRole()->getName()} for user {$uo->getUsers()->getUserIdentifier()}"
);
}
} else {
if ($uoa->isActive()) {
$uoa->setIsActive(false);
$this->entityManager->persist($uoa);
$this->actionService->createAction(
"Deactivate user role for application",
$actingUser,
$uo->getOrganization(),
"App: {$application->getName()}, Role: {$uoa->getRole()->getName()} for user {$uo->getUsers()->getUserIdentifier()}"
);
}
}
}
// Add missing roles
foreach ($selectedRoleIds as $roleId) {
if (!in_array($roleId, $currentRoleIds)) {
$role = $this->entityManager->getRepository(Roles::class)->find($roleId);
if ($role) {
$newUoa = new UserOrganizatonApp();
$newUoa->setUserOrganization($uo);
$newUoa->setApplication($application);
$newUoa->setRole($role);
$newUoa->setIsActive(true);
$this->entityManager->persist($newUoa);
$this->actionService->createAction("New user role for application",
$actingUser,
$uo->getOrganization(),
"App: {$application->getName()}, Role: {$role->getName()} for user {$uo->getUsers()->getUserIdentifier()}");
}
}
}
$this->entityManager->flush();
}
} }

View File

@ -9,6 +9,7 @@ use App\Entity\UsersOrganizations;
use App\Service\ActionService; use App\Service\ActionService;
use \App\Service\UserOrganizationAppService; use \App\Service\UserOrganizationAppService;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/** /**
* Service pour la gestion des organisations d'utilisateurs. * Service pour la gestion des organisations d'utilisateurs.
@ -43,5 +44,14 @@ readonly class UserOrganizationService
} }
} }
public function getByIdOrFail(int $id): UsersOrganizations
{
$uo = $this->entityManager->getRepository(UsersOrganizations::class)->find($id);
if (!$uo) {
throw new NotFoundHttpException("UserOrganization not found");
}
return $uo;
}
} }

View File

@ -0,0 +1,19 @@
{% block body %}
<div class="card">
<div class="card-header">
<div class="card-title">
<h3><img width=10% src="{{ asset(application.logoUrl) }}" alt="Logo {{ application.title }}">
{{ application.name }}</h3>
</div>
</div>
<div class="card-body d-flex flex-column align-items-center">
<p class="card-text">{{ application.description }}</p>
<div>
<a href="http://{{ application.subDomain }}.solutions-easy.moi" class="btn btn-primary me-2">Accéder à l'application</a>
</div>
</div>
</div>
{% endblock %}

View File

@ -16,7 +16,8 @@
<a href="#" class="btn btn-secondary">Gérer l'application</a> <a href="#" class="btn btn-secondary">Gérer l'application</a>
</div> </div>
{% else %}<a href="#" class="btn btn-primary">Demander l'accès</a> {% else %}
<a href="#" class="btn btn-primary">Demander l'accès</a>
{#TODO: page d'accès#} {#TODO: page d'accès#}
{% endif %} {% endif %}
</div> </div>

View File

@ -0,0 +1,23 @@
{% extends 'base.html.twig' %}
{% block title %}
Suite Easy
{% endblock %}
{% block body %}
<div class="row m-5">
<div class="container mt-5">
<h1 class="mb-4">Bienvenue sur la suite Easy</h1>
<p class="lead">Ici, vous pouvez trouver toutes nos applications à un seul endroit!</p>
</div>
{% for application in applications %}
<div class="col-6 mb-3">
{% include 'application/InformationCard.html.twig' with {
application: application
} %}
</div>
{% endfor %}
</div>
{% endblock %}

View File

@ -28,24 +28,31 @@
</ul> </ul>
</div> </div>
</li> </li>
<li class="nav-item">
<a class="nav-link" href="{{ path('application_index') }}">
<i class="icon-grid menu-icon">{{ ux_icon('material-symbols:settings-applications-outline', {height: '15px', width: '15px'}) }}</i>
<span class="menu-title">Applications</span>
</a>
</li>
{# if user is Super Admin #} {# if user is Super Admin #}
{% if is_granted('ROLE_ADMIN') %} {% if is_granted('ROLE_SUPER_ADMIN') %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{{ path('user_index') }}"> <a class="nav-link" href="{{ path('user_index') }}">
<i class="icon-grid menu-icon">{{ ux_icon('fa6-regular:circle-user', {height: '15px', width: '15px'}) }}</i> <i class="icon-grid menu-icon">{{ ux_icon('fa6-regular:circle-user', {height: '15px', width: '15px'}) }}</i>
<span class="menu-title">Users</span> <span class="menu-title">Users</span>
</a> </a>
</li> </li>
<li class="nav-item">
{% if is_granted('ROLE_ADMIN') %}
<a class="nav-link" href="{{ path('organization_index') }}">
<i class="icon-grid menu-icon"> {{ ux_icon('bi:buildings', {height: '15px', width: '15px'}) }}
</i>
<span class="menu-title">
Organizations</span>
</a>
{% endif %}
</li>
{% endif %} {% endif %}
<li class="nav-item">
{% if is_granted('ROLE_ADMIN') %}
<a class="nav-link" href="{{ path('organization_index') }}">
<i class="icon-grid menu-icon"> {{ ux_icon('bi:buildings', {height: '15px', width: '15px'}) }}
</i>
<span class="menu-title">
Organizations</span>
</a>
{% endif %}
</li>
</ul> </ul>
</nav> </nav>

View File

@ -25,6 +25,7 @@
<th>Nom</th> <th>Nom</th>
<th>Email</th> <th>Email</th>
<th>Visualiser</th> <th>Visualiser</th>
<th>Status</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -38,6 +39,13 @@
</td> </td>
<td>{{ organization.name }}</td> <td>{{ organization.name }}</td>
<td>{{ organization.email }}</td> <td>{{ organization.email }}</td>
<td>
{% if organization.active %}
<span class="badge bg-success">Active</span>
{% else %}
<span class="badge bg-danger">Inactive</span>
{% endif %}
</td>
<td> <td>
<a href="{{ path('organization_show', {'id': organization.id}) }}" <a href="{{ path('organization_show', {'id': organization.id}) }}"
class="p-3 align-middle color-primary"> class="p-3 align-middle color-primary">

View File

@ -18,13 +18,20 @@
onsubmit="return confirm('Vous allez supprimer cette organisation, êtes vous sûre?');" onsubmit="return confirm('Vous allez supprimer cette organisation, êtes vous sûre?');"
style="display: inline-block;"> style="display: inline-block;">
<button class="btn btn-danger" type="submit">Supprimer l'organisation</button> <button class="btn btn-danger" type="submit">Supprimer l'organisation</button>
{# {% if organization.active %}#} </form>
{# <a href="{{ path('organization_deactivate', {'id': organization.id}) }}"#} {% if organization.active %}
{# class="btn btn-danger">Désactiver l'organisation</a>#} <form method="POST" action="{{ path('organization_deactivate', {'id': organization.id}) }}"
{# {% else %}#} onsubmit="return confirm('Vous allez désactiver cette organisation, êtes vous sûre?');"
{# <a href="{{ path('organization_activate', {'id': organization.id}) }}"#} style="display: inline-block;">
{# class="btn btn-success">Activer l'organisation</a>#} <button class="btn btn-warning" type="submit">Désactiver l'organisation</button>
{# {% endif %}#} </form>
{% else %}
<form method="POST" action="{{ path('organization_activate', {'id': organization.id}) }}"
onsubmit="return confirm('Vous allez re-activer cette organisation, êtes vous sûre?');"
style="display: inline-block;">
<button class="btn btn-primary" type="submit">Activer l'organisation</button>
</form>
{% endif %}
{% elseif is_granted("ROLE_ADMIN") %} {% elseif is_granted("ROLE_ADMIN") %}
<a href="{{ path('organization_edit', {'id': organization.id}) }}" class="btn btn-primary">Gérer mon <a href="{{ path('organization_edit', {'id': organization.id}) }}" class="btn btn-primary">Gérer mon
organisation</a> organisation</a>
@ -52,18 +59,18 @@
} %} } %}
</div> </div>
</div> </div>
{# <div class="m-auto">#} {# <div class="m-auto"> #}
{% include 'user/userList.html.twig' with { {% include 'user/userList.html.twig' with {
title: 'Mes utilisateurs', title: 'Mes utilisateurs',
organizationId: organization.id, organizationId: organization.id,
empty_message: 'Aucun utilisateurs trouvé.' empty_message: 'Aucun utilisateurs trouvé.'
} %} } %}
{# </div>#} {# </div> #}
{# APPLICATION ROW #} {# APPLICATION ROW #}
<div class="row "> <div class="row ">
{% for application in applications %} {% for application in applications %}
<div class="col-6 mb-3"> <div class="col-6 mb-3">
{% include 'applications/appSmall.html.twig' with { {% include 'application/appSmall.html.twig' with {
application: application application: application
} %} } %}
</div> </div>

View File

@ -14,41 +14,42 @@
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<p><b> Description : </b>{{ uoa.application.description|default('Aucune description disponible.') }}</p> <p><b> Description : </b>{{ uoa.application.description|default('Aucune description disponible.') }}</p>
{% if roles|length is not null %}
<div class="col">
<p><b>Rôles :</b>
{% for role in roles %}
{% if role.name == "SUPER ADMIN" %}
<span class="badge bg-danger">{{ role.name|capitalize }}</span>
{% elseif role.name == "ADMIN" %}
<span class="badge bg-danger">{{ role.name|capitalize }}</span>
{% else %}
<span class="badge bg-primary">{{ role.name|capitalize }}</span>
{% endif %}
{% if not loop.last %} - {% endif %}
{% else %}
<p>Aucun rôle attribué.</p>
{% endfor %}
</p>
</div>
{% endif %}
</div> </div>
{# {% if is_granted('ROLE_ADMIN') %} #} {% if is_granted('ROLE_ADMIN') %}
{# <form method="POST" action="{{ path('user_organization_edit', {'id' : uo.uoId}) }}" #} <form method="POST"
{# data-controller="user" #} action="{{ path('user_application_role', { id : uoa.uoId }) }}"
{# data-user-roles-array-value="{{ rolesArray|json_encode }}" #} onsubmit="return confirm('Attention, si le role utilisateur ' +
{# data-user-selected-role-ids-value="{{ selectedRoleIds|json_encode }}"> #} 'n\'est pas attribué, l\'utilisateur ne pourra plus accéder à l\'application. Êtes-vous sûr ?');"
{# <div class="form-group mb-3"> #} data-controller="user"
{# <label for="roles">Roles</label> #} data-user-roles-array-value="{{ uoa.rolesArray|json_encode }}"
{# <select class="choices" data-type="select-multiple" id="roles" name="roles[]" multiple> #} data-user-selected-role-ids-value="{{ uoa.selectedRoleIds|json_encode }}">
{# </select> #} <div class="form-group mb-3">
{# </div> #} <label for="roles-{{ uoa.application.id }}"><b>Rôles :</b></label>
{# <button type="submit" class="btn btn-primary">Sauvegarder</button> #} <select data-user-target="select"
{# </form> #} class="choices"
{# {% endif %} #} 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>
{% endblock %} {% endblock %}

View File

@ -14,9 +14,9 @@
{% if user.active %} {% if user.active %}
<a href="{{ path('user_deactivate', {'id': user.id}) }}" <a href="{{ path('user_deactivate', {'id': user.id}) }}"
class="btn btn-danger">Désactiver</a> class="btn btn-danger">Désactiver l'utilisateur</a>
{% else %} {% else %}
<a href="{{ path('user_activate', {'id': user.id}) }}" class="btn btn-success">Activer</a> <a href="{{ path('user_activate', {'id': user.id}) }}" class="btn btn-success">Activer l'utilisateur</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>
@ -24,13 +24,10 @@
</div> </div>
{% endif %} {% endif %}
{% include 'user/userInformation.html.twig' %} {% include 'user/userInformation.html.twig' %}
{% if orgs|length >1 %} {% if orgs|length >0 %}
<h1 class="mt-5 mb-4">Vos applications</h1> <h1 class="mt-5 mb-4">Vos applications</h1>
{% elseif orgs|length == 1 %}
{% for org in orgs %}
<h1 class="mt-5 mb-4">{{ org.name }}</h1>
{% endfor %}
{% else %} {% else %}
<h1 class="mt-5 mb-4">Aucune application</h1> <h1 class="mt-5 mb-4">Aucune application</h1>
{% endif %} {% endif %}

View File

@ -14,13 +14,13 @@
<form method="post" action="{{ path('user_deactivate_organization', {'id': user.id}) }}" <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?');"> onsubmit="return confirm('Vous allez retirer l\'utilisateur de cette organisation, êtes vous sûre?');">
<input type="hidden" name="organizationId" value="{{ organizationId }}"> <input type="hidden" name="organizationId" value="{{ organizationId }}">
<button class="btn btn-danger" type="submit">Désactiver</button> <button class="btn btn-danger" type="submit">Désactiver l'utilisateur de l'organisation</button>
</form> </form>
{% else %} {% else %}
<form method="post" action="{{ path('user_activate_organization', {'id': user.id}) }}" <form method="post" action="{{ path('user_activate_organization', {'id': user.id}) }}"
onsubmit="return confirm('Vous allez activer cette utilisateur dans votre organisation, êtes vous sûre?');"> onsubmit="return confirm('Vous allez activer cette utilisateur dans votre organisation, êtes vous sûre?');">
<input type="hidden" name="organizationId" value="{{ organizationId }}"> <input type="hidden" name="organizationId" value="{{ organizationId }}">
<button class="btn btn-primary" type="submit">Activer</button> <button class="btn btn-primary" type="submit">Activer l'utilisateur de l'organisation</button>
</form> </form>
{% endif %} {% endif %}
{% endif %} {% endif %}