mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-10-31 09:18:24 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into refactor-using-rector-202303
This commit is contained in:
		| @@ -47,7 +47,6 @@ | ||||
|         "symfony/monolog-bundle": "^3.5", | ||||
|         "symfony/security-bundle": "^4.4", | ||||
|         "symfony/serializer": "^5.3", | ||||
|         "symfony/swiftmailer-bundle": "^3.5", | ||||
|         "symfony/templating": "^4.4", | ||||
|         "symfony/translation": "^4.4", | ||||
|         "symfony/twig-bundle": "^4.4", | ||||
|   | ||||
| @@ -2631,11 +2631,6 @@ parameters: | ||||
| 			count: 2 | ||||
| 			path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php | ||||
|  | ||||
| 		- | ||||
| 			message: "#^Call to method getRoleScopes\\(\\) on an unknown class Chill\\\\MainBundle\\\\Entity\\\\PermissionGroup\\.$#" | ||||
| 			count: 1 | ||||
| 			path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php | ||||
|  | ||||
| 		- | ||||
| 			message: "#^Empty array passed to foreach\\.$#" | ||||
| 			count: 1 | ||||
|   | ||||
| @@ -41,7 +41,6 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; | ||||
| use Symfony\Component\Form\FormInterface; | ||||
| use Symfony\Component\HttpFoundation\Request; | ||||
| use Symfony\Component\HttpFoundation\Response; | ||||
| use Symfony\Component\Security\Core\Role\Role; | ||||
| use Symfony\Component\Serializer\SerializerInterface; | ||||
| use Symfony\Contracts\Translation\TranslatorInterface; | ||||
| use function array_key_exists; | ||||
| @@ -213,7 +212,7 @@ final class ActivityController extends AbstractController | ||||
|  | ||||
|         $form = $this->createForm(ActivityType::class, $entity, [ | ||||
|             'center' => $this->centerResolver->resolveCenters($entity)[0] ?? null, | ||||
|             'role' => new Role('CHILL_ACTIVITY_UPDATE'), | ||||
|             'role' => 'CHILL_ACTIVITY_UPDATE', | ||||
|             'activityType' => $entity->getActivityType(), | ||||
|             'accompanyingPeriod' => $accompanyingPeriod, | ||||
|         ]); | ||||
| @@ -442,7 +441,7 @@ final class ActivityController extends AbstractController | ||||
|  | ||||
|         $form = $this->createForm(ActivityType::class, $entity, [ | ||||
|             'center' => $this->centerResolver->resolveCenters($entity)[0] ?? null, | ||||
|             'role' => new Role('CHILL_ACTIVITY_CREATE'), | ||||
|             'role' => 'CHILL_ACTIVITY_CREATE', | ||||
|             'activityType' => $entity->getActivityType(), | ||||
|             'accompanyingPeriod' => $accompanyingPeriod, | ||||
|         ]); | ||||
|   | ||||
| @@ -120,7 +120,6 @@ class ListActivitiesByAccompanyingPeriodContext implements | ||||
|  | ||||
|     public function contextGenerationDataDenormalize(DocGeneratorTemplate $template, $entity, array $data): array | ||||
|     { | ||||
|  | ||||
|         $denormalized = $this->accompanyingPeriodContext->contextGenerationDataDenormalize($template, $entity, $data); | ||||
|  | ||||
|         foreach (['myActivitiesOnly', 'myWorksOnly'] as $k) { | ||||
|   | ||||
| @@ -106,6 +106,9 @@ CHILL_ACTIVITY_SEE_DETAILS: Voir le détail des échanges | ||||
| CHILL_ACTIVITY_DELETE: Supprimer un échange | ||||
| CHILL_ACTIVITY_STATS: Statistique des échanges | ||||
| CHILL_ACTIVITY_LIST: Liste des échanges | ||||
| CHILL_ACTIVITY_CREATE_PERSON: Créer un échange lié à un usager | ||||
| CHILL_ACTIVITY_CREATE_ACCOMPANYING_COURSE: Créer un échange lié à un parcours | ||||
| CHILL_ACTIVITY_FULL: Voir les détails, créer, supprimer et mettre à jour un échange | ||||
|  | ||||
| # admin | ||||
| Activities: Échanges | ||||
| @@ -116,7 +119,7 @@ Activity type configuration: Configuration des catégories d'échanges | ||||
| Activity Reasons: Sujets d'un échange | ||||
| Activity Reasons Category: Catégories de sujet d'échanges | ||||
| Activity Types Categories: Catégories des types d'échange | ||||
| Activity Presences: Presences aux échanges | ||||
| Activity Presences: Présences aux échanges | ||||
| Associated activity reason category is inactive: La catégorie de sujet attachée est inactive | ||||
|  | ||||
|  | ||||
| @@ -124,13 +127,13 @@ Associated activity reason category is inactive: La catégorie de sujet attaché | ||||
| crud: | ||||
|     activity_type: | ||||
|         title_new: Nouveau type d'échange | ||||
|         title_edit: Edition d'un type d'activité | ||||
|         title_edit: Édition d'un type d'échange | ||||
|     activity_type_category: | ||||
|         title_new: Nouvelle catégorie de type d'activité | ||||
|         title_edit: Edition d'une catégorie de type d'activité | ||||
|         title_new: Nouvelle catégorie de type d'échange | ||||
|         title_edit: Édition d'une catégorie de type d'échange | ||||
|     activity_presence: | ||||
|         title_new: Nouvelle Présence aux activités | ||||
|         title_edit: Edition d'une Présence aux activités | ||||
|         title_new: Nouvelle présence aux échanges | ||||
|         title_edit: Édition d'une présence aux échanges | ||||
|  | ||||
| # activity reason admin | ||||
| ActivityReason list: Liste des sujets | ||||
| @@ -139,7 +142,7 @@ Active: Actif | ||||
| Category: Catégorie | ||||
| ActivityReason creation: Nouveau sujet | ||||
| ActivityReason edit: Modification d'un sujet | ||||
| ActivityReason: Sujet d'activité | ||||
| ActivityReason: Sujet d'échange | ||||
| The entity is inactive and won't be proposed: Le sujet est inactif et ne sera pas proposé | ||||
| The entity is active and will be proposed: Le sujet est actif et sera proposé | ||||
|  | ||||
| @@ -148,17 +151,17 @@ ActivityReasonCategory list: Catégories de sujets | ||||
| Create a new activity category reason: Créer une nouvelle catégorie | ||||
| ActivityReasonCategory creation: Nouvelle catégorie de sujet | ||||
| ActivityReasonCategory edit: Modification d'une catégorie de sujet | ||||
| ActivityReasonCategory: Catégorie de sujet d'activité | ||||
| ActivityReasonCategory: Catégorie de sujet d'échange | ||||
| ActivityReasonCategory is active and will be proposed: La catégorie est active et sera proposée | ||||
| ActivityReasonCategory is inactive and won't be proposed: La catégorie est inactive et ne sera pas proposée | ||||
|  | ||||
| #activity presence admin | ||||
| ActivityPresence list: Liste des Présences aux activités | ||||
| Create a new activity presence: Créer une nouvelle "Présence aux activités" | ||||
| ActivityPresence list: Liste des présences aux échanges | ||||
| Create a new activity presence: Créer une nouvelle "Présence aux échanges" | ||||
|  | ||||
| # activity type type admin | ||||
| ActivityType list: Types d'activités | ||||
| Create a new activity type: Créer un nouveau type d'activité | ||||
| ActivityType list: Types d'échanges | ||||
| Create a new activity type: Créer un nouveau type d'échange | ||||
| Persons visible: Visibilité du champ Usagers | ||||
| Persons label: Libellé du champ Usagers | ||||
| User visible: Visibilité du champ Utilisateur | ||||
| @@ -197,135 +200,135 @@ Documents visible: Visibilité du champ Documents | ||||
| Documents label: Libellé du champ Documents | ||||
|  | ||||
| # activity type category admin | ||||
| ActivityTypeCategory list: Liste des catégories des types d'activité | ||||
| Create a new activity type category: Créer une nouvelle catégorie de type d'activité | ||||
| ActivityTypeCategory list: Liste des catégories des types d'échange | ||||
| Create a new activity type category: Créer une nouvelle catégorie de type d'échange | ||||
|  | ||||
| # activity delete | ||||
| Remove activity: Supprimer une activité | ||||
| Are you sure you want to remove the activity about "%name%" ?: Êtes-vous sûr de vouloir supprimer une activité qui concerne "%name%" ? | ||||
| The activity has been successfully removed.: L'activité a été supprimée. | ||||
| Remove activity: Supprimer un échange | ||||
| Are you sure you want to remove the activity about "%name%" ?: Êtes-vous sûr de vouloir supprimer un échange qui concerne "%name%" ? | ||||
| The activity has been successfully removed.: L'échange a été supprimé. | ||||
|  | ||||
| # exports | ||||
| Exports of activities linked to a person: Exports des activités liées à un usager | ||||
| Number of activities linked to a person: Nombre d'activités liées à un usager | ||||
| Count activities linked to a person: Nombre d'activités | ||||
| Count activities linked to a person by various parameters.: Compte le nombre d'activités enregistrées et liées à un usager en fonction de différents paramètres. | ||||
| Sum activity linked to a person duration: Durée des activités | ||||
| Sum activities linked to a person duration: Durée des activités liés à un usager | ||||
| Sum activities linked to a person duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres. | ||||
| List activity linked to a person: Liste les activités | ||||
| List activities linked to a person: Liste des activités liés à un usager | ||||
| List activities linked to a person description: Crée la liste des activités en fonction de différents paramètres. | ||||
| Exports of activities linked to a person: Exports des échanges liés à un usager | ||||
| Number of activities linked to a person: Nombre d'échanges liés à un usager | ||||
| Count activities linked to a person: Nombre d'échanges | ||||
| Count activities linked to a person by various parameters.: Compte le nombre d'échanges enregistrés et liés à un usager en fonction de différents paramètres. | ||||
| Sum activity linked to a person duration: Durée des échanges | ||||
| Sum activities linked to a person duration: Durée des échanges liés à un usager | ||||
| Sum activities linked to a person duration by various parameters.: Additionne la durée des échanges en fonction de différents paramètres. | ||||
| List activity linked to a person: Liste les échanges | ||||
| List activities linked to a person: Liste des échanges liés à un usager | ||||
| List activities linked to a person description: Crée la liste des échanges en fonction de différents paramètres. | ||||
|  | ||||
| Exports of activities linked to an accompanying period: Exports des activités liées à un parcours | ||||
| Number of activities linked to an accompanying period: Nombre d'activités liées à un parcours | ||||
| Count activities linked to an accompanying period: Nombre d'activités | ||||
| Count activities linked to an accompanying period by various parameters.: Compte le nombre d'activités enregistrées et liées à un parcours en fonction de différents paramètres. | ||||
| Sum activity linked to an accompanying period duration: Somme de la durée des activités | ||||
| Sum activities linked to an accompanying period duration: Somme de la durée des activités liées à un parcours | ||||
| Sum activities linked to an accompanying period duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres. | ||||
| Sum activity linked to an accompanying period visit duration: Somme de la durée de déplacement des activités | ||||
| Sum activities linked to an accompanying period visit duration: Somme de la durée de déplacement des activités liées à un parcours | ||||
| Sum activities linked to an accompanying period visit duration by various parameters.: Additionne la durée de déplacement des activités en fonction de différents paramètres. | ||||
| Average activity linked to an accompanying period duration: Moyenne de la durée des activités | ||||
| Average activities linked to an accompanying period duration: Moyenne de la durée des activités liées à un parcours | ||||
| Average activities linked to an accompanying period duration by various parameters.: Moyenne de la durée des activités en fonction de différents paramètres. | ||||
| Average activity linked to an accompanying period visit duration: Moyenne de la durée de déplacement des activités | ||||
| Average activities linked to an accompanying period visit duration: Moyenne de la durée de déplacement des activités liées à un parcours | ||||
| Average activities linked to an accompanying period visit duration by various parameters.: Moyenne de la durée de déplacement des activités en fonction de différents paramètres. | ||||
| Exports of activities linked to an accompanying period: Exports des échanges liés à un parcours | ||||
| Number of activities linked to an accompanying period: Nombre d'échanges liés à un parcours | ||||
| Count activities linked to an accompanying period: Nombre d'échanges | ||||
| Count activities linked to an accompanying period by various parameters.: Compte le nombre d'échanges enregistrés et liées à un parcours en fonction de différents paramètres. | ||||
| Sum activity linked to an accompanying period duration: Somme de la durée des échanges | ||||
| Sum activities linked to an accompanying period duration: Somme de la durée des échanges liés à un parcours | ||||
| Sum activities linked to an accompanying period duration by various parameters.: Additionne la durée des échanges en fonction de différents paramètres. | ||||
| Sum activity linked to an accompanying period visit duration: Somme de la durée de déplacement des échanges | ||||
| Sum activities linked to an accompanying period visit duration: Somme de la durée de déplacement des échanges liés à un parcours | ||||
| Sum activities linked to an accompanying period visit duration by various parameters.: Additionne la durée de déplacement des échanges en fonction de différents paramètres. | ||||
| Average activity linked to an accompanying period duration: Moyenne de la durée des échanges | ||||
| Average activities linked to an accompanying period duration: Moyenne de la durée des échanges liés à un parcours | ||||
| Average activities linked to an accompanying period duration by various parameters.: Moyenne de la durée des échanges en fonction de différents paramètres. | ||||
| Average activity linked to an accompanying period visit duration: Moyenne de la durée de déplacement des échanges | ||||
| Average activities linked to an accompanying period visit duration: Moyenne de la durée de déplacement des échanges liés à un parcours | ||||
| Average activities linked to an accompanying period visit duration by various parameters.: Moyenne de la durée de déplacement des échanges en fonction de différents paramètres. | ||||
|  | ||||
| #filters | ||||
| Filter by reason: Filtrer les activités par sujet | ||||
| Filter by reason: Filtrer les échanges par sujet | ||||
| 'Filtered by reasons: only %list%': 'Filtré par sujet: seulement %list%' | ||||
| 'Filtered by activity type: only %list%': "Filtré par type d'activité: uniquement %list%" | ||||
| Filtered by date activity: Filtrer les activités par date | ||||
| Activities after this date: Activités après cette date | ||||
| Activities before this date: Activités avant cette date | ||||
| "Filtered by date of activity: only between %date_from% and %date_to%": "Filtré par date de l'activité: uniquement entre %date_from% et %date_to%" | ||||
| This date should be after the date given in "Implied in an activity after this date" field: Cette date devrait être postérieure à la date donnée dans le champ "activités après cette date" | ||||
| 'Filtered by activity type: only %list%': "Filtré par type d'échange: uniquement %list%" | ||||
| Filtered by date activity: Filtrer les échanges par date | ||||
| Activities after this date: Échanges après cette date | ||||
| Activities before this date: Échanges avant cette date | ||||
| "Filtered by date of activity: only between %date_from% and %date_to%": "Filtré par date de l'échange: uniquement entre %date_from% et %date_to%" | ||||
| This date should be after the date given in "Implied in an activity after this date" field: Cette date devrait être postérieure à la date donnée dans le champ "échanges après cette date" | ||||
|  | ||||
| Filtered by person having an activity in a period: Uniquement les usagers ayant eu une activité dans la période donnée | ||||
| Implied in an activity after this date: Impliqué dans une activité après cette date | ||||
| Implied in an activity before this date: Impliqué dans une activité avant cette date | ||||
| Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Filtré par usager associées à une activité entre %date_from% et %date_to% avec les sujets %reasons_name% | ||||
| Activity reasons for those activities: Sujets de ces activités | ||||
| Filtered by person having an activity in a period: Uniquement les usagers ayant eu un échange dans la période donnée | ||||
| Implied in an activity after this date: Impliqué dans un échange après cette date | ||||
| Implied in an activity before this date: Impliqué dans un échange avant cette date | ||||
| Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Filtré par usager associées à un échange entre %date_from% et %date_to% avec les sujets %reasons_name% | ||||
| Activity reasons for those activities: Sujets de ces échanges | ||||
|  | ||||
| Filter by activity type: Filtrer les activités par type | ||||
| Filter by activity type: Filtrer les échanges par type | ||||
|  | ||||
| Filter activity by location: Filtrer les activités par localisation | ||||
| Filter activity by location: Filtrer les échanges par localisation | ||||
| 'Filtered activity by location: only %locations%': "Filtré par localisation: uniquement %locations%" | ||||
| Filter activity by locationtype: Filtrer les activités par type de localisation | ||||
| Filter activity by locationtype: Filtrer les échanges par type de localisation | ||||
| 'Filtered activity by locationtype: only %types%': "Filtré par type de localisation: uniquement %types%" | ||||
| Accepted locationtype: Types de localisation | ||||
| Accepted users: TMS(s) | ||||
| Filter activity by emergency: Filtrer les activités par urgence | ||||
| Filter activity by emergency: Filtrer les échanges par urgence | ||||
| 'Filtered activity by emergency: only %emergency%': "Filtré par urgence: uniquement si %emergency%" | ||||
| activity is emergency: l'activité est urgente | ||||
| activity is not emergency: l'activité n'est pas urgente | ||||
| Filter activity by sentreceived: Filtrer les activités par envoyé/reçu | ||||
| activity is emergency: l'échange est urgent | ||||
| activity is not emergency: l'échange n'est pas urgent | ||||
| Filter activity by sentreceived: Filtrer les échanges par envoyé/reçu | ||||
| 'Filtered activity by sentreceived: only %sentreceived%': "Filtré par envoyé/reçu: uniquement %sentreceived%" | ||||
| Accepted sentreceived: '' | ||||
| Filter activity by linked socialaction: Filtrer les activités par action liée | ||||
| Filter activity by linked socialaction: Filtrer les échanges par action liée | ||||
| 'Filtered activity by linked socialaction: only %actions%': "Filtré par action liée: uniquement %actions%" | ||||
| Filter activity by linked socialissue: Filtrer les activités par problématique liée | ||||
| Filter activity by linked socialissue: Filtrer les échanges par problématique liée | ||||
| 'Filtered activity by linked socialissue: only %issues%': "Filtré par problématique liée: uniquement %issues%" | ||||
| Filter activity by user: Filtrer les activités par créateur | ||||
| Filter activity by users: Filtrer les activités par utilisateur participant | ||||
| Filter activity by creator: Filtrer les activités par créateur de l'échange | ||||
| Filter activity by user: Filtrer les échanges par créateur | ||||
| Filter activity by users: Filtrer les échanges par utilisateur participant | ||||
| Filter activity by creator: Filtrer les échanges par créateur de l'échange | ||||
| 'Filtered activity by user: only %users%': "Filtré par référent: uniquement %users%" | ||||
| 'Filtered activity by users: only %users%': "Filtré par utilisateurs participants: uniquement %users%" | ||||
| 'Filtered activity by creator: only %users%': "Filtré par créateur: uniquement %users%" | ||||
| Creators: Créateurs | ||||
| Filter activity by userscope: Filtrer les activités par service du créateur | ||||
| Filter activity by userscope: Filtrer les échanges par service du créateur | ||||
| 'Filtered activity by userscope: only %scopes%': "Filtré par service du créateur: uniquement %scopes%" | ||||
| Accepted userscope: Services | ||||
|  | ||||
| Filter acp which has no activity: Filtrer les parcours qui n’ont pas d’activité | ||||
| Filtered acp which has no activities: Filtrer les parcours sans activité associée | ||||
| Group acp by activity number: Grouper les parcours par nombre d’activité | ||||
| Filter acp which has no activity: Filtrer les parcours qui n’ont pas d’échange | ||||
| Filtered acp which has no activities: Filtrer les parcours sans échange associé | ||||
| Group acp by activity number: Grouper les parcours par nombre d’échange | ||||
|  | ||||
| #aggregators | ||||
| Activity type: Type d'activité | ||||
| Activity user: Utilisateur lié à l'activité | ||||
| Activity type: Type d'échange | ||||
| Activity user: Utilisateur lié à l'échange | ||||
| By reason: Par sujet | ||||
| By category of reason: Par catégorie de sujet | ||||
| Reason's level: Niveau du sujet | ||||
| Group by reasons: Sujet d'activité | ||||
| Aggregate by activity user: Grouper les activités par référent | ||||
| Aggregate by activity users: Grouper les activités par utilisateurs participants | ||||
| Aggregate by activity type: Grouper les activités par type | ||||
| Aggregate by activity reason: Grouper les activités par sujet | ||||
| Aggregate by users scope: Grouper les activités par service principal de l'utilisateur | ||||
| Users 's scope: Service principal des utilisateurs participants à l'activité | ||||
| Aggregate by users job: Grouper les activités par métier des utilisateurs participants | ||||
| Users 's job: Métier des utilisateurs participants à l'activité | ||||
| Group by reasons: Sujet d'échange | ||||
| Aggregate by activity user: Grouper les échanges par référent | ||||
| Aggregate by activity users: Grouper les échanges par utilisateurs participants | ||||
| Aggregate by activity type: Grouper les échanges par type | ||||
| Aggregate by activity reason: Grouper les échanges par sujet | ||||
| Aggregate by users scope: Grouper les échanges par service principal de l'utilisateur | ||||
| Users 's scope: Service principal des utilisateurs participants à l'échange | ||||
| Aggregate by users job: Grouper les échanges par métier des utilisateurs participants | ||||
| Users 's job: Métier des utilisateurs participants à l'échange | ||||
|  | ||||
| Group activity by locationtype: Grouper les activités par type de localisation | ||||
| Group activity by date: Grouper les activités par date | ||||
| Group activity by locationtype: Grouper les échanges par type de localisation | ||||
| Group activity by date: Grouper les échanges par date | ||||
| Frequency: Fréquence | ||||
| by month: Par mois | ||||
| by week: Par semaine | ||||
| for week: Semaine | ||||
| by year: Par année | ||||
| in year: En | ||||
| Group activity by creator: Grouper les activités par créateur de l'échange | ||||
| Group activity by creator scope: Grouper les activités par service du créateur de l'échange | ||||
| Group activity by linked thirdparties: Grouper les activités par tiers impliqué | ||||
| Group activity by creator: Grouper les échanges par créateur de l'échange | ||||
| Group activity by creator scope: Grouper les échanges par service du créateur de l'échange | ||||
| Group activity by linked thirdparties: Grouper les échanges par tiers impliqué | ||||
| Accepted thirdparty: Tiers impliqué | ||||
| Group activity by linked socialaction: Grouper les activités par action liée | ||||
| Group activity by linked socialissue: Grouper les activités par problématique liée | ||||
| Group activity by userscope: Grouper les activités par service du créateur | ||||
| Group activity by linked socialaction: Grouper les échanges par action liée | ||||
| Group activity by linked socialissue: Grouper les échanges par problématique liée | ||||
| Group activity by userscope: Grouper les échanges par service du créateur | ||||
|  | ||||
| Last activities: Les dernières activités | ||||
| Last activities: Les derniers échanges | ||||
|  | ||||
| See activity in accompanying course context: Voir l'activité dans le contexte du parcours d'accompagnement | ||||
| See activity in accompanying course context: Voir l'échange dans le contexte du parcours d'accompagnement | ||||
|  | ||||
| You get notified of an activity which does not exists any more: Cette notification ne correspond pas à une activité valide. | ||||
| you are not allowed to see it details: La notification fait référence à une activité à laquelle vous n'avez pas accès. | ||||
| This is the minimal activity data: Activité n° | ||||
| You get notified of an activity which does not exists any more: Cette notification ne correspond pas à un échange valide. | ||||
| you are not allowed to see it details: La notification fait référence à un échange auquel vous n'avez pas accès. | ||||
| This is the minimal activity data: Échange n° | ||||
|  | ||||
| docgen: | ||||
|     Activity basic: Echange | ||||
|     Activity basic: Échange | ||||
|     A basic context for activity: Contexte pour les échanges | ||||
|     Accompanying period with a list of activities: Parcours d'accompagnement avec liste des échanges | ||||
|     Accompanying period with a list of activities description: Ce contexte reprend les informations du parcours, et tous les échanges pour un parcours. Les échanges ne sont pas filtrés. | ||||
| @@ -341,7 +344,7 @@ export: | ||||
|             persons ids: Identifiant des usagers | ||||
|             persons name: Nom des usagers | ||||
|             thirds parties: Tiers | ||||
|             date: Date de l'activité | ||||
|             date: Date de l'échange | ||||
|             locationName: Localisation | ||||
|             sent received: Envoyé ou reçu | ||||
|             emergency: Urgence | ||||
| @@ -350,17 +353,17 @@ export: | ||||
|             travelTime: Durée de déplacement | ||||
|             durationTime: Durée | ||||
|             id: Identifiant | ||||
|             List activities linked to an accompanying course: Liste les activités liées à un parcours en fonction de différents filtres. | ||||
|             List activity linked to a course: Liste des activités liées à un parcours | ||||
|             List activities linked to an accompanying course: Liste les échanges liés à un parcours en fonction de différents filtres. | ||||
|             List activity linked to a course: Liste des échanges liés à un parcours | ||||
|  | ||||
|  | ||||
|     filter: | ||||
|         activity: | ||||
|             by_usersjob: | ||||
|                 Filter by users job: Filtrer les activités par métier d'au moins un utilisateur participant | ||||
|                 Filter by users job: Filtrer les échanges par métier d'au moins un utilisateur participant | ||||
|                 'Filtered activity by users job: only %jobs%': 'Filtré par métier d''au moins un utilisateur participant: seulement %jobs%' | ||||
|             by_usersscope: | ||||
|                 Filter by users scope: Filtrer les activités par services d'au moins un utilisateur participant | ||||
|                 Filter by users scope: Filtrer les échanges par services d'au moins un utilisateur participant | ||||
|                 'Filtered activity by users scope: only %scopes%': 'Filtré par service d''au moins un utilisateur participant: seulement %scopes%' | ||||
|     aggregator: | ||||
|         activity: | ||||
| @@ -368,4 +371,4 @@ export: | ||||
|                 Sent or received: Envoyé ou reçu | ||||
|                 is sent: envoyé | ||||
|                 is received: reçu | ||||
|                 Group activity by sentreceived: Grouper les activités par envoyé / reçu | ||||
|                 Group activity by sentreceived: Grouper les échanges par envoyé / reçu | ||||
|   | ||||
| @@ -1,39 +1,42 @@ | ||||
| .subtitle { | ||||
| h3.subtitle { | ||||
|     margin-top: 1rem; | ||||
|     margin-bottom: 1rem; | ||||
|     padding: 1rem; | ||||
|     &::before { | ||||
|         font: normal normal normal 20px/1 ForkAwesome; | ||||
|         margin-right: 0.5em; | ||||
|         content: "\f061"; | ||||
|     } | ||||
| } | ||||
| .family-title { | ||||
|  | ||||
| $col_charge: #e03851d7; | ||||
| $col_resource: #6d9e63d8; | ||||
|  | ||||
| h4.family-title { | ||||
|     margin-top: 1.5rem; | ||||
|     margin-bottom: 1rem !important; | ||||
|     padding-left: 0.7em; | ||||
|     i { | ||||
|         margin-right: 0.4em; | ||||
|     } | ||||
|     &.charge i { color: $col_charge; } | ||||
|     &.resource i { color: $col_resource; } | ||||
| } | ||||
| .budget-table th { | ||||
|     th { | ||||
|         color: white; | ||||
|     } | ||||
| } | ||||
| .budget-table { | ||||
|     th.charge { | ||||
|         background-color: #e03851d7; | ||||
|     } | ||||
| } | ||||
| .budget-table { | ||||
|     th.resource { | ||||
|         background-color: #6d9e63d8; | ||||
|     } | ||||
| } | ||||
| .budget-table { | ||||
|  | ||||
| table.budget-table { | ||||
|     th, td { | ||||
|         padding: 10px; | ||||
|         text-align: right; | ||||
|     } | ||||
|     td.column-wide { | ||||
|         width: 20%; | ||||
|     } | ||||
|     td.column-small { | ||||
|         width: 15%; | ||||
|         &.right { | ||||
|             align-items: right; | ||||
|         } | ||||
|     th.charge { background-color: $col_charge; } | ||||
|     th.resource { background-color: $col_resource; } | ||||
|     td.column-fixed { | ||||
|         width: 9.5em; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -58,4 +61,4 @@ | ||||
| button[aria-expanded="true"] > span.folded, | ||||
| button[aria-expanded="false"] > span.unfolded { display: none; } | ||||
| button[aria-expanded="false"] > span.folded, | ||||
| button[aria-expanded="true"] > span.unfolded { display: inline; } | ||||
| button[aria-expanded="true"] > span.unfolded { display: inline; } | ||||
|   | ||||
| @@ -32,28 +32,21 @@ | ||||
|     {% endif %} | ||||
| {% endfor %} | ||||
|  | ||||
|  | ||||
| <h3 class="subtitle">{{ 'Actual budget'|trans }}</h3> | ||||
|  | ||||
| {% if actualCharges|length > 0 or actualResources|length > 0 %} | ||||
|     {% include 'ChillBudgetBundle:Budget:_current_budget.html.twig' with { | ||||
|     {% include '@ChillBudget/Budget/_current_budget.html.twig' with { | ||||
|         'actualResources': actualResources, | ||||
|         'actualCharges': actualCharges, | ||||
|         'results': results, | ||||
|         'entity': entity | ||||
|     } %} | ||||
| {% else %} | ||||
|     <div class="flex-table"> | ||||
|         <div class="item-bloc"> | ||||
|             <p><span class="chill-no-data-statement">{{ "There isn't any element recorded"|trans }}</span></p> | ||||
|         </div> | ||||
|     </div> | ||||
|     <p><span class="chill-no-data-statement">{{ "There isn't any element recorded"|trans }}</span></p> | ||||
| {% endif %} | ||||
|  | ||||
| {% if pastCharges|length > 0 or pastResources|length > 0 %} | ||||
|     <h2 class="subtitle">{{ 'Past budget'|trans }}</h2> | ||||
|  | ||||
|     {% include 'ChillBudgetBundle:Budget:_past_budget.html.twig' with { | ||||
|     <h3 class="subtitle">{{ 'Past budget'|trans }}</h3> | ||||
|     {% include '@ChillBudget/Budget/_past_budget.html.twig' with { | ||||
|         'pastCharges': pastCharges, | ||||
|         'pastResources': pastResources, | ||||
|         'entity': entity | ||||
| @@ -61,9 +54,8 @@ | ||||
| {% endif %} | ||||
|  | ||||
| {% if futureCharges|length > 0 or futureResources|length > 0 %} | ||||
|     <h2 class="subtitle">{{ 'Future budget'|trans }}</h2> | ||||
|  | ||||
|     {% include 'ChillBudgetBundle:Budget:_future_budget.html.twig' with { | ||||
|     <h3 class="subtitle">{{ 'Future budget'|trans }}</h3> | ||||
|     {% include '@ChillBudget/Budget/_future_budget.html.twig' with { | ||||
|         'futureResources': futureResources, | ||||
|         'futureCharges': futureCharges, | ||||
|         'entity': entity | ||||
|   | ||||
| @@ -1,30 +1,17 @@ | ||||
| {% from 'ChillBudgetBundle:Budget:_macros.html.twig' import table_elements, table_results %} | ||||
|  | ||||
| {# <h2 class="subtitle">{{ 'Actual budget'|trans }}</h2> #} | ||||
|  | ||||
| <div class="flex-table"> | ||||
|     <h4 class="family-title">{{ 'Actual resources'|trans }}</h4> | ||||
| {% from '@ChillBudget/Budget/_macros.html.twig' import table_elements, table_results %} | ||||
|  | ||||
| <div class="my-4"> | ||||
|     <h4 class="family-title resource"><i class="fa fa-fw fa-plus-square"></i>{{ 'Actual resources'|trans }}</h4> | ||||
|     {% if actualResources|length > 0 %} | ||||
|     <div class="item-bloc"> | ||||
|         {{ table_elements(actualResources, 'resource') }} | ||||
|     </div> | ||||
|     {% else %} | ||||
|     <div class="item-bloc"> | ||||
|         <span class="chill-no-data-statement">{{ 'No resources registered'|trans }}</span> | ||||
|     </div> | ||||
|     {% endif %} | ||||
| </div> | ||||
|  | ||||
| <div class="flex-table"> | ||||
|     <h4 class="family-title">{{ 'Actual charges'|trans }}</h4> | ||||
|     <h4 class="family-title charge"><i class="fa fa-fw fa-minus-square"></i>{{ 'Actual charges'|trans }}</h4> | ||||
|     {% if actualCharges|length > 0 %} | ||||
|     <div class="item-bloc"> | ||||
|         {{ table_elements(actualCharges, 'charge') }} | ||||
|     </div> | ||||
|     {% else %} | ||||
|     <div class="item-bloc"> | ||||
|         <span class="chill-no-data-statement">{{ 'No charges registered'|trans }}</span> | ||||
|     </div> | ||||
|     {% endif %} | ||||
| </div> | ||||
|   | ||||
| @@ -20,32 +20,23 @@ | ||||
|             aria-labelledby="heading_future_{{ entity.id }}" | ||||
|             data-bs-parent="#future_{{ entity.id }}"> | ||||
|  | ||||
|             <div class="flex-table"> | ||||
|                 <h3 class="family-title">{{ 'Future resources'|trans }}</h3> | ||||
|             <div class="my-4"> | ||||
|                 <h4 class="family-title resource"><i class="fa fa-fw fa-plus-square"></i>{{ 'Future resources'|trans }}</h4> | ||||
|  | ||||
|                 {% if futureResources|length > 0 %} | ||||
|                     <div class="item-bloc"> | ||||
|                         {{ table_elements(futureResources, 'resource') }} | ||||
|                     </div> | ||||
|                     {{ table_elements(futureResources, 'resource') }} | ||||
|                 {% else %} | ||||
|                     <div class="item-bloc"> | ||||
|                         <span class="chill-no-data-statement">{{ 'No future resources registered'|trans }}</span> | ||||
|                     </div> | ||||
|                     <span class="chill-no-data-statement">{{ 'No future resources registered'|trans }}</span> | ||||
|                 {% endif %} | ||||
|             </div> | ||||
|             <div class="flex-table"> | ||||
|                 <h3 class="family-title">{{ 'Future charges'|trans }}</h3> | ||||
|  | ||||
|                 <h4 class="family-title charge"><i class="fa fa-fw fa-minus-square"></i>{{ 'Future charges'|trans }}</h4> | ||||
|  | ||||
|                 {% if futureCharges|length > 0 %} | ||||
|                     <div class="item-bloc"> | ||||
|                         {{ table_elements(futureCharges, 'charge') }} | ||||
|                     </div> | ||||
|                     {{ table_elements(futureCharges, 'charge') }} | ||||
|                 {% else %} | ||||
|                     <div class="item-bloc"> | ||||
|                         <span class="chill-no-data-statement">{{ 'No future charges registered'|trans }}</span> | ||||
|                     </div> | ||||
|                     <span class="chill-no-data-statement">{{ 'No future charges registered'|trans }}</span> | ||||
|                 {% endif %} | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| </div> | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| {% macro table_elements(elements, family) %} | ||||
| <table class="budget-table"> | ||||
| <table class="table table-bordered border-dark budget-table"> | ||||
|     <thead> | ||||
|         <tr> | ||||
|             <th class="{{ family }} el-type">{{ 'Budget element type'|trans }}</th> | ||||
| @@ -13,25 +13,22 @@ | ||||
|         {% for f in elements %} | ||||
|         {% set total = total + f.amount %} | ||||
|         <tr> | ||||
|             <td class="column-wide el-type"> | ||||
|                 <span class="badge-title"> | ||||
|                     <span class="title_label title_label_{{ family }}"></span> | ||||
|                     {% if f.isResource %} | ||||
|                         <span class="title_action">{{ f.resource.name|localize_translatable_string }}<span> | ||||
|                     {% else %} | ||||
|                         <span class="title_action">{{ f.charge.name|localize_translatable_string }}<span> | ||||
|                     {% endif %} | ||||
|                 </span> | ||||
|             <td class="el-type"> | ||||
|                 {% if f.isResource %} | ||||
|                     {{ f.resource.name|localize_translatable_string }} | ||||
|                 {% else %} | ||||
|                     {{ f.charge.name|localize_translatable_string }} | ||||
|                 {% endif %} | ||||
|             </td> | ||||
|             <td class="column-small">{{ f.amount|format_currency('EUR') }}</td> | ||||
|             <td class="column-wide"> | ||||
|             <td>{{ f.amount|format_currency('EUR') }}</td> | ||||
|             <td> | ||||
|                 {% if f.endDate is not null %} | ||||
|                     {{ f.startDate|format_date('short') ~ ' - ' ~ f.endDate|format_date('short') }} | ||||
|                 {% else %} | ||||
|                     {{ f.startDate|format_date('short') ~ ' - ...' }} | ||||
|                     {{ 'depuis le  ' ~ f.startDate|format_date('short') }} | ||||
|                 {% endif %} | ||||
|             </td> | ||||
|             <td class="column-small"> | ||||
|             <td class="column-fixed"> | ||||
|                 <ul class="record_actions"> | ||||
|                     {% if is_granted('CHILL_BUDGET_ELEMENT_SEE', f) %} | ||||
|                         <li> | ||||
| @@ -80,10 +77,9 @@ | ||||
|  | ||||
| {% set result = (totalResources - totalCharges) %} | ||||
|  | ||||
| <table> | ||||
| <table class="table table-bordered border-dark"> | ||||
|     <thead> | ||||
|         <tr> | ||||
|             <th> </th> | ||||
|             <th> </th> | ||||
|             <th>{{ 'Budget calculator result'|trans }}</th> | ||||
|         </tr> | ||||
| @@ -91,7 +87,6 @@ | ||||
|     <tbody> | ||||
|         <tr> | ||||
|             <td>{{ 'The balance'|trans }}</td> | ||||
|             <td> </td> | ||||
|             <td> | ||||
|                 {{ result|format_currency('EUR') }} | ||||
|             </td> | ||||
|   | ||||
| @@ -20,34 +20,24 @@ | ||||
|             aria-labelledby="heading_past_{{ entity.id }}" | ||||
|             data-bs-parent="#past_{{ entity.id }}"> | ||||
|  | ||||
|             <div class="flex-table"> | ||||
|                 <h3 class="family-title">{{ 'Past resources'|trans }}</h3> | ||||
|             <div class="my-4"> | ||||
|                 <h4 class="family-title resource"><i class="fa fa-fw fa-plus-square"></i>{{ 'Past resources'|trans }}</h4> | ||||
|  | ||||
|                 {% if pastResources|length > 0 %} | ||||
|                     <div class="item-bloc"> | ||||
|                         {{ table_elements(pastResources, 'resource') }} | ||||
|                     </div> | ||||
|                     {{ table_elements(pastResources, 'resource') }} | ||||
|                 {% else %} | ||||
|                     <div class="item-bloc"> | ||||
|                         <span class="chill-no-data-statement">{{ 'No past resources registered'|trans }}</span> | ||||
|                     </div> | ||||
|                     <span class="chill-no-data-statement">{{ 'No past resources registered'|trans }}</span> | ||||
|                 {% endif %} | ||||
|             </div> | ||||
|  | ||||
|             <div class="flex-table"> | ||||
|                 <h3 class="family-title">{{ 'Past charges'|trans }}</h3> | ||||
|                 <h4 class="family-title charge"><i class="fa fa-fw fa-minus-square"></i>{{ 'Past charges'|trans }}</h4> | ||||
|  | ||||
|                 {% if pastCharges|length > 0 %} | ||||
|                     <div class="item-bloc"> | ||||
|                         {{ table_elements(pastCharges, 'charge') }} | ||||
|                     </div> | ||||
|                     {{ table_elements(pastCharges, 'charge') }} | ||||
|                 {% else %} | ||||
|                     <div class="item-bloc"> | ||||
|                         <span class="chill-no-data-statement">{{ 'No past charges registered'|trans }}</span> | ||||
|                     </div> | ||||
|                     <span class="chill-no-data-statement">{{ 'No past charges registered'|trans }}</span> | ||||
|                 {% endif %} | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|     </div> | ||||
| </div> | ||||
| </div> | ||||
|   | ||||
| @@ -24,16 +24,14 @@ | ||||
| } %} | ||||
|  | ||||
|     {# | ||||
| <div class="flex-table"> | ||||
|     <h3 class="family-title">{{ 'Budget calculator'|trans }}</h3> | ||||
|     <div class="item-bloc"> | ||||
|         {{ table_results(wholeCharges, wholeResources) }} | ||||
|     </div> | ||||
| <div class="my-4"> | ||||
|     <h4 class="family-title">{{ 'Budget calculator'|trans }}</h4> | ||||
|     {{ table_results(wholeCharges, wholeResources) }} | ||||
| </div> | ||||
| #} | ||||
|  | ||||
| {% if household.getCurrentMembers|length > 0 %} | ||||
|     <h2 class="subtitle">{{ 'Current budget household members'|trans }}</h2> | ||||
|     <h1 class="my-5">{{ 'Budget household members'|trans }}</h1> | ||||
|  | ||||
|     {% for hm in household.getCurrentMembers %} | ||||
|         {% set member = hm.person %} | ||||
| @@ -57,6 +55,8 @@ | ||||
|                     aria-labelledby="heading_{{ member.id }}" | ||||
|                     data-bs-parent="#nonCurrent"> | ||||
|  | ||||
|                         <h2 class="mt-4">{{ 'Budget for %name%'|trans({'%name%': member.firstName ~ " " ~ member.lastName }) }}</h2> | ||||
|  | ||||
|                         {% include 'ChillBudgetBundle:Budget:_budget.html.twig' with { | ||||
|                             'resources': member.getBudgetResources, | ||||
|                             'charges': member.getBudgetCharges, | ||||
|   | ||||
| @@ -17,17 +17,15 @@ | ||||
| {% block content %} | ||||
| <h1>{{ title }}</h1> | ||||
|  | ||||
| {% include 'ChillBudgetBundle:Budget:_budget.html.twig' with { | ||||
| {% include '@ChillBudget/Budget/_budget.html.twig' with { | ||||
|     'resources': resources, | ||||
|     'charges': charges, | ||||
|     'person': person | ||||
| } %} | ||||
|  | ||||
| <div class="flex-table"> | ||||
|     <h3 class="family-title">{{ 'Budget calculator'|trans }}</h2> | ||||
|     <div class="item-bloc"> | ||||
|         {{ table_results(charges, resources) }} | ||||
|     </div> | ||||
| <div class="mt-5"> | ||||
|     <h3 class="subtitle">{{ 'Budget calculator'|trans }}</h3> | ||||
|     {{ table_results(charges, resources) }} | ||||
| </div> | ||||
|  | ||||
| {% if is_granted('CHILL_BUDGET_ELEMENT_CREATE', person) %} | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
|     {% set indexPage = 'chill_budget_elements_household_index' %} | ||||
|     {% set activeRouteKey = '' %} | ||||
|     {% set household = element.household %} | ||||
|     {% set confirm_question = 'Are you sure you want to remove the ressource "%type%" associated to household "%household%" ?'|trans({ '%household%' : household.id, '%type%': element.resource.getName | localize_translatable_string} ) %} | ||||
|     {% set confirm_question = 'Are you sure you want to remove the resource "%type%" associated to household "%household%" ?'|trans({ '%household%' : household.id, '%type%': element.resource.getName | localize_translatable_string} ) %} | ||||
| {% endif %} | ||||
|  | ||||
| {% extends template %} | ||||
|   | ||||
| @@ -3,23 +3,23 @@ Resource: Ressource | ||||
| Charge: Charge | ||||
| Budget for %name%: Budget de %name% | ||||
| Budget for household %household%: Budget du ménage | ||||
| Current budget household members: Budget actuel des membres du ménage | ||||
| Budget household members: Budget des membres du ménage | ||||
| Show budget of %name%: Montrer budget de %name% | ||||
| See complete budget: Voir budget complet | ||||
| Hide budget: Masquer | ||||
| Hide budget of %name%: Masquer budget de %name% | ||||
| Resource element type: Nature de la ressource | ||||
| Actual budget: Éléments actuels du budget | ||||
| Actual budget: Éléments actuels | ||||
| Actual resources: Ressources actuelles | ||||
| Actual resources for %name%: Ressources actuelles de %name% | ||||
| Actual charges for %name%: Charges actuelles de %name% | ||||
| Actual charges: Charges actuelles | ||||
| Past budget: Éléments du budget passé | ||||
| Past budget: Éléments passés | ||||
| Show past budget: Montrer budget passé | ||||
| Show future budget: Montrer budget future | ||||
| Past resources: Ressources passées | ||||
| Past charges: Charges passées | ||||
| Future budget: Futurs éléments du budget | ||||
| Future budget: Éléments futurs | ||||
| Future resources: Ressources futures | ||||
| Future charges: Charges futures | ||||
| Budget element type: Nature | ||||
| @@ -49,6 +49,8 @@ Remove resource: Supprimer la ressource | ||||
| Remove charge: Supprimer la charge | ||||
| Are you sure you want to remove the ressource "%type%" associated to "%name%" ?: Êtes-vous sûr·e de vouloir supprimer la ressource de nature "%type%" associée à %name% ? | ||||
| Are you sure you want to remove the charge "%type%" associated to "%name%" ?: Êtes-vous sûr·e de vouloir supprimer la charge de nature "%type%" associée à %name% ? | ||||
| Are you sure you want to remove the charge "%type%" associated to household "%household%" ?: Êtes-vous sur·e de vouloir supprimer la charge "%type%" associée au ménage ? | ||||
| Are you sure you want to remove the resource "%type%" associated to household "%household%" ?: Êtes-vous sur·e de vouloir supprimer la ressource "%type%" associée au ménage ? | ||||
| Resource deleted: Ressource supprimée | ||||
| Charge deleted: Charge supprimée | ||||
| Charge created: Charge créée | ||||
|   | ||||
| @@ -76,7 +76,7 @@ class MapAndSubscribeUserCalendarCommand extends Command | ||||
|             'expiration' => $expiration->format(DateTimeImmutable::ATOM), | ||||
|         ]); | ||||
|  | ||||
|         while ($offset < ($total - 1)) { | ||||
|         while ($offset < $total) { | ||||
|             $users = $this->userRepository->findByMostOldSubscriptionOrWithoutSubscriptionOrData( | ||||
|                 $interval, | ||||
|                 $limit, | ||||
|   | ||||
| @@ -107,8 +107,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface | ||||
|                 'users/' . $userId . '/calendarView', | ||||
|                 [ | ||||
|                     'query' => [ | ||||
|                         'startDateTime' => $startDate->format(DateTimeImmutable::ATOM), | ||||
|                         'endDateTime' => $endDate->format(DateTimeImmutable::ATOM), | ||||
|                         'startDateTime' => $startDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), | ||||
|                         'endDateTime' => $endDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), | ||||
|                         '$count' => 'true', | ||||
|                         '$top' => 0, | ||||
|                     ], | ||||
| @@ -181,8 +181,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface | ||||
|                 'users/' . $userId . '/calendarView', | ||||
|                 [ | ||||
|                     'query' => [ | ||||
|                         'startDateTime' => $startDate->format(DateTimeImmutable::ATOM), | ||||
|                         'endDateTime' => $endDate->format(DateTimeImmutable::ATOM), | ||||
|                         'startDateTime' => $startDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), | ||||
|                         'endDateTime' => $endDate->setTimezone(RemoteEventConverter::getRemoteTimeZone())->format(RemoteEventConverter::getRemoteDateTimeSimpleFormat()), | ||||
|                         '$select' => 'id,subject,start,end,isAllDay', | ||||
|                         '$top' => $limit, | ||||
|                         '$skip' => $offset, | ||||
| @@ -539,10 +539,13 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface | ||||
|         $userId = $this->mapCalendarToUser->getUserId($user); | ||||
|  | ||||
|         if (null === $userId) { | ||||
|             throw new Exception('no remote calendar for this user', [ | ||||
|                 'user' => $user->getId(), | ||||
|                 'remoteId' => $remoteId, | ||||
|             ]); | ||||
|             throw new Exception( | ||||
|                 sprintf( | ||||
|                     'no remote calendar for this user: %s, remoteid: %s', | ||||
|                     $user->getId(), | ||||
|                     $remoteId | ||||
|                 ) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|   | ||||
| @@ -23,7 +23,7 @@ ordering: ordre | ||||
| label_field: label du champ | ||||
| active: actif | ||||
| No value defined for this option: Pas de valeur pour cette option | ||||
| CustomFieldsGroup edit: Edition d'un groupe de champs personnalisé | ||||
| CustomFieldsGroup edit: Édition d'un groupe de champs personnalisé | ||||
| type: type | ||||
| The custom fields group has been created: Le groupe de champs personnalisés a été créé | ||||
| The custom fields group has been updated: Le groupe de champs personnalisés a été mis à jour | ||||
|   | ||||
| @@ -27,9 +27,7 @@ | ||||
|                         </form> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <a href="{{ chill_path_add_return_path('chill_crud_docgen_template_edit', { 'id': entity.id }) }}" class="btn btn-edit"> | ||||
|                             {{ 'Edit'|trans }} | ||||
|                         </a> | ||||
|                         <a href="{{ chill_path_add_return_path('chill_crud_docgen_template_edit', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'Edit'|trans }}"></a> | ||||
|                     </td> | ||||
|                 </tr> | ||||
|             {% endfor %} | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| docgen: | ||||
|     Generate a document: Génerer un document | ||||
|     Generate: Génerer | ||||
|     Generate a document: Générer un document | ||||
|     Generate: Générer | ||||
|     Document generation: Génération de documents | ||||
|     Manage templates and document generation: Gestion des documents générés et de leurs modèles | ||||
|     Pick template context: Choisir un contexte | ||||
|   | ||||
| @@ -5,14 +5,14 @@ | ||||
| {% block admin_content %} | ||||
|     <h1>{{ 'Document category list' | trans }}</h1> | ||||
|  | ||||
|     <table class="table"> | ||||
|     <table class="table table-bordered border-dark align-middle"> | ||||
|         <thead> | ||||
|             <tr> | ||||
|                 <th>{{ 'Creator bundle id' | trans }}</th> | ||||
|                 <th>{{ 'Internal id inside creator bundle' | trans }}</th> | ||||
|                 <th>{{ 'Document class' | trans }}</th> | ||||
|                 <th>{{ 'Name' | trans }}</th> | ||||
|                 <th>{{ 'Actions' | trans }}</th> | ||||
|                 <th class="w-25">{{ 'Actions' | trans }}</th> | ||||
|             </tr> | ||||
|         </thead> | ||||
|         <tbody> | ||||
| @@ -23,7 +23,7 @@ | ||||
|                 <td>{{ document_category.documentClass }}</td> | ||||
|                 <td>{{ document_category.name | localize_translatable_string}}</td> | ||||
|  | ||||
|                 <td> | ||||
|                 <td class="text-end"> | ||||
|                     <a href="{{ path('document_category_show', {'bundleId': document_category.bundleId, 'idInsideBundle': document_category.idInsideBundle}) }}" | ||||
|                        class="btn btn-show" title="{{ 'show' | trans }}"></a> | ||||
|                     <a href="{{ path('document_category_edit', {'bundleId': document_category.bundleId, 'idInsideBundle': document_category.idInsideBundle}) }}" | ||||
|   | ||||
| @@ -274,7 +274,7 @@ class ApiController extends AbstractCRUDController | ||||
|             $postedData = $this->getSerializer()->deserialize($request->getContent(), $postedDataType, $_format, $postedDataContext); | ||||
|         } catch (\Symfony\Component\Serializer\Exception\UnexpectedValueException $e) { | ||||
|             throw new BadRequestHttpException(sprintf('Unable to deserialize posted ' . | ||||
|                 'data: %s', $e->getMessage()), 0, $e); | ||||
|                 'data: %s', $e->getMessage()), $e, 0); | ||||
|         } | ||||
|  | ||||
|         switch ($request->getMethod()) { | ||||
|   | ||||
| @@ -107,5 +107,4 @@ class AddressToReferenceMatcherController | ||||
|             true | ||||
|         ); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -31,7 +31,7 @@ class GroupCenter | ||||
|      * ) | ||||
|      * @ORM\Cache(usage="NONSTRICT_READ_WRITE") | ||||
|      */ | ||||
|     private $center; | ||||
|     private ?Center $center = null; | ||||
|  | ||||
|     /** | ||||
|      * @var int | ||||
| @@ -40,83 +40,64 @@ class GroupCenter | ||||
|      * @ORM\Column(name="id", type="integer") | ||||
|      * @ORM\GeneratedValue(strategy="AUTO") | ||||
|      */ | ||||
|     private $id; | ||||
|     private ?int $id = null; | ||||
|  | ||||
|     /** | ||||
|      * @var PermissionsGroup | ||||
|      * | ||||
|      * @ORM\ManyToOne( | ||||
|      *     targetEntity="Chill\MainBundle\Entity\PermissionsGroup", | ||||
|      * inversedBy="groupCenters") | ||||
|      * @ORM\Cache(usage="NONSTRICT_READ_WRITE") | ||||
|      */ | ||||
|     private $permissionsGroup; | ||||
|     private ?PermissionsGroup $permissionsGroup = null; | ||||
|  | ||||
|     /** | ||||
|      * @var Collection | ||||
|      * | ||||
|      * @ORM\ManyToMany( | ||||
|      *     targetEntity="Chill\MainBundle\Entity\User", | ||||
|      *     mappedBy="groupCenters" | ||||
|      * ) | ||||
|      * @var Collection<User::class> | ||||
|      */ | ||||
|     private $users; | ||||
|     private Collection $users; | ||||
|  | ||||
|     /** | ||||
|      * GroupCenter constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->permissionsGroup = new ArrayCollection(); | ||||
|         $this->users = new ArrayCollection(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Center | ||||
|      */ | ||||
|     public function getCenter() | ||||
|     public function getCenter(): ?Center | ||||
|     { | ||||
|         return $this->center; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return int | ||||
|      */ | ||||
|     public function getId() | ||||
|     public function getId(): ?int | ||||
|     { | ||||
|         return $this->id; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return PermissionGroup | ||||
|      */ | ||||
|     public function getPermissionsGroup() | ||||
|     public function getPermissionsGroup(): ?PermissionsGroup | ||||
|     { | ||||
|         return $this->permissionsGroup; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return ArrayCollection|Collection | ||||
|      * @return Collection<User::class> | ||||
|      */ | ||||
|     public function getUsers() | ||||
|     public function getUsers(): Collection | ||||
|     { | ||||
|         return $this->users; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Chill\MainBundle\Entity\GroupCenter | ||||
|      */ | ||||
|     public function setCenter(Center $center) | ||||
|     public function setCenter(Center $center): self | ||||
|     { | ||||
|         $this->center = $center; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Chill\MainBundle\Entity\GroupCenter | ||||
|      */ | ||||
|     public function setPermissionsGroup(PermissionsGroup $permissionsGroup) | ||||
|     public function setPermissionsGroup(PermissionsGroup $permissionsGroup): self | ||||
|     { | ||||
|         $this->permissionsGroup = $permissionsGroup; | ||||
|  | ||||
|   | ||||
| @@ -88,6 +88,7 @@ class ComposedRoleScopeType extends AbstractType | ||||
|             ]) | ||||
|             ->add('scope', EntityType::class, [ | ||||
|                 'class' => Scope::class, | ||||
|                 'placeholder' => 'Choose amongst scopes', | ||||
|                 'choice_label' => static function (Scope $scope) use ($translatableStringHelper) { | ||||
|                     return $translatableStringHelper->localize($scope->getName()); | ||||
|                 }, | ||||
|   | ||||
| @@ -60,15 +60,17 @@ class ScopePickerType extends AbstractType | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder, array $options) | ||||
|     { | ||||
|         $items = array_filter( | ||||
|             $this->authorizationHelper->getReachableScopes( | ||||
|                 $this->security->getUser(), | ||||
|                 $options['role'] instanceof Role ? $options['role']->getRole() : $options['role'], | ||||
|                 $options['center'] | ||||
|             ), | ||||
|             static function (Scope $s) { | ||||
|                 return $s->isActive(); | ||||
|             } | ||||
|         $items = array_values( | ||||
|             array_filter( | ||||
|                 $this->authorizationHelper->getReachableScopes( | ||||
|                     $this->security->getUser(), | ||||
|                     $options['role'] instanceof Role ? $options['role']->getRole() : $options['role'], | ||||
|                     $options['center'] | ||||
|                 ), | ||||
|                 static function (Scope $s) { | ||||
|                     return $s->isActive(); | ||||
|                 } | ||||
|             ) | ||||
|         ); | ||||
|  | ||||
|         if (0 === count($items)) { | ||||
|   | ||||
| @@ -247,7 +247,7 @@ class WorkflowStepType extends AbstractType | ||||
|                     function ($step, ExecutionContextInterface $context, $payload) { | ||||
|                         $form = $context->getObject(); | ||||
|  | ||||
|                         foreach($form->get('future_dest_users')->getData() as $u) { | ||||
|                         foreach ($form->get('future_dest_users')->getData() as $u) { | ||||
|                             if (in_array($u, $form->get('future_cc_users')->getData(), true)) { | ||||
|                                 $context | ||||
|                                     ->buildViolation('workflow.The user in cc cannot be a dest user in the same workflow step') | ||||
|   | ||||
| @@ -15,7 +15,10 @@ use Chill\MainBundle\Entity\User; | ||||
| use Psr\Log\LoggerInterface; | ||||
| use Swift_Mailer; | ||||
| use Swift_Message; | ||||
| use Symfony\Component\Mailer\MailerInterface; | ||||
| use Symfony\Component\Mime\Email; | ||||
| use Symfony\Component\Routing\RouterInterface; | ||||
| use Symfony\Component\Templating\EngineInterface; | ||||
| use Symfony\Contracts\Translation\TranslatorInterface; | ||||
| use Twig\Environment; | ||||
|  | ||||
| @@ -26,43 +29,34 @@ use function call_user_func; | ||||
|  * Classe d'aide pour l'envoi de notification. | ||||
|  * | ||||
|  * Héberge toutes les méthodes pour ré-écrire les URL en fonction de la langue de l'utilisateur. | ||||
|  * | ||||
|  * @deprecated use the MailerInterface | ||||
|  */ | ||||
| class Mailer | ||||
| { | ||||
|     /** | ||||
|      * @var Swift_Mailer | ||||
|      */ | ||||
|     protected $forcedMailer; | ||||
|  | ||||
|     /** | ||||
|      * @var LoggerInterface | ||||
|      */ | ||||
|     protected $logger; | ||||
|  | ||||
|     /** | ||||
|      * @var Swift_Mailer | ||||
|      */ | ||||
|     protected $mailer; | ||||
|     private $logger; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $routeParameters; | ||||
|     private $routeParameters; | ||||
|  | ||||
|     /** | ||||
|      * @var RouterInterface | ||||
|      */ | ||||
|     protected $router; | ||||
|     private $router; | ||||
|  | ||||
|     /** | ||||
|      * @var TranslatorInterface | ||||
|      */ | ||||
|     protected $translator; | ||||
|     private $translator; | ||||
|  | ||||
|     /** | ||||
|      * @var \Twig\Environment | ||||
|      */ | ||||
|     protected $twig; | ||||
|     private EngineInterface $twig; | ||||
|  | ||||
|     private MailerInterface $mailer; | ||||
|  | ||||
|     /** | ||||
|      * Mailer constructor. | ||||
| @@ -70,11 +64,9 @@ class Mailer | ||||
|      * @param $routeParameters | ||||
|      */ | ||||
|     public function __construct( | ||||
|         MailerInterface $mailer, | ||||
|         LoggerInterface $logger, | ||||
|         Environment $twig, | ||||
|         Swift_Mailer $mailer, | ||||
|         // due to bug https://github.com/symfony/swiftmailer-bundle/issues/127 | ||||
|         // \Swift_Transport $mailerTransporter, | ||||
|         EngineInterface $twig, | ||||
|         RouterInterface $router, | ||||
|         TranslatorInterface $translator, | ||||
|         $routeParameters | ||||
| @@ -82,7 +74,6 @@ class Mailer | ||||
|         $this->logger = $logger; | ||||
|         $this->twig = $twig; | ||||
|         $this->mailer = $mailer; | ||||
|         //$this->forcedMailer = new \Swift_Mailer($mailerTransporter); | ||||
|         $this->router = $router; | ||||
|         $this->translator = $translator; | ||||
|         $this->routeParameters = $routeParameters; | ||||
| @@ -115,20 +106,6 @@ class Mailer | ||||
|         return $content; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $force | ||||
|      * | ||||
|      * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface | ||||
|      */ | ||||
|     public function sendMessage(Swift_Message $message, $force) | ||||
|     { | ||||
|         if ($force) { | ||||
|             $this->forcedMailer->send($message); | ||||
|         } else { | ||||
|             $this->mailer->send($message); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Envoie une notification à un utilisateur. | ||||
|      * | ||||
| @@ -155,23 +132,25 @@ class Mailer | ||||
|             $subject[2] ?? null | ||||
|         ); | ||||
|  | ||||
|         $message = (new Swift_Message($subjectI18n)) | ||||
|             ->setFrom($fromEmail, $fromName) | ||||
|             ->setTo($to); | ||||
|         $email = new Email(); | ||||
|         $email->addTo($to)->subject($subjectI18n); | ||||
|  | ||||
|         foreach ($bodies as $contentType => $content) { | ||||
|             $message->setBody($content, $contentType); | ||||
|             match ($contentType) { | ||||
|                 'text/plain' => $email->text($content), | ||||
|                 default => $email->text($content), | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         if (null !== $callback) { | ||||
|             call_user_func($callback, $message); | ||||
|             call_user_func($callback, $email); | ||||
|         } | ||||
|  | ||||
|         $this->logger->info('[notification] Sending notification', [ | ||||
|             'to' => $message->getTo(), | ||||
|             'subject' => $message->getSubject(), | ||||
|             'to' => $email->getTo(), | ||||
|             'subject' => $email->getSubject() | ||||
|         ]); | ||||
|  | ||||
|         $this->sendMessage($message, $force); | ||||
|         $this->mailer->send($email); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -375,6 +375,12 @@ span.dt { | ||||
|     font-weight: bolder; | ||||
|     background-color: var(--bs-chill-light-gray); | ||||
| } | ||||
| /// help text | ||||
| .help-text { | ||||
|     margin-top: 0.25rem; | ||||
|     font-size: 0.875em; | ||||
|     color: var(--bs-gray); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|   | ||||
| @@ -1,3 +1,11 @@ | ||||
| /// mixin to set sticky area on bottom when scrolling | ||||
| @mixin sticky-bottom { | ||||
|     position: sticky; | ||||
|     bottom: 0; | ||||
|     margin-top: 4em; | ||||
|     z-index: 1000; | ||||
| } | ||||
|  | ||||
| ul.record_actions { | ||||
|    display: flex; | ||||
|    flex-direction: row; | ||||
| @@ -53,16 +61,30 @@ ul.record_actions { | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  | ||||
| .sticky-form { | ||||
|     background-color: $white; | ||||
|     padding-top: 1.25em; | ||||
|     margin: -1em; | ||||
|     box-shadow: 0 -20px 20px -20px rgba($chill-gray, .5); | ||||
|     @include sticky-bottom; | ||||
|  | ||||
|     .sticky-form-buttons { | ||||
|         position: initial; | ||||
|         bottom: unset; | ||||
|         margin-top: unset; | ||||
|         z-index: unset; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .sticky-form-buttons { | ||||
|    margin-top: 4em; | ||||
|    background-color: $beige; | ||||
|    position: sticky; | ||||
|    bottom: 0.3em; | ||||
|    text-align: center; | ||||
|    display: flex; | ||||
|    padding: 0.8em 1.6em; | ||||
|    border-radius: 0; | ||||
|    z-index: 1000; | ||||
|     display: flex; | ||||
|     background-color: $beige; | ||||
|     text-align: center; | ||||
|     padding: 0.8em 1.6em; | ||||
|     border-radius: 0; | ||||
|     @include sticky-bottom; | ||||
|     bottom: 0.3em; | ||||
| } | ||||
|  | ||||
| /// EXCEPTIONS | ||||
|   | ||||
| @@ -64,6 +64,7 @@ section.chill-entity { | ||||
|                 margin: 0.7em 0; | ||||
|                 p { | ||||
|                     display: block; | ||||
|                     margin-bottom: 0; | ||||
|                 } | ||||
|             } | ||||
|             &.delimiter { | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <span v-if="data.working_ref_status === 'to_review'" class="badge bg-danger address-details-button-warning">L'adresse de référence a été modifiée</span> | ||||
|   <a v-if="data.loading === false" @click.prevent="clickOrOpen" class="btn btn-sm btn-misc"> | ||||
|     <span class="fa fa-map address-details-button"></span> | ||||
|   <a v-if="data.loading === false" @click.prevent="clickOrOpen" class="btn btn-misc address-details-button"> | ||||
|     <span class="fa fa-map"></span> <!-- button --> | ||||
|   </a> | ||||
|   <span v-if="data.loading" class="fa fa-spin fa-spinner "></span> | ||||
|   <AddressModal :address="data.working_address" @update-address="onUpdateAddress" ref="address_modal"></AddressModal> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
|     {% set formId = crudMainFormId|default('crud_main_form') %} | ||||
|      | ||||
|     {% block crud_content_header %} | ||||
|         <h1>{{ ('crud.'~crud_name~'.title_edit')|trans }}</h1> | ||||
|         <h1 class="mb-5">{{ ('crud.'~crud_name~'.title_edit')|trans }}</h1> | ||||
|     {% endblock crud_content_header %} | ||||
|  | ||||
|     {% block crud_content_form %} | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|     {% endblock %} | ||||
| {% else %} | ||||
|     {% block table_entities %} | ||||
|     <table class="table table-bordered border-dark"> | ||||
|     <table class="table table-bordered border-dark align-middle"> | ||||
|         <thead> | ||||
|             <tr> | ||||
|                 {% block table_entities_thead_tr %} | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
|     * has_no_address    bool | ||||
|     * multiline         bool    multiline display | ||||
|     * extended_infos    bool    add extra informations (step, floor, etc.) DEPRECATED | ||||
|     * details_button    bool    add an address details button | ||||
|  | ||||
| #} | ||||
|  | ||||
| @@ -79,7 +80,12 @@ | ||||
|             <i class="fa fa-fw fa-map-marker"></i> | ||||
|         {% endif %} | ||||
|         {{ _self.inline(address, options, streetLine, lines) }} | ||||
|         <span data-address-details="1" data-address-id="{{ address.id|escape('html_attr') }}" data-address-ref-status="{{ address.refStatus|escape('html_attr') }}"></span> | ||||
|         {% if options['details_button'] is defined and options['details_button'] == true  %} | ||||
|             <span data-address-details="1" | ||||
|                 data-address-id="{{ address.id|escape('html_attr') }}" | ||||
|                 data-address-ref-status="{{ address.refStatus|escape('html_attr') }}"> | ||||
|             </span> | ||||
|         {% endif %} | ||||
|     </span> | ||||
| {%- endif -%} | ||||
|  | ||||
| @@ -112,7 +118,12 @@ | ||||
|                     <i class="fa fa-fw fa-map-marker"></i> | ||||
|                 {% endif %} | ||||
|                 {{ _self.raw(lines) }} | ||||
|                 <p><span data-address-details="1" data-address-id="{{ address.id|escape('html_attr') }}" data-address-ref-status="{{ address.refStatus|escape('html_attr') }}"></span></p> | ||||
|                 {% if options['details_button'] is defined and options['details_button'] == true  %}<p class="mt-3"> | ||||
|                     <span data-address-details="1" | ||||
|                         data-address-id="{{ address.id|escape('html_attr') }}" | ||||
|                         data-address-ref-status="{{ address.refStatus|escape('html_attr') }}"> | ||||
|                     </span></p> | ||||
|                 {% endif %} | ||||
|             </div> | ||||
|         {% endif %} | ||||
|         {{ _self.validity(address, options) }} | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <footer class="footer"> | ||||
|     <p> | ||||
|         {{ 'This program is free software: you can redistribute it and/or modify it under the terms of the <strong>GNU Affero General Public License</strong>'|trans|raw }} | ||||
|         <br/>  | ||||
|         <a name="bottom" class="btn text-white" href="https://{{ app.request.locale }}.wikibooks.org/wiki/Chill" target="_blank"> | ||||
|         <br/> | ||||
|         <a name="bottom" class="btn text-white" href="https://gitea.champs-libres.be/Chill-project/manuals/releases" target="_blank"> | ||||
|             {{ 'User manual'|trans }} | ||||
|         </a> | ||||
|     </p> | ||||
|   | ||||
| @@ -3,93 +3,130 @@ | ||||
| {% block title %}{{ 'PermissionsGroup "%name%" edit'|trans( { '%name%': entity.name } ) }}{% endblock %} | ||||
|  | ||||
| {% block admin_content -%} | ||||
|     <h1>{{ 'PermissionsGroup "%name%" edit'|trans( { '%name%': entity.name } ) }}</h1> | ||||
| <div class="container-xxl"> | ||||
|     <div class="row"> | ||||
|  | ||||
|     <h2>{{ 'Details'|trans }}</h2> | ||||
|         <h1 class="mb-4">{{ 'PermissionsGroup "%name%" edit'|trans( { '%name%': entity.name } ) }}</h1> | ||||
|  | ||||
|     {{ form_start(edit_form) }} | ||||
|     {{ form_row(edit_form.name) }} | ||||
|     {% if edit_form.flags is defined %} | ||||
|     {{ form_row(edit_form.flags) }} | ||||
|     {% endif %} | ||||
|     {{ form_row(edit_form.submit, { 'attr': { 'class': 'btn btn-chill-green' } } ) }} | ||||
|     {{ form_end(edit_form) }} | ||||
|         <h2>{{ 'Details'|trans }}</h2> | ||||
|  | ||||
|     <h2>{{ 'Grant those permissions'|trans }} :</h2> | ||||
|         {{ form_start(edit_form) }} | ||||
|         {{ form_row(edit_form.name) }} | ||||
|         {% if edit_form.flags is defined %} | ||||
|         {{ form_row(edit_form.flags) }} | ||||
|         {% endif %} | ||||
|         {{ form_row(edit_form.submit, { 'attr': { 'class': 'btn btn-save float-end' } } ) }} | ||||
|         {{ form_end(edit_form) }} | ||||
|  | ||||
|     {%- if entity.getRoleScopes|length > 0 -%} | ||||
|     {% for title, role_scopes in role_scopes_sorted %} | ||||
|         <h2 class="mb-5">{{ 'Grant those permissions'|trans }} :</h2> | ||||
|  | ||||
|     <h3>{{ title|default("Unclassified")|trans }}</h3> | ||||
|         {%- if entity.getRoleScopes|length > 0 -%} | ||||
|         {% for title, role_scopes in role_scopes_sorted %} | ||||
|  | ||||
|     <table class="striped rounded"> | ||||
|         <thead> | ||||
|         <h3>{{ title|default("Unclassified")|trans }}</h3> | ||||
|  | ||||
|         <table class="table table-bordered border-dark align-middle mb-5"> | ||||
|             <thead> | ||||
|                 <tr> | ||||
|                     <th>{{ 'Circle'|trans }}</th> | ||||
|                     <th class="w-75">{{ 'Role'|trans }}</th> | ||||
|                     <th>{{ 'Actions'|trans }}</th> | ||||
|                 </tr> | ||||
|             </thead> | ||||
|             <tbody> | ||||
|  | ||||
|         {% for role_scope in role_scopes %} | ||||
|             <tr> | ||||
|                 <th>{{ 'Role'|trans }}</th> | ||||
|                 <th>{{ 'Circle'|trans }}</th> | ||||
|                 <th>{{ 'Actions'|trans }}</th> | ||||
|             </tr> | ||||
|         </thead> | ||||
|         <tbody> | ||||
|  | ||||
|     {% for role_scope in role_scopes %} | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <span class="role_scope role">{{ role_scope.role|trans }}</span> | ||||
|                 {% if expanded_roles[role_scope.role]|length > 1 %} | ||||
|                         <br/> | ||||
|                         <small>{{ 'Which implies'|trans }} : {% for role in expanded_roles[role_scope.role] %}{{ role|trans }}{% if not loop.last %}, {% endif %}{% endfor %}</small> | ||||
|                 <td style="width: 7em"> | ||||
|                     {%- if role_scope.scope is not null -%} | ||||
|                         <span class="role_scope scope"> | ||||
|                         {{ role_scope.scope.name|localize_translatable_string }} | ||||
|                     </span> | ||||
|                     {%- else -%} | ||||
|                         <small><i>N/A</i></small> | ||||
|                     {%- endif -%} | ||||
|                 </td> | ||||
|                 <td> | ||||
|                     <span class="role_scope role">{{ role_scope.role|trans }}</span> | ||||
|                     {% if expanded_roles[role_scope.role]|length > 1 %} | ||||
|                         <div class="help-text"> | ||||
|                             <span style="text-decoration: underline dotted;">{{ 'Which implies'|trans }} :</span> | ||||
|                             {% for role in expanded_roles[role_scope.role] %} | ||||
|                                 {% if role != role_scope.role  %} | ||||
|                                     {{ role|trans }} | ||||
|                                     {% if not loop.last %}, {% endif %} | ||||
|                                 {% endif %} | ||||
|                             {% endfor %} | ||||
|                         </div> | ||||
|                     {% endif %} | ||||
|             </td> | ||||
|             <td> | ||||
|                 {%- if role_scope.scope is not null -%} | ||||
|                 <span class="role_scope scope"> | ||||
|                     {{ role_scope.scope.name|localize_translatable_string }} | ||||
|                 </span> | ||||
|                 {%- else -%} | ||||
|                     <em>N/A</em> | ||||
|                 {%- endif -%} | ||||
|             </td> | ||||
|             <td> | ||||
|                 {{ form_start(delete_role_scopes_form[role_scope.id]) }} | ||||
|                 {{ form_widget(delete_role_scopes_form[role_scope.id].submit, { 'attr': { 'class': 'btn btn-chill-red' } } ) }} | ||||
|                 {{ form_end(delete_role_scopes_form[role_scope.id]) }} | ||||
|             </td> | ||||
|         </tr> | ||||
|                 </td> | ||||
|                 <td style="width: 7em"> | ||||
|                     {{ form_start(delete_role_scopes_form[role_scope.id]) }} | ||||
|                     {{ form_widget(delete_role_scopes_form[role_scope.id].submit, { 'attr': { 'class': 'btn btn-remove' } } ) }} | ||||
|                     {{ form_end(delete_role_scopes_form[role_scope.id]) }} | ||||
|                 </td> | ||||
|             </tr> | ||||
|  | ||||
|     {% endfor %} | ||||
|         </tbody> | ||||
|     </table> | ||||
|     {% endfor %} | ||||
|         {% endfor %} | ||||
|             </tbody> | ||||
|         </table> | ||||
|         {% endfor %} | ||||
|  | ||||
|     {%- else -%} | ||||
|         <p>{{ 'This group does not provide any permission'|trans }}</p> | ||||
|     {%- endif -%} | ||||
|         {%- else -%} | ||||
|             <p>{{ 'This group does not provide any permission'|trans }}</p> | ||||
|         {%- endif -%} | ||||
|  | ||||
|     </div> | ||||
|     <div class="row sticky-form"> | ||||
|  | ||||
|     <div class="mt-5"> | ||||
|         <h2>{{ 'Grant new permissions'|trans }}</h2> | ||||
|  | ||||
|         {{ form_start(add_role_scopes_form) }} | ||||
|         {{ form_errors(add_role_scopes_form) }} | ||||
|         {{ form_row(add_role_scopes_form.composed_role_scope.role) }} | ||||
|         {{ form_row(add_role_scopes_form.composed_role_scope.scope) }} | ||||
|  | ||||
|         <div class="input-group"> | ||||
|             {{ form_widget(add_role_scopes_form.composed_role_scope.role, { 'attr': { 'class': 'w-50' }}) }} | ||||
|             {{ form_widget(add_role_scopes_form.composed_role_scope.scope) }} | ||||
|         </div> | ||||
|         <div id="role_scope_legend" class="help-text mb-3">{{ 'Help to pick role and scope'|trans }}</div> | ||||
|  | ||||
|         <ul class="record_actions sticky-form-buttons"> | ||||
|             <li> | ||||
|                 {{ form_row(add_role_scopes_form.submit, { 'attr' : { 'class': 'btn btn-create' } } ) }} | ||||
|             </li> | ||||
|             <li> | ||||
|                 <a href="{{ path('admin_permissionsgroup_show', { 'id': entity.id }) }}" class="btn btn-cancel">{{ 'Cancel'|trans }}</a> | ||||
|             </li> | ||||
|             <li> | ||||
|             <li class="cancel"> | ||||
|                 <a href="{{ path('admin_permissionsgroup') }}" class="btn btn-cancel"> | ||||
|                     {{ 'Back to the list'|trans }} | ||||
|                 </a> | ||||
|                 <a href="{{ path('admin_permissionsgroup_show', { 'id': entity.id }) }}" class="btn btn-misc">{{ 'Cancel'|trans }}</a> | ||||
|             </li> | ||||
|             <li> | ||||
|                 {{ form_widget(add_role_scopes_form.submit, { 'attr' : { 'class': 'btn btn-create' } } ) }} | ||||
|             </li> | ||||
|         </ul> | ||||
|  | ||||
|         {{ form_end(add_role_scopes_form) }} | ||||
|     </div> | ||||
|  | ||||
|  | ||||
| </div> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block js %} | ||||
| <script> | ||||
|  | ||||
|     // An event listener give contextual legend when choosing an option. | ||||
|     const select = document.getElementById('form_composed_role_scope_role'); | ||||
|     const legend = document.getElementById('role_scope_legend'); | ||||
|  | ||||
|     select.addEventListener('change', function() { | ||||
|         const option = this.options[this.selectedIndex]; | ||||
|         const hasScope = option.getAttribute('data-has-scope'); | ||||
|         legend.style.display = 'block'; | ||||
|         if (hasScope === '0') { | ||||
|             legend.innerText = '{{ 'The role does not need scope'|trans }}'; | ||||
|         } else if (hasScope === '1') { | ||||
|             legend.innerText = '{{ 'The role need scope'|trans }}'; | ||||
|         } else { | ||||
|             legend.innerText = '{{ 'Help to pick role and scope'|trans }}'; | ||||
|         } | ||||
|     }); | ||||
|  | ||||
| </script> | ||||
| {% endblock %} | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| {% block admin_content -%} | ||||
|     <h1>{{ 'Permissions group list'|trans }}</h1> | ||||
|  | ||||
|     <table class="records_list"> | ||||
|     <table class="table table-bordered border-dark align-middle"> | ||||
|         <thead> | ||||
|             <tr> | ||||
|                 <th>{{ 'Name'|trans }}</th> | ||||
|   | ||||
| @@ -10,8 +10,6 @@ | ||||
|     {% if form.flags is defined %} | ||||
|     {{ form_row(form.flags) }} | ||||
|     {% endif %} | ||||
|     {{ form_row(form.submit, { 'attr': { 'class': 'btn btn-chill-green' } } ) }} | ||||
|     {{ form_end(form) }} | ||||
|  | ||||
|     <ul class="record_actions sticky-form-buttons"> | ||||
|         <li class='cancel'> | ||||
| @@ -19,5 +17,10 @@ | ||||
|                 {{ 'Back to the list'|trans }} | ||||
|             </a> | ||||
|         </li> | ||||
|         <li> | ||||
|             {{ form_widget(form.submit, { 'attr': { 'class': 'btn btn-create' } } ) }} | ||||
|         </li> | ||||
|     </ul> | ||||
|  | ||||
|     {{ form_end(form) }} | ||||
| {% endblock %} | ||||
|   | ||||
| @@ -3,44 +3,52 @@ | ||||
| {% block title %}{{ 'Permission group "%name%"'|trans({ '%name%': entity.name }) }}{% endblock %} | ||||
|  | ||||
| {% block admin_content -%} | ||||
|     <h1>{{ 'Permission group "%name%"'|trans({ '%name%': entity.name }) }}</h1> | ||||
|     <h1 class="mb-4">{{ 'Permission group "%name%"'|trans({ '%name%': entity.name }) }}</h1> | ||||
|  | ||||
|     <table class="record_properties"> | ||||
|     <table class="table table-bordered border-dark align-middle"> | ||||
|         <tbody> | ||||
|             <tr> | ||||
|                 <th>{{ 'Name'|trans }}</th> | ||||
|                 <td>{{ entity.name }}</td> | ||||
|                 <td class="w-25">{{ entity.name }}</td> | ||||
|             </tr> | ||||
|         </tbody> | ||||
|     </table> | ||||
|  | ||||
|     {% if role_scopes_sorted|length > 0 %} | ||||
|     <h2>{{ 'Grant those permissions'|trans }} :</h2> | ||||
|     <h2 class="mb-5">{{ 'Grant those permissions'|trans }} :</h2> | ||||
|  | ||||
|     {% for title, role_scopes in role_scopes_sorted %} | ||||
|     <h3>{{ title|default('Unclassified')|trans }}</h3> | ||||
|     <table class="striped rounded"> | ||||
|     <table class="table table-bordered border-dark align-middle mb-5"> | ||||
|         <thead> | ||||
|             <tr> | ||||
|                 <th class="w-25">{{ 'Circle'|trans }}</th> | ||||
|                 <th>{{ 'Role'|trans }}</th> | ||||
|                 <th>{{ 'Circle'|trans }}</th> | ||||
|             </tr> | ||||
|         </thead> | ||||
|         <tbody> | ||||
|  | ||||
|             {% for role_scope in role_scopes %} | ||||
|             <tr> | ||||
|                 <td> | ||||
|                     {{ role_scope.role|trans }} | ||||
|                     {% if expanded_roles[role_scope.role]|length > 1 %} | ||||
|                         <br/> | ||||
|                         <small>{{ 'Which implies'|trans }} : {% for role in expanded_roles[role_scope.role] %}{{ role|trans }}{% if not loop.last %}, {% endif %}{% endfor %}</small> | ||||
|                     {% endif %} | ||||
|                 </td> | ||||
|                 <td>{%- if role_scope.scope is not null -%} | ||||
|                     {{ role_scope.scope.name|localize_translatable_string }} | ||||
|                 <td style="width: 7em">{%- if role_scope.scope is not null -%} | ||||
|                         {{ role_scope.scope.name|localize_translatable_string }} | ||||
|                     {%- else -%} | ||||
|                     <em>N/A</em> | ||||
|                 {%- endif -%} | ||||
|                         <small><i>N/A</i></small> | ||||
|                     {%- endif -%} | ||||
|                 </td> | ||||
|                 <td> | ||||
|                     <span class="role_scope role">{{ role_scope.role|trans }}</span> | ||||
|                     {% if expanded_roles[role_scope.role]|length > 1 %} | ||||
|                         <div class="help-text"> | ||||
|                             <span style="text-decoration: underline dotted;">{{ 'Which implies'|trans }} :</span> | ||||
|                             {% for role in expanded_roles[role_scope.role] %} | ||||
|                                 {% if role != role_scope.role  %} | ||||
|                                     {{ role|trans }} | ||||
|                                     {% if not loop.last %}, {% endif %} | ||||
|                                 {% endif %} | ||||
|                             {% endfor %} | ||||
|                         </div> | ||||
|                     {% endif %} | ||||
|                 </td> | ||||
|             </tr> | ||||
|             {% endfor %} | ||||
| @@ -57,17 +65,15 @@ | ||||
|     {% endif %} | ||||
|  | ||||
|     <ul class="record_actions sticky-form-buttons"> | ||||
|  | ||||
|         <li class="cancel"> | ||||
|             <a href="{{ path('admin_permissionsgroup') }}" class="btn btn-cancel"> | ||||
|                 {{ 'Back to the list'|trans }} | ||||
|             </a> | ||||
|         </li> | ||||
|         <li> | ||||
|             <a href="{{ path('admin_permissionsgroup_edit', { 'id': entity.id }) }}" class="btn btn-edit"> | ||||
|                {{ 'Edit'|trans }} | ||||
|             </a> | ||||
|         </li> | ||||
|         <li> | ||||
|             <a href="{{ path('admin_permissionsgroup') }}" class="btn btn-cancel"> | ||||
|                 {{ 'Back to the list'|trans }} | ||||
|             </a> | ||||
|         </li> | ||||
|  | ||||
|     </ul> | ||||
| {% endblock %} | ||||
|   | ||||
| @@ -4,10 +4,10 @@ | ||||
|     {% embed '@ChillMain/CRUD/_edit_content.html.twig' %} | ||||
|         {% block crud_content_after_form %} | ||||
|             {% if access_permissions_group_list %} | ||||
|                 <h2>{{ 'Permissions granted'|trans }}</h2> | ||||
|                 <h2 class="mt-5">{{ 'Permissions granted'|trans }}</h2> | ||||
|  | ||||
|                 {% if entity.groupcenters|length > 0 %} | ||||
|                     <table> | ||||
|                     <table class="table table-bordered border-dark align-middle mb-5"> | ||||
|                         <thead> | ||||
|                         <tr> | ||||
|                             <th>{{ 'Permission group'|trans }}</th> | ||||
| @@ -19,18 +19,18 @@ | ||||
|                         {% for groupcenter in entity.groupcenters %} | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                         <span class="user_group permissionsgroup"> | ||||
|                             {{ groupcenter.permissionsgroup.name }} | ||||
|                         </span> | ||||
|                                     <span class="user_group permissionsgroup"> | ||||
|                                         {{ groupcenter.permissionsgroup.name }} | ||||
|                                     </span> | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                         <span class="user_group center"> | ||||
|                             {{ groupcenter.center.name }} | ||||
|                         </span> | ||||
|                                     <span class="user_group center"> | ||||
|                                         {{ groupcenter.center.name }} | ||||
|                                     </span> | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                 <td class="w-25 text-end"> | ||||
|                                     {{ form_start(delete_groupcenter_form[groupcenter.id]) }} | ||||
|                                     {{ form_row(delete_groupcenter_form[groupcenter.id].submit, { 'attr': { 'class': 'btn btn-chill-red' } } ) }} | ||||
|                                     {{ form_widget(delete_groupcenter_form[groupcenter.id].submit, { 'attr': { 'class': 'btn btn-remove' } } ) }} | ||||
|                                     {{ form_rest(delete_groupcenter_form[groupcenter.id]) }} | ||||
|                                     {{ form_end(delete_groupcenter_form[groupcenter.id]) }} | ||||
|                                 </td> | ||||
| @@ -47,7 +47,7 @@ | ||||
|                 {{ form_start(add_groupcenter_form) }} | ||||
|                 {{ form_row(add_groupcenter_form.composed_groupcenter.center) }} | ||||
|                 {{ form_row(add_groupcenter_form.composed_groupcenter.permissionsgroup) }} | ||||
|                 {{ form_row(add_groupcenter_form.submit, { 'attr' : { 'class': 'btn btn-chill-green' } } ) }} | ||||
|                 {{ form_row(add_groupcenter_form.submit, { 'attr' : { 'class': 'btn btn-create' } } ) }} | ||||
|  | ||||
|                 {{ form_end(add_groupcenter_form) }} | ||||
|             {% endif %} | ||||
|   | ||||
| @@ -69,19 +69,20 @@ | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <ul class="record_actions"> | ||||
|  | ||||
|                             {% if is_granted('ROLE_ALLOWED_TO_SWITCH') %} | ||||
|                                 <li> | ||||
|                                     <a class="btn btn-chill-blue" href="{{ path('chill_main_homepage', {'_switch_user': entity.username }) }}" title="{{ "Impersonate"|trans|e('html_attr') }}"><i class="fa fa-user-secret"></i></a> | ||||
|                                 </li> | ||||
|                             {% endif %} | ||||
|  | ||||
|                             <li> | ||||
|                                 <a class="btn btn-edit" title="{{ 'Edit'|trans }}" href="{{ path('chill_crud_admin_user_edit', { 'id': entity.id }) }}"></a> | ||||
|                             </li> | ||||
|  | ||||
|                             {% if allow_change_password is same as(true) %} | ||||
|                                 <li> | ||||
|                                     <a class="btn btn-chill-red" href="{{ path('admin_user_edit_password',  { 'id' : entity.id }) }}" title="{{ 'Edit password'|trans|e('html_attr') }}"><i class="fa fa-ellipsis-h"></i></a> | ||||
|                                 </li> | ||||
|                             {% endif %} | ||||
|  | ||||
|                             {% if is_granted('ROLE_ALLOWED_TO_SWITCH') %} | ||||
|                                 <li> | ||||
|                                     <a class="btn btn-chill-blue" href="{{ path('chill_main_homepage', {'_switch_user': entity.username }) }}" title="{{ "Impersonate"|trans|e('html_attr') }}"><i class="fa fa-user-secret"></i></a> | ||||
|                                     <a class="btn btn-reset" href="{{ path('admin_user_edit_password',  { 'id' : entity.id }) }}" title="{{ 'Edit password'|trans|e('html_attr') }}"><i class="fa fa-key-modern"></i></a> | ||||
|                                 </li> | ||||
|                             {% endif %} | ||||
|                         </ul> | ||||
|   | ||||
| @@ -2,14 +2,14 @@ | ||||
|  | ||||
| {% block admin_content %} | ||||
|     {% embed '@ChillMain/CRUD/_index.html.twig' %} | ||||
|          | ||||
|  | ||||
|         {% block table_entities_thead_tr %} | ||||
|             <th>id</th> | ||||
|             <th>{{ 'Label'|trans }}</th> | ||||
|             <th>{{ 'Active'|trans }}</th> | ||||
|             <th>{{ 'Actions'|trans }}</th> | ||||
|         {% endblock %} | ||||
|          | ||||
|  | ||||
|         {% block table_entities_tbody %} | ||||
|             {% for entity in entities %} | ||||
|                 <tr> | ||||
| @@ -25,19 +25,19 @@ | ||||
|                     <td> | ||||
|                         <ul class="record_actions"> | ||||
|                             <li> | ||||
|                                 <a href="{{ chill_path_add_return_path('chill_crud_admin_user_job_edit', { 'id': entity.id}) }}" class="btn btn-sm btn-edit btn-mini"></a> | ||||
|                                 <a href="{{ chill_path_add_return_path('chill_crud_admin_user_job_edit', { 'id': entity.id}) }}" class="btn btn-edit"></a> | ||||
|                             </li> | ||||
|                         </ul> | ||||
|                     </td> | ||||
|                 </tr> | ||||
|              {% endfor %} | ||||
|         {% endblock %} | ||||
|          | ||||
|  | ||||
|         {% block actions_before %} | ||||
|             <li class='cancel'> | ||||
|                 <a href="{{ path('chill_main_admin_central') }}" class="btn btn-cancel">{{'Back to the admin'|trans}}</a> | ||||
|             </li> | ||||
|         {% endblock %} | ||||
|          | ||||
|  | ||||
|     {% endembed %} | ||||
| {% endblock %} | ||||
|   | ||||
| @@ -120,6 +120,11 @@ class AuthorizationHelper implements AuthorizationHelperInterface | ||||
|         if ($role instanceof Role) { | ||||
|             $role = $role->getRole(); | ||||
|         } | ||||
|  | ||||
|         if (!$user instanceof User) { | ||||
|             return []; | ||||
|         } | ||||
|  | ||||
|         /** @var array<string, Center> $centers */ | ||||
|         $centers = []; | ||||
|  | ||||
|   | ||||
| @@ -14,6 +14,8 @@ namespace Chill\MainBundle\Security\PasswordRecover; | ||||
| use Chill\MainBundle\Entity\User; | ||||
| use Chill\MainBundle\Notification\Mailer; | ||||
| use DateTimeInterface; | ||||
| use Symfony\Bridge\Twig\Mime\TemplatedEmail; | ||||
| use Symfony\Component\Mailer\MailerInterface; | ||||
| use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | ||||
|  | ||||
| use function array_merge; | ||||
| @@ -22,33 +24,26 @@ class RecoverPasswordHelper | ||||
| { | ||||
|     public const RECOVER_PASSWORD_ROUTE = 'password_recover'; | ||||
|  | ||||
|     /** | ||||
|      * @var Mailer | ||||
|      */ | ||||
|     protected $mailer; | ||||
|  | ||||
|     protected $routeParameters; | ||||
|     private MailerInterface $mailer; | ||||
|  | ||||
|     /** | ||||
|      * @var TokenManager | ||||
|      */ | ||||
|     protected $tokenManager; | ||||
|     private $tokenManager; | ||||
|  | ||||
|     /** | ||||
|      * @var UrlGeneratorInterface | ||||
|      */ | ||||
|     protected $urlGenerator; | ||||
|     private $urlGenerator; | ||||
|  | ||||
|     public function __construct( | ||||
|         TokenManager $tokenManager, | ||||
|         UrlGeneratorInterface $urlGenerator, | ||||
|         Mailer $mailer, | ||||
|         array $routeParameters | ||||
|         MailerInterface $mailer, | ||||
|     ) { | ||||
|         $this->tokenManager = $tokenManager; | ||||
|         $this->urlGenerator = $urlGenerator; | ||||
|         $this->mailer = $mailer; | ||||
|         $this->routeParameters = $routeParameters; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -59,27 +54,14 @@ class RecoverPasswordHelper | ||||
|      */ | ||||
|     public function generateUrl(User $user, DateTimeInterface $expiration, $absolute = true, array $parameters = []) | ||||
|     { | ||||
|         $context = $this->urlGenerator->getContext(); | ||||
|         $previousHost = $context->getHost(); | ||||
|         $previousScheme = $context->getScheme(); | ||||
|  | ||||
|         $context->setHost($this->routeParameters['host']); | ||||
|         $context->setScheme($this->routeParameters['scheme']); | ||||
|  | ||||
|         $url = $this->urlGenerator->generate( | ||||
|         return $this->urlGenerator->generate( | ||||
|             self::RECOVER_PASSWORD_ROUTE, | ||||
|             array_merge( | ||||
|                 $this->tokenManager->generate($user, $expiration), | ||||
|                 $parameters | ||||
|             ), | ||||
|             $absolute ? UrlGeneratorInterface::ABSOLUTE_URL : UrlGeneratorInterface::ABSOLUTE_PATH | ||||
|             UrlGeneratorInterface::ABSOLUTE_URL | ||||
|         ); | ||||
|  | ||||
|         // reset the host | ||||
|         $context->setHost($previousHost); | ||||
|         $context->setScheme($previousScheme); | ||||
|  | ||||
|         return $url; | ||||
|     } | ||||
|  | ||||
|     public function sendRecoverEmail( | ||||
| @@ -91,26 +73,20 @@ class RecoverPasswordHelper | ||||
|         array $additionalUrlParameters = [], | ||||
|         $emailSubject = 'Recover your password' | ||||
|     ) { | ||||
|         $content = $this->mailer->renderContentToUser( | ||||
|             $user, | ||||
|             $template, | ||||
|             array_merge( | ||||
|                 [ | ||||
|                     'user' => $user, | ||||
|                     'url' => $this->generateUrl($user, $expiration, true, $additionalUrlParameters), | ||||
|                 ], | ||||
|                 $templateParameters | ||||
|             ) | ||||
|         ); | ||||
|         if (null === $user->getEmail() || '' === trim($user->getEmail())) { | ||||
|             throw new \UnexpectedValueException("No emaail associated to the user"); | ||||
|         } | ||||
|  | ||||
|         $this->mailer->sendNotification( | ||||
|             $user, | ||||
|             [$emailSubject], | ||||
|             [ | ||||
|                 'text/plain' => $content, | ||||
|             ], | ||||
|             null, | ||||
|             $force | ||||
|         ); | ||||
|         $email = (new TemplatedEmail()) | ||||
|             ->subject($emailSubject) | ||||
|             ->to($user->getEmail()) | ||||
|             ->textTemplate($template) | ||||
|             ->context([ | ||||
|                 'user' => $user, | ||||
|                 'url' => $this->generateUrl($user, $expiration, true, $additionalUrlParameters), | ||||
|                 ...$templateParameters | ||||
|             ]); | ||||
|  | ||||
|         $this->mailer->send($email); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -207,7 +207,7 @@ final class GeographicalUnitBaseImporter | ||||
|             (id, geom, unitname, layer_id, unitrefid) | ||||
|             SELECT | ||||
|                 nextval('chill_main_geographical_unit_id_seq'), | ||||
|                 geom, | ||||
|                 st_makevalid(geom), | ||||
|                 unitName, | ||||
|                 layer.id, | ||||
|                 unitKey | ||||
|   | ||||
| @@ -78,8 +78,8 @@ class PostalCodeFRFromOpenData | ||||
|  | ||||
|     private function handleRecord(array $record): void | ||||
|     { | ||||
|         if ('' !== trim($record['coordonnees_gps'])) { | ||||
|             [$lat, $lon] = array_map(static fn ($el) => (float) trim($el), explode(',', $record['coordonnees_gps'])); | ||||
|         if ('' !== trim($record['coordonnees_geographiques'] ?? $record['coordonnees_gps'])) { | ||||
|             [$lat, $lon] = array_map(static fn ($el) => (float) trim($el), explode(',', $record['coordonnees_geographiques'] ?? $record['coordonnees_gps'])); | ||||
|         } else { | ||||
|             $lat = $lon = 0.0; | ||||
|         } | ||||
|   | ||||
| @@ -10,12 +10,6 @@ services: | ||||
|  | ||||
|     Chill\MainBundle\Notification\Mailer: | ||||
|         arguments: | ||||
|             $logger: '@Psr\Log\LoggerInterface' | ||||
|             $twig: '@Twig\Environment' | ||||
|             $mailer: '@swiftmailer.mailer.default' | ||||
|             # $mailerTransporter: '@swiftmailer.transport' | ||||
|             $router: '@Symfony\Component\Routing\RouterInterface' | ||||
|             $translator: '@Symfony\Contracts\Translation\TranslatorInterface' | ||||
|             $routeParameters: '%chill_main.notifications%' | ||||
|  | ||||
|     Chill\MainBundle\Notification\NotificationHandlerManager: | ||||
|   | ||||
| @@ -61,11 +61,7 @@ services: | ||||
|         arguments: | ||||
|             $secret: '%kernel.secret%' | ||||
|  | ||||
|     Chill\MainBundle\Security\PasswordRecover\RecoverPasswordHelper: | ||||
|         arguments: | ||||
|             $tokenManager: '@Chill\MainBundle\Security\PasswordRecover\TokenManager' | ||||
|             $mailer: '@Chill\MainBundle\Notification\Mailer' | ||||
|             $routeParameters: "%chill_main.notifications%" | ||||
|     Chill\MainBundle\Security\PasswordRecover\RecoverPasswordHelper: ~ | ||||
|  | ||||
|     Chill\MainBundle\Security\PasswordRecover\PasswordRecoverEventSubscriber: | ||||
|         arguments: | ||||
|   | ||||
| @@ -69,7 +69,6 @@ final class Version20230306145728 extends AbstractMigration | ||||
|         $this->addSql('CREATE INDEX IDX_165051F63174800F ON chill_main_address (createdBy_id)'); | ||||
|         $this->addSql('CREATE INDEX IDX_165051F665FF1AEC ON chill_main_address (updatedBy_id)'); | ||||
|         $this->addSql('COMMENT ON COLUMN chill_main_address_reference.point IS \'(DC2Type:point)\''); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function down(Schema $schema): void | ||||
|   | ||||
| @@ -167,12 +167,16 @@ Permissionsgroup: Groupe de permissions | ||||
| New permission group: Nouveau groupe de permissions | ||||
| PermissionsGroup "%name%" edit: Modification du groupe de permission '%name%' | ||||
| Role: Rôle | ||||
| Choose amongst roles: Choisir parmi les rôles | ||||
| Choose amongst roles: Choisir un rôle | ||||
| Choose amongst scopes: Choisir un cercle | ||||
| Add permission: Ajouter les permissions | ||||
| This group does not provide any permission: Ce groupe n'attribue aucune permission | ||||
| The role '%role%' has been removed: Le rôle "%role%" a été enlevé de ce groupe de permission | ||||
| The role '%role%' on circle '%scope%' has been removed: Le rôle "%role%" sur le cercle "%scope%" a été enlevé de ce groupe de permission | ||||
| Unclassified: Non classifié | ||||
| Help to pick role and scope: Certains rôles ne nécessitent pas de cercle. | ||||
| The role need scope: Ce rôle nécessite un cercle. | ||||
| The role does not need scope: Ce rôle ne nécessite pas de cercle ! | ||||
|  | ||||
| #admin section for users | ||||
| User configuration: Gestion des utilisateurs | ||||
| @@ -423,6 +427,7 @@ No entities: Aucun élément | ||||
|  | ||||
| CHILL_FOO_SEE: Voir un élément | ||||
| CHILL_FOO_EDIT: Modifier un élément | ||||
| chill_export: Exports (statistiques) | ||||
|  | ||||
| #Show templates | ||||
| Date: Date | ||||
|   | ||||
| @@ -64,7 +64,7 @@ class ReferrerScopeAggregator implements AggregatorInterface | ||||
|                         $qb->expr()->lte($userHistory . '.startDate', ':' . $dateCalc), | ||||
|                         $qb->expr()->orX( | ||||
|                             $qb->expr()->isNull($userHistory . '.endDate'), | ||||
|                             $qb->expr()->lt($userHistory . '.endDate', ':' . $dateCalc) | ||||
|                             $qb->expr()->gt($userHistory . '.endDate', ':' . $dateCalc) | ||||
|                         ) | ||||
|                     ) | ||||
|                 ) | ||||
|   | ||||
| @@ -93,7 +93,7 @@ class ReferrerFilter implements FilterInterface | ||||
|  | ||||
|         return [ | ||||
|             'Filtered by referrer: only %referrers%', [ | ||||
|                 '%referrers' => implode(', ', $users), | ||||
|                 '%referrers%' => implode(', ', $users), | ||||
|             ], ]; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -174,7 +174,10 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC | ||||
|             ->andWhere( | ||||
|                 $qb->expr()->orX( | ||||
|                     $qb->expr()->neq('ap.step', ':draft'), | ||||
|                     $qb->expr()->eq('ap.createdBy', ':creator') | ||||
|                     $qb->expr()->orX( | ||||
|                         $qb->expr()->eq('ap.createdBy', ':creator'), | ||||
|                         $qb->expr()->isNull('ap.createdBy') | ||||
|                     ) | ||||
|                 ) | ||||
|             ) | ||||
|             ->setParameter('draft', AccompanyingPeriod::STEP_DRAFT) | ||||
|   | ||||
| @@ -14,6 +14,31 @@ | ||||
| @import './scss/person_by_phonenumber.scss'; | ||||
| @import './scss/address_history.scss'; | ||||
|  | ||||
| /* | ||||
|  * Mixins | ||||
|  */ | ||||
|  | ||||
| @mixin context_buttons ($context) { | ||||
|     .chill-entity.entity-address .address { | ||||
|         padding-right: 1em; | ||||
|     } | ||||
|     .address-details-button, | ||||
|     .household-link { | ||||
|         border: 1px solid white; | ||||
|         background-color: transparent; | ||||
|         width: 1.85rem; | ||||
|         height: 1.85rem; | ||||
|         font-size: 75%; | ||||
|         padding: .38rem; | ||||
|         border-radius: 5px; | ||||
|         color: white; | ||||
|         cursor: pointer; | ||||
|         &:hover { | ||||
|             background-color: white; | ||||
|             color: $context | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* | ||||
| *  PERSON CONTEXT | ||||
| @@ -39,17 +64,7 @@ div.banner { | ||||
|                 margin-right: 1em; | ||||
|             } | ||||
|         } | ||||
|         .household-link { | ||||
|             border: 1px solid white; | ||||
|             padding: .05rem .3rem; | ||||
|             border-radius: 5px; | ||||
|             color: white; | ||||
|             cursor: pointer; | ||||
|             &:hover { | ||||
|                 background-color: white; | ||||
|                 color: $chill-person-context | ||||
|             } | ||||
|         } | ||||
|         @include context_buttons($chill-person-context); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -219,6 +234,8 @@ div.banner { | ||||
|             font-weight: 700; | ||||
|             font-weight: bold; | ||||
|         } | ||||
|  | ||||
|         @include context_buttons($chill-household-context); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -22,6 +22,7 @@ | ||||
|  | ||||
|     <div class="col-md-10"> | ||||
|         <h1>{{ 'My accompanying periods in draft'|trans }}</h1> | ||||
|         <p class="help-text">{{ 'Display draft periods created by me'|trans }}</p> | ||||
|  | ||||
|         <div class="flex-table accompanyingcourse-list"> | ||||
|             {% for period in accompanyingPeriods %} | ||||
| @@ -31,7 +32,9 @@ | ||||
|             {% endfor %} | ||||
|         </div> | ||||
|  | ||||
|         {{ chill_pagination(pagination) }} | ||||
|         {% if accompanyingPeriods|length > 0 %} | ||||
|             {{ chill_pagination(pagination) }} | ||||
|         {% endif %} | ||||
|  | ||||
|     </div> | ||||
|  | ||||
|   | ||||
| @@ -58,7 +58,8 @@ | ||||
|                     {% else %} | ||||
|                         <span class=" d-block d-sm-inline-block"> | ||||
|                             {{ address|chill_entity_render_box({ | ||||
|                                 'render': 'inline', 'multiline': false, 'with_picto': true, 'with_delimiter': true | ||||
|                                 'render': 'inline', 'multiline': false, 'with_picto': true, 'with_delimiter': true, | ||||
|                                 'details_button': false | ||||
|                             }) }} | ||||
|                         </span> | ||||
|                     {% endif %} | ||||
|   | ||||
| @@ -23,7 +23,11 @@ | ||||
|             {% if address is empty %} | ||||
|                 <p class="chill-no-data-statement">{{ 'household.Household does not have any address currently'|trans }}</p> | ||||
|             {% else %} | ||||
|                 {{ address|chill_entity_render_box({'multiline': true, 'extended_infos': true }) }} | ||||
|                 {{ address|chill_entity_render_box({ | ||||
|                     'multiline': true, | ||||
|                     'extended_infos': true, | ||||
|                     'details_button': true | ||||
|                 }) }} | ||||
|             {% endif %} | ||||
|  | ||||
|             <ul class="list-inline text-right mt-2"> | ||||
|   | ||||
| @@ -19,25 +19,25 @@ | ||||
|     <div id="header-person-details" class="header-details"> | ||||
|         <div class="container-xxl"> | ||||
|             <div class="row justify-content-between"> | ||||
|                 <div class="col-md-12 ps-md-5 ps-xxl-0 container"> | ||||
|                     <div class="row contact"> | ||||
|  | ||||
|                 <div class="col-md-12 ps-md-5 ps-xxl-0"> | ||||
|                     <div class="contact"> | ||||
|                         {% if person.phonenumber %} | ||||
|                             <span class="phonenumber d-block d-sm-inline-block"> | ||||
|                             <span class="col-auto phonenumber"> | ||||
|                                 <i class="fa fa-fw fa-phone"></i> | ||||
|                                 <a href="{{ 'tel:' ~ person.phonenumber|phone_number_format('E164') }}" class="phone mr-3" title="{{ 'Phonenumber'|trans }}"> | ||||
|                                     {{ person.phonenumber|chill_format_phonenumber }}</a> | ||||
|                             </span> | ||||
|                         {% endif %} | ||||
|                         {% if person.mobilenumber %} | ||||
|                             <span class="mobilenumber d-block d-sm-inline-block"> | ||||
|                             <span class="col-auto mobilenumber"> | ||||
|                                 <i class="fa fa-fw fa-mobile"></i> | ||||
|                                 <a href="{{ 'tel:' ~ person.mobilenumber|phone_number_format('E164') }}" class="phone mr-3" title="{{ 'Mobilenumber'|trans }}"> | ||||
|                                     {{ person.mobilenumber|chill_format_phonenumber }}</a> | ||||
|                             </span> | ||||
|                         {% endif %} | ||||
|                         {% if person.email %} | ||||
|                             <span class="email d-block d-sm-inline-block"> | ||||
|                             <span class="col-auto email"> | ||||
|                                 <i class="fa fa-fw fa-envelope-o"></i> | ||||
|                                 <a href="{{ 'mailto:' ~ person.email }}" class="email" title="{{ 'Email'|trans }}"> | ||||
|                                     {{ person.email }} | ||||
| @@ -51,23 +51,25 @@ | ||||
|                         {%- elseif person.lastAddress is not empty -%} | ||||
|                             {% set address = person.lastAddress %} | ||||
|                         {%- endif -%} | ||||
|                         {%- if address is not null -%} | ||||
|                             <span class=" d-block d-sm-inline-block"> | ||||
|  | ||||
|                         <span class="col-md-auto address"> | ||||
|                             {%- if address is not null -%} | ||||
|                                 {{ address|chill_entity_render_box({ | ||||
|                                     'render': 'inline', 'multiline': false, 'with_picto': true, 'with_delimiter': true | ||||
|                                     'render': 'inline', 'multiline': false, 'with_picto': true, 'with_delimiter': true, | ||||
|                                     'details_button': false | ||||
|                                 }) }} | ||||
|                             </span> | ||||
|                         {%- endif -%} | ||||
|                         {% if person.getCurrentHousehold is not null %} | ||||
|                             <span> | ||||
|                                 <a class="household-link" href="{{ chill_path_add_return_path('chill_person_household_summary', { 'household_id' : person.getCurrentHousehold.id } ) }}"> | ||||
|                                     <i class="fa fa-home"></i> | ||||
|                             {%- endif -%} | ||||
|                             {% if person.getCurrentHousehold is not null %} | ||||
|                                 <a class="btn household-link text-end" | ||||
|                                     href="{{ chill_path_add_return_path('chill_person_household_summary', { 'household_id' : person.getCurrentHousehold.id } ) }}" | ||||
|                                     title="{{ 'Show household'|trans }}"> | ||||
|                                     <i class="fa fa-lg fa-home"></i> | ||||
|                                 </a> | ||||
|                             </span> | ||||
|                         {% endif %} | ||||
|                             {% endif %} | ||||
|                         </span> | ||||
|  | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
|   | ||||
| @@ -287,7 +287,7 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface | ||||
|             $return['socialActionChild'] = $previousSocialActionChild; | ||||
|         } else { | ||||
|             $return['socialActionChild'] = $child = (new SocialAction())->setTitle(['fr' => $socialActionChildTitle]); | ||||
|             $parent->addChild($child); | ||||
|             $child->setParent($parent); | ||||
|             $child->setIssue($socialIssue)->setOrdering($orderingChild); | ||||
|             $this->entityManager->persist($child); | ||||
|         } | ||||
| @@ -332,7 +332,7 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface | ||||
|         } elseif (null !== $socialIssueChildTitle) { | ||||
|             $return['socialIssueChild'] = $child = (new SocialIssue())->setTitle(['fr' => $socialIssueChildTitle]) | ||||
|                 ->setOrdering($orderingChild); | ||||
|             $parent->addChild($child); | ||||
|             $child->setParent($parent); | ||||
|             $this->entityManager->persist($child); | ||||
|         } else { | ||||
|             $return['socialIssueChild'] = null; | ||||
|   | ||||
| @@ -966,6 +966,7 @@ Linked evaluations: Évaluations associées | ||||
| # Accompanying period per user | ||||
| My accompanying periods: Mes parcours | ||||
| My accompanying periods in draft: Mes parcours brouillons | ||||
| Display draft periods created by me: Affiche les parcours en attente de confirmation. Ils ne sont visibles que par moi-même. Ces parcours restent disponibles 15 jours après leur création, avant d'être supprimés automatiquement. | ||||
| Number of periods: Nombre de parcours | ||||
|  | ||||
| workflow: | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| 'Report edit': "Edition d'un rapport" | ||||
| 'Report edit': "Édition d'un rapport" | ||||
| 'Save report': "Enregistrer le rapport" | ||||
| 'Reset report': "Remise à zéro" | ||||
| 'Add a report': "Ajout d'un rapport" | ||||
|   | ||||
| @@ -33,6 +33,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||||
| use Symfony\Component\EventDispatcher\EventDispatcherInterface; | ||||
| use Symfony\Component\Form\Extension\Core\Type\SubmitType; | ||||
| use Symfony\Component\Form\FormFactoryInterface; | ||||
| use Symfony\Component\Form\FormInterface; | ||||
| use Symfony\Component\HttpFoundation\JsonResponse; | ||||
| use Symfony\Component\HttpFoundation\Request; | ||||
| use Symfony\Component\HttpFoundation\Response; | ||||
| @@ -205,7 +206,7 @@ final class SingleTaskController extends AbstractController | ||||
|             . 'allowed to edit this task'); | ||||
|  | ||||
|         $event = (new UIEvent('single-task', $task)) | ||||
|             ->setForm($this->setCreateForm($task, new Role(TaskVoter::UPDATE))); | ||||
|             ->setForm($this->setCreateForm($task, TaskVoter::UPDATE)); | ||||
|         $this->eventDispatcher->dispatch(UIEvent::EDIT_FORM, $event); | ||||
|  | ||||
|         $form = $event->getForm(); | ||||
| @@ -557,7 +558,7 @@ final class SingleTaskController extends AbstractController | ||||
|         $this->denyAccessUnlessGranted($role, $task, 'You are not ' | ||||
|              . 'allowed to create this task'); | ||||
|  | ||||
|         $form = $this->setCreateForm($task, new Role($role)); | ||||
|         $form = $this->setCreateForm($task, $role); | ||||
|  | ||||
|         $form->handleRequest($request); | ||||
|  | ||||
| @@ -650,7 +651,7 @@ final class SingleTaskController extends AbstractController | ||||
|     /** | ||||
|      * @return \Symfony\Component\Form\FormInterface | ||||
|      */ | ||||
|     protected function setCreateForm(SingleTask $task, Role $role) | ||||
|     protected function setCreateForm(SingleTask $task, string $role) | ||||
|     { | ||||
|         $form = $this->createForm(SingleTaskType::class, $task, [ | ||||
|             'role' => $role, | ||||
| @@ -684,12 +685,9 @@ final class SingleTaskController extends AbstractController | ||||
|  | ||||
|     /** | ||||
|      * Creates a form to delete a Task entity by id. | ||||
|      * | ||||
|      * @param mixed $id The entity id | ||||
|      * | ||||
|      * @return \Symfony\Component\Form\Form The form | ||||
|      * @param mixed $id | ||||
|      */ | ||||
|     private function createDeleteForm($id) | ||||
|     private function createDeleteForm($id): FormInterface | ||||
|     { | ||||
|         return $this->createFormBuilder() | ||||
|             ->setAction($this->generateUrl( | ||||
|   | ||||
| @@ -81,7 +81,7 @@ class SingleTaskType extends AbstractType | ||||
|                 ->add('circle', ScopePickerType::class, [ | ||||
|                     'center' => $center, | ||||
|                     'role' => $options['role'], | ||||
|                     'required' => false, | ||||
|                     'required' => true, | ||||
|                 ]); | ||||
|         } | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user