Show an organization informations

This commit is contained in:
Charles 2025-09-03 14:38:16 +02:00
parent 9257709605
commit a540bb5d9e
8 changed files with 191 additions and 19 deletions

View File

@ -2,6 +2,7 @@
namespace App\Controller;
use App\Entity\Actions;
use App\Entity\Apps;
use App\Entity\Roles;
use App\Entity\User;
@ -139,5 +140,52 @@ class OrganizationController extends AbstractController
]);
}
#[Route(path: '/{id}', name: 'show', methods: ['GET'])]
public function show($id)
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$organization = $this->entityManager->getRepository(Organizations::class)->find($id);
$actingUser = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier());
if (!$organization) {
$this->addFlash('error', self::NOT_FOUND);
return $this->redirectToRoute('organization_index');
}
//check if the user is admin of the organization
if (!$this->isGranted("ROLE_SUPER_ADMIN") && !$this->userService->isAdminOfOrganization($organization)) {
$this->createNotFoundException(self::NOT_FOUND);
}
$newUO = $this->entityManager->getRepository(UsersOrganizations::class)->findNewestUO($organization);
$newUsers = [];
foreach ($newUO as $uo) {
$newUsers[] = $uo->getUsers();
}
$adminUO = $this->entityManager->getRepository(UsersOrganizations::class)->findAdminsInOrganization($organization);
$adminUsers = [];
foreach ($adminUO as $uo) {
$adminUsers[] = $uo->getUsers();
}
$uos = $this->entityManager
->getRepository(UsersOrganizations::class)
->findBy(['organization' => $organization, 'isActive' => true]);
$users = $this->userService->formatOrgUsers($uos);
$allApps = $this->entityManager->getRepository(Apps::class)->findAll(); // appsAll
$orgApps = $organization->getApps()->toArray(); // apps
$apps = $this->organizationsService->appsAccess($allApps, $orgApps);
$actions = $this->entityManager->getRepository(Actions::class)->findBy(['Organization' => $organization]);
$activities = $this->actionService->formatActivities($actions);
return $this->render('organization/show.html.twig', [
'organization' => $organization,
'newUsers' => $newUsers,
'adminUsers' => $adminUsers,
'users' => $users,
'applications' => $apps,
'activities' => $activities,
]);
}
}

View File

@ -2,6 +2,8 @@
namespace App\Repository;
use App\Entity\Organizations;
use App\Entity\User;
use App\Entity\UsersOrganizations;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
@ -79,4 +81,59 @@ class UsersOrganizationsRepository extends ServiceEntityRepository
return $qb->getQuery()->getResult();
}
/**
* Find 10 newest Users in an Organization.
*
* @param Organizations $organization
* @return User[]
*/
public function findNewestUO(Organizations $organization): array
{
$qb = $this->createQueryBuilder('uo')
->select('uo', 'u')
->leftJoin('uo.users', 'u')
->where('uo.organization = :org')
->andWhere('uo.isActive = :uoActive')
->andWhere('u.isActive = :uActive')
->andWhere('u.isDeleted = :uDeleted')
->orderBy('u.createdAt', 'DESC')
->setMaxResults(10)
->setParameter('org', $organization)
->setParameter('uoActive', true)
->setParameter('uActive', true)
->setParameter('uDeleted', false);
return $qb->getQuery()->getResult();
}
/**
* Find all the admins of an Organization.
* limited to 10 results.
*
* @param Organizations $organization
* @return User[]
*/
public function findAdminsInOrganization(Organizations $organization): array
{
$qb = $this->createQueryBuilder('uo')
->select('uo', 'u')
->leftJoin('uo.users', 'u')
->leftJoin('uo.userOrganizatonApps', 'uoa')
->leftJoin('uoa.role', 'r')
->where('uo.organization = :org')
->andWhere('uo.isActive = :uoActive')
->andWhere('u.isActive = :uActive')
->andWhere('u.isDeleted = :uDeleted')
->andWhere('r.name = :roleAdmin')
->orderBy('u.surname', 'ASC')
->setMaxResults(10)
->setParameter('org', $organization)
->setParameter('uoActive', true)
->setParameter('uActive', true)
->setParameter('uDeleted', false)
->setParameter('roleAdmin', 'ADMIN');
return $qb->getQuery()->getResult();
}
}

View File

@ -30,6 +30,26 @@ readonly class ActionService
return '#C76633';
}
/**
* Format activities to include the computed color.
*
* @param Actions[] $activities
* @return array<int, array<string, mixed>>
*/
public function formatActivities(array $activities): array
{
return array_map(function (Actions $activity) {
return [
'date' => $activity->getDate(),
'actionType' => $activity->getActionType(),
'users' => $activity->getUsers(),
'organization' => $activity->getOrganization(),
'description' => $activity->getDescription(),
'color' => $this->getActivityColor($activity->getDate())
];
}, $activities);
}
public function createAction(
string $actionType,
User $user,

View File

@ -45,4 +45,27 @@ class OrganizationsService
}
}
/**
* Merge all apps with org apps and add a "hasAccess" flag.
*
* @param array $appsAll
* @param array $apps
* @return array
*/
public function appsAccess(array $appsAll, array $apps): array
{
// Build a quick lookup of app IDs the org has access to
$orgAppIds = array_map(static fn(Apps $app) => $app->getId(), $apps);
$result = [];
foreach ($appsAll as $app) {
$result[] = [
'entity' => $app, // Keep the full entity for Twig
'hasAccess' => in_array($app->getId(), $orgAppIds, true),
];
}
return $result;
}
}

View File

@ -266,4 +266,27 @@ class UserService
throw new FileException('File upload failed: ' . $e->getMessage());
}
}
/**
* Format users of a specific organization.
*
* @param UsersOrganizations[] $userOrganizations
* @return array
*/
public function formatOrgUsers(array $userOrganizations): array
{
$users = [];
foreach ($userOrganizations as $uo) {
$user = $uo->getUsers();
$users[] = [
'entity' => $user,
'connected' => $this->isUserConnected($user->getUserIdentifier()),
'isActive' => (bool)$uo->isActive(),
];
}
return $users;
}
}

View File

@ -3,21 +3,21 @@
<div class="card">
<div class="card-header">
<div class="card-title">
<h3><img width=10% src="{{ asset(application.application.logoUrl) }}" alt="Logo application">
{{ application.application.name }}</h3>
<h3><img width=10% src="{{ asset(application.entity.logoUrl) }}" alt="Logo application">
{{ application.entity.name }}</h3>
</div>
</div>
<div class="card-body d-flex flex-column align-items-center">
<p class="card-text">{{ application.application.descriptionSmall }}</p>
{% if application.has_access %}
<p class="card-text">{{ application.entity.descriptionSmall }}</p>
{% if application.hasAccess %}
<div >
<a href="http://{{ application.application.subDomain }}.solutions-easy.moi" class="btn btn-primary me-2">Y
<a href="http://{{ application.entity.subDomain }}.solutions-easy.moi" class="btn btn-primary me-2">Y
accéder</a>
<a href="#" class="btn btn-secondary">Gérer l'application</a>
</div>
{% else %}<a href="#" class="btn btn-primary">Demander l'accès</a>
{#TODO: page d'accès#}
{% endif %}
</div>
</div>

View File

@ -39,9 +39,10 @@
<td>{{ organization.name }}</td>
<td>{{ organization.email }}</td>
<td>
{# <a href="{{ path('organization_show', {'id': organization.id}) }}" class="p-3 align-middle color-primary"> #}
{# {{ ux_icon('fa6-regular:eye', {height: '30px', width: '30px'}) }} #}
{# </a> #}
<a href="{{ path('organization_show', {'id': organization.id}) }}"
class="p-3 align-middle color-primary">
{{ ux_icon('fa6-regular:eye', {height: '30px', width: '30px'}) }}
</a>
</td>
</tr>
{% endfor %}

View File

@ -5,7 +5,7 @@
<div class="col d-flex justify-content-between align-items-center ">
<div class="d-flex ">
{% if organization.logoUrl %}
<img src="{{ asset('uploads/logos/' ~ organization.logoUrl) }}" alt="Organization logo"
<img src="{{ asset(organization.logoUrl) }}" alt="Organization logo"
class="rounded-circle" style="width:40px; height:40px;">
{% endif %}
<h1 class="mb-4 ms-3">{{ organization.name|title }} - Dashboard</h1>
@ -14,13 +14,13 @@
{% if is_granted("ROLE_SUPER_ADMIN") %}
<a href="{{ path('organization_edit', {'id': organization.id}) }}" class="btn btn-primary">Gérer
l'organisation</a>
{% if organization.active %}
<a href="{{ path('organization_deactivate', {'id': organization.id}) }}"
class="btn btn-danger">Désactiver l'organisation</a>
{% else %}
<a href="{{ path('organization_activate', {'id': organization.id}) }}"
class="btn btn-success">Activer l'organisation</a>
{% endif %}
{# {% if organization.active %}#}
{# <a href="{{ path('organization_deactivate', {'id': organization.id}) }}"#}
{# class="btn btn-danger">Désactiver l'organisation</a>#}
{# {% else %}#}
{# <a href="{{ path('organization_activate', {'id': organization.id}) }}"#}
{# class="btn btn-success">Activer l'organisation</a>#}
{# {% endif %}#}
{% elseif is_granted("ROLE_ADMIN") %}
<a href="{{ path('organization_edit', {'id': organization.id}) }}" class="btn btn-primary">Gérer mon
organisation</a>
@ -48,13 +48,13 @@
} %}
</div>
</div>
<div class="m-auto">
{# <div class="m-auto">#}
{% include 'user/userList.html.twig' with {
title: 'Mes utilisateurs',
organizationId: organization.id,
empty_message: 'Aucun utilisateurs trouvé.'
} %}
</div>
{# </div>#}
{# APPLICATION ROW #}
<div class="row ">
{% for application in applications %}