Merge branch '295_resume_retouches' into 'master'

295 resume retouches

See merge request Chill-Projet/chill-bundles!238
This commit is contained in:
Julien Fastré 2021-11-29 13:48:18 +00:00
commit 3b725a8a12
30 changed files with 590 additions and 339 deletions

View File

@ -18,6 +18,15 @@ and this project adheres to
* Use the user.label in accompanying course banner, instead of username;
* fix: show validation message when closing accompanying course;
* [thirdparty] link from modal to thirdparty detail page fixed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/228)
* [assets] new asset to style suggestions lists (with add/remove item link) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/258)
* [accompanyingCourseWorkEdit] improves hyphenation and line breaks for long badges
* [acompanyingCourse] improve Resume page
* complete all needed informations,
* actions and activities are clickables,
* better placement with js masonry blocks on top of content area,
* https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/101
* https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/295
* [activity/calendar] on show page, concerned groups of persons table adapt itself to isVisibles options
* [activity] remove the "plus" button in activity list
* [activity] check ACL on activity list in person context
* [list for accompanying course in person] filter list using ACL
@ -57,7 +66,7 @@ and this project adheres to
* [accompanyingCourse] Ability to close accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/296)
* [task] Select2 field in task form to allow search for a user (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/167)
* [list result] show all courses, except ones with period closed
* [accompanyingCourse] improve banner with small carousel to display slide social-issues or slide associated persons (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/69)
### Test release 2021-11-15

View File

@ -56,28 +56,28 @@ Arborescence:
Comment s'échaffaudent les styles dans Chill ?
1. l'entrypoint **mod_bootstrap** (module bootstrap) est le premier niveau. Toutes les parties(modules) de bootstrap sont convoquées dans le fichier ```bootstrap.js``` situé dans ```ChillMainBundle/Resources/public/module/bootstrap```.
* Au début, ce fichier importe le fichier ```variables.scss``` qui détermine la plupart des réglages bootstrap tels qu'on les a personnalisés. Ce fichier surcharge l'original, et de nombreuses variables y sont adaptées pour Chill.
1. l'entrypoint **mod_bootstrap** (module bootstrap) est le premier niveau. Toutes les parties(modules) de bootstrap sont convoquées dans le fichier ```bootstrap.js``` situé dans ```ChillMainBundle/Resources/public/module/bootstrap```.
* Au début, ce fichier importe le fichier ```variables.scss``` qui détermine la plupart des réglages bootstrap tels qu'on les a personnalisés. Ce fichier surcharge l'original, et de nombreuses variables y sont adaptées pour Chill.
* On veillera à ce qu'on puisse toujours comparer ce fichier à l'original de bootstrap. En cas de mise à jour de bootstrap, il faudra générer un diff, et adapter ce diff sur le fichier variable de la nouvelle version.
* A la fin on importe le fichier ```custom.scss```, qui comprends des adaptations de bootstrap pour le préparer à notre thème Chill.
* A la fin on importe le fichier ```custom.scss```, qui comprends des adaptations de bootstrap pour le préparer à notre thème Chill.
* ce ```custom.scss``` peut être splitté en plus petits fichiers avec des ```@import 'custom/...'```
* L'idée est que cette première couche bootstrap règle un partie importante des styles de l'application, en particulier ce qui touche aux position du layout, aux points de bascules responsive, aux marges et écarts appliqués par défauts aux éléments qu'on manipule.
2. l'entrypoint **chill** est le second niveau. Il contient le thème Chill qui est reconnaissable à l'application.
* Chaque bundle a un dossier ```Resources/public/chill``` dans lequel on peut trouver une feuille sass principale, qui est éventuellement splittée avec des ```@imports```. Toutes ces feuilles sont compilées dans un unique entrypoint Chill, c'est le thème de l'application. Celui-ci surcharge bootstrap.
* La feuille chillmain.scss devrait contenir les cascades de styles les plus générales, celles qui sont appliquées à de nombreux endroits de l'application.
* La feuille chillmain.scss devrait contenir les cascades de styles les plus générales, celles qui sont appliquées à de nombreux endroits de l'application.
* La feuille chillperson.scss va aussi retrouver des styles propres aux différents contextes des personnes: person, household et accompanyingcourse.
* Certains bundles plus secondaires ne contiennent que des styles spécifiques à leur fonctionnement.
3. les entrypoints **vue_** sont utilisés pour des composants vue. Les fichiers vue peuvent contenir un bloc de styles scss. Ce sont des styles qui ne concernent que le composant et son héritage, le tag ```scoped``` précise justement sa portée (voir la doc).
4. les entrypoints **page_** sont utilisés pour ajouter des assets spécifiques à certaines pages, le plus souvent des scripts et des styles.
4. les entrypoints **page_** sont utilisés pour ajouter des assets spécifiques à certaines pages, le plus souvent des scripts et des styles.
## Taguer du code html et construire la cascade de styles
L'exemple suivant montre comment taguer sans excès un élément de code. On remarque que:
* il n'est pas nécessaire de taguer toutes les classes intérieures,
* il n'est pas nécessaire de taguer toutes les classes intérieures,
* il ne faut pas répéter la classe parent dans toutes les classes enfants. La cascade sass va permettre de saisir le html avec souplesse sans alourdir la structure des balises.
* souvent la première classe sera déclinée par plusieurs classes qui commencent de la même manière: ```bloc-dark``` ajoute juste la version sombre de ```bloc```, on ne met pas ```bloc dark```, car on ne souhaite pas que la classe ```dark``` de ```bloc``` interagisse avec la même classe ```dark``` de ```table```. On aura donc un élément ```bloc bloc-dark``` et un élément ```table table-dark```.
@ -94,11 +94,11 @@ L'exemple suivant montre comment taguer sans excès un élément de code. On rem
</div>
```
Finalement, il importe ici de définir ce qu'est un bloc, ce qu'est une zone d'actions et ce qu'est un bouton. Ces 3 éléments existent de manière autonome, ce sont les seuls qu'on tagge.
Finalement, il importe ici de définir ce qu'est un bloc, ce qu'est une zone d'actions et ce qu'est un bouton. Ces 3 éléments existent de manière autonome, ce sont les seuls qu'on tagge.
Par exemple pour mettre un style au titre on précise juste h3 dans la cascade bloc.
```sass
```scss
div.bloc {
// un bloc générique, utilisé à plusieurs endroits
&.bloc-dark {
@ -113,12 +113,12 @@ div.bloc {
}
}
div.mon-bloc {
// des exceptions spécifiques à mon-bloc,
// des exceptions spécifiques à mon-bloc,
// qui sont des adaptations de bloc
}
ul.record_actions {
// va uniformiser tous les record_actions de l'application
// va uniformiser tous les record_actions de l'application
li {
//...
}
@ -260,7 +260,7 @@ Exemple:
address|chill_entity_render_box
```
Justification:
Justification:
* des éléments sont parfois personnalisés par installation (par exemple, le nom de chaque utilisateur sera suivi par le nom du service)
* pour rationaliser et rendre semblable les affichages
@ -270,13 +270,13 @@ A prevoir:
* toujours trois positions:
* inline
* block
* block
* item (dans un tableau, une ligne)
> block et item sont en fait la même option passée au render_box: render: bloc. Il y a aussi raw pour le inline, et label pour une titraille configurable avec des options.
> quand on passe loption render: bloc, on peut placer le render_box dans une boucle for plus large qui fonctionne avec la classe flex-table ou la classe flex-bloc, ce qui donnera un affichage en rangée (table) ou en blocs. [name=Mathieu]
> quand on passe loption render: bloc, on peut placer le render_box dans une boucle for plus large qui fonctionne avec la classe flex-table ou la classe flex-bloc, ce qui donnera un affichage en rangée (table) ou en blocs. [name=Mathieu]
#### En vue
@ -292,13 +292,13 @@ A chaque fois qu'on indique le nom d'une personne, un parcours, un ménage, il y
Ces éléments sont toujours proposé par des `render_box` par défaut. Des options permettent de les désactiver dans des cas particuliers
> à discuter, quelques réflexion:
> quelle est la logique qui domine pour les boutons ? on a symbolisé les 4 actions du crud par des couleurs: bleu(show) orange(edit) vert(create) et rouge(delete).
> Est-ce que c'est ça qui prime, et comment ça s'articule avec la logique des pictos ?
> à discuter, quelques réflexion:
> quelle est la logique qui domine pour les boutons ? on a symbolisé les 4 actions du crud par des couleurs: bleu(show) orange(edit) vert(create) et rouge(delete).
> Est-ce que c'est ça qui prime, et comment ça s'articule avec la logique des pictos ?
> Par exemple, il pourrait être logique d'utiliser l'oeil bleu pour voir l'objet, qu'il s'agisse d'une personne ou d'un parcours, ce serait plutôt le contexte, et l'infobulle (title) qui préciserait le contexte.
> Je pense que les pictos de boutons doivent faire référence à l'action, mais pas à l'objet. Autrement dit je n'utiliserais jamais l'icone du ménage ou du parcours dans les boutons.
> Pour représenter les ménages et les parcours, je pense qu'il faudrait trouver autre chose que forkawesome. Si c'est des pictos, trouver un motif différents et de tailles différente. Réfléchir à un couplage picto-couleur-forme différent, qui exprime le contexte et qui se distingue bien des boutons.
> Idem pour les badges, il faut une palette de badge qui couvre tous les besoins: socialIssue, socialActions, socialReason, members, etc. [name=Mathieu]
> Idem pour les badges, il faut une palette de badge qui couvre tous les besoins: socialIssue, socialActions, socialReason, members, etc. [name=Mathieu]
### Formulaires
@ -350,7 +350,7 @@ A chaque fois qu'un élément est créé par un formulaire, un message flash doi
> "L'élément a été créé"
Le nom de l'élément peut être remplacé par quelque chose de plus pertinent:
Le nom de l'élément peut être remplacé par quelque chose de plus pertinent:
> * L'activité a été créée
> * Le rendez-vous a été créé
@ -362,7 +362,7 @@ Le nom de l'élément peut être remplacé par quelque chose de plus pertinent:
A chaque fois qu'un élément est enregistré, un message flash doit apparaitre:
> * Les données ont été modifiées
>
>
#### Erreur sur un formulaire (erreur de validation)
@ -377,7 +377,35 @@ Les erreurs doivent apparaitre attachée au champ qui les concerne. Toutefois, i
A chaque fois qu'un lien est indiqué, vérifier si on ne doit pas utiliser la fonction `chill_return_path`, `chill_forward_return_path` ou `chill_return_path_or`.
* depuis la page liste, vers l'ouverture d'un élément, ou le bouton création => utiliser `chill_path_add_return_path`
* dans ces pages d'éditions,
* dans ces pages d'éditions,
* utiliser `chill_return_path_or` dans le bouton "Cancel";
* pour les boutons "enregistrer et voir" et "Enregistrer et fermer" => ?
### Assets pour les listes de suggestion
Créer une liste de suggestions à ajouter (tout l'item est cliquable)
```html
<ul class="list-suggest add-items">
<li>
<span>item</span>
</li>
</ul>
```
Créer une liste de suggestions à enlever (avec une croix rouge cliquable, l'ancre a est vide)
```html
<ul class="list-suggest remove-items">
<li>
<span>
item
<a></a>
</span>
</li>
</ul>
```
Créer un titre enlevable (avec une croix rouge cliquable, l'ancre a est vide)
```html
<div class="item-title">
title
<a></a>
</div>
```

View File

@ -354,8 +354,9 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
if (null !== $this->accompanyingPeriod) {
$personsNotAssociated = [];
// TODO better semantic with: return $this->persons->filter(...);
foreach ($this->persons as $person) {
if (!in_array($person, $this->getPersonsAssociated())) {
if ($this->accompanyingPeriod->getOpenParticipationContainsPerson($person) === null) {
$personsNotAssociated[] = $person;
}
}

View File

@ -1,35 +1,33 @@
<template>
<teleport to="#add-persons" v-if="isComponentVisible">
<teleport to="#add-persons" v-if="isComponentVisible">
<div class="flex-bloc concerned-groups" :class="getContext">
<persons-bloc
v-for="bloc in contextPersonsBlocs"
v-bind:key="bloc.key"
v-bind:bloc="bloc"
v-bind:setPersonsInBloc="setPersonsInBloc">
</persons-bloc>
</div>
<div v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0">
<ul class="list-unstyled">
<li v-for="p in suggestedEntities" @click="addSuggestedEntity(p)">
<span class="badge bg-primary" style="cursor: pointer;">
<i class="fa fa-plus fa-fw text-success"></i>
{{ p.text }}
</span>
</li>
</ul>
</div>
<div class="flex-bloc concerned-groups" :class="getContext">
<persons-bloc
v-for="bloc in contextPersonsBlocs"
v-bind:key="bloc.key"
v-bind:bloc="bloc"
v-bind:blocWidth="getBlocWidth"
v-bind:setPersonsInBloc="setPersonsInBloc">
</persons-bloc>
</div>
<div v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0">
<ul class="list-suggest add-items">
<li v-for="p in suggestedEntities" @click="addSuggestedEntity(p)">
<span>{{ p.text }}</span>
</li>
</ul>
</div>
<add-persons
buttonTitle="activity.add_persons"
modalTitle="activity.add_persons"
v-bind:key="addPersons.key"
v-bind:options="addPersonsOptions"
@addNewPersons="addNewPersons"
ref="addPersons">
</add-persons>
<add-persons
buttonTitle="activity.add_persons"
modalTitle="activity.add_persons"
v-bind:key="addPersons.key"
v-bind:options="addPersonsOptions"
@addNewPersons="addNewPersons"
ref="addPersons">
</add-persons>
</teleport>
</teleport>
</template>
<script>
@ -122,6 +120,9 @@ export default {
}
}
},
getBlocWidth() {
return Math.round(100/(this.contextPersonsBlocs.length)) + '%';
}
},
mounted() {
this.setPersonsInBloc();

View File

@ -1,12 +1,8 @@
<template>
<li>
<span class="badge bg-primary" :title="person.text">
<span class="chill_denomination">
{{ textCutted }}
</span>
<a class="fa fa-fw fa-times text-danger text-decoration-none"
@click.prevent="$emit('remove', person)">
</a>
<span :title="person.text">
<span class="chill_denomination">{{ textCutted }}</span>
<a @click.prevent="$emit('remove', person)"></a>
</span>
</li>
</template>

View File

@ -1,11 +1,11 @@
<template>
<div class="item-bloc">
<div class="item-bloc" :style="{ 'flex-basis': blocWidth }">
<div class="item-row">
<div class="item-col">
<h4>{{ $t(bloc.title) }}</h4>
</div>
<div class="item-col">
<ul class="list-content">
<ul class="list-suggest remove-items">
<person-badge
v-for="person in bloc.persons"
v-bind:key="person.id"
@ -25,7 +25,7 @@ export default {
components: {
PersonBadge
},
props: ['bloc', 'setPersonsInBloc'],
props: ['bloc', 'setPersonsInBloc', 'blocWidth'],
methods: {
removePerson(item) {
console.log('@@ CLICK remove person: item', item);

View File

@ -26,23 +26,45 @@
{{ activity.type.name | localize_translatable_string }}
<ul class="small_in_title">
{% if activity.location and t.locationVisible %}
<li>
<span class="item-key">{{ 'location'|trans ~ ': ' }}</span>
<span>{{ activity.location.locationType.title|localize_translatable_string }}</span>
{{ activity.location.name }}
</li>
{% if activity.emergency %}
<span class="badge bg-danger rounded-pill fs-6">{{ 'Emergency'|trans|upper }}</span>
{% endif %}
<ul class="small_in_title mt-3">
{% if activity.sentReceived is not empty and t.sentReceivedVisible %}
<li>
<span class="item-key">{{ 'Sent received'|trans ~ ' : ' }}</span>
<b>{{ activity.sentReceived|capitalize|trans }}</b>
</li>
{% endif %}
{% if activity.location and t.locationVisible %}
<li>
<span class="item-key">{{ 'location'|trans ~ ': ' }}</span>
<b>
<span>{{ activity.location.locationType.title|localize_translatable_string }}</span>
{{ activity.location.name }}
</b>
</li>
{% endif %}
{% if activity.user and t.userVisible %}
<li>
<span class="item-key">{{ 'Referrer'|trans ~ ': ' }}</span>
{{ activity.user.usernameCanonical }}
<b>{{ activity.user.usernameCanonical }}</b>
</li>
{% endif %}
<li class="associated-persons">
<span class="item-key">{{ 'Participants'|trans ~ ' : ' }}</span>
{% for p in activity.personsAssociated %}
<span class="badge-person">{{ p|chill_entity_render_box }}</span>
{% endfor %}
</li>
</ul>
<ul class="list-content">
<ul class="list-content my-3">
{%- if t.reasonsVisible -%}
{%- if activity.reasons is not empty -%}
<li class="reasons">
@ -71,11 +93,9 @@
{%- endif -%}
{% endif %}
</ul>
</span>
</h2>
{#
{% if context == 'person' and activity.accompanyingPeriod is not empty %}
<div class="mt-3">
<a class="btn btn-sm btn-outline-primary"
@ -87,4 +107,4 @@
</a>
</div>
{% endif %}
#}

View File

@ -3,89 +3,93 @@
{{ path(pathname, parms) }}
{% endmacro %}
{% if context == 'person' %}
{% set blocs = [
{ 'title': 'Others persons'|trans,
{% macro computeWidth(nbBlocks) %}
{{ 'flex-basis: ' ~ (100 / nbBlocks)|round(1) ~ '%;' }}
{% endmacro %}
{% set blocks = [] %}
{% if entity.activityType.personsVisible %}
{% if context == 'person' %}
{% set blocks = blocks|merge([{
'title': 'Others persons'|trans,
'items': entity.persons,
'path' : 'chill_person_view',
'key' : 'person_id'
},
{ 'title': 'Third parties'|trans,
'items': entity.thirdParties,
'path' : 'chill_crud_3party_3party_view',
'key' : 'id'
},
{ 'title': 'Users concerned'|trans,
'items': entity.users,
'key' : 'id'
},
] %}
{% else %}
{% set blocs = [
{ 'title': 'Persons in accompanying course'|trans,
}]) %}
{% else %}
{% set blocks = blocks|merge([{
'title': 'Persons in accompanying course'|trans,
'items': entity.personsAssociated,
'path' : 'chill_person_view',
'key' : 'person_id'
},
{ 'title': 'Third persons'|trans,
},{
'title': 'Third persons'|trans,
'items': entity.personsNotAssociated,
'path' : 'chill_person_view',
'key' : 'person_id'
},
{ 'title': 'Third parties'|trans,
'items': entity.thirdParties,
'path' : 'chill_crud_3party_3party_view',
'key' : 'id'
},
{ 'title': 'Users concerned'|trans,
'items': entity.users,
'key' : 'id'
},
] %}
'key' : 'person_id',
}]) %}
{% endif %}
{% endif %}
{% if entity.activityType.thirdPartiesVisible %}
{% set blocks = blocks|merge([{
'title': 'Third parties'|trans,
'items': entity.thirdParties,
'path' : 'chill_crud_3party_3party_view',
'key' : 'id',
}]) %}
{% endif %}
{% if entity.activityType.usersVisible %}
{% set blocks = blocks|merge([{
'title': 'Users concerned'|trans,
'items': entity.users,
'key' : 'id',
}]) %}
{% endif %}
{% if (with_display == 'bloc') %}
<div class="{{ context }} flex-bloc concerned-groups">
{% for bloc in blocs %}
<div class="item-bloc">
<div class="item-row">
<div class="item-col">
<h4>{{ bloc.title }}</h4>
</div>
<div class="item-col">
<ul class="list-content">
{% for item in bloc.items %}
<li>
{% if bloc.path is defined %}
<a href="{{ _self.href(bloc.path, bloc.key, item.id) }}">
<span class="{% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
{{ item|chill_entity_render_box({
'render': 'raw',
'addAltNames': false
}) }}
</span>
</a>
{% else %}
<span class="{% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
{{ item|chill_entity_render_box({
'render': 'raw',
'addAltNames': false
}) }}
</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% for bloc in blocks %}
<div class="item-bloc" style="{{ _self.computeWidth(loop.length) }}">
<div class="item-row">
<div class="item-col">
<h4>{{ bloc.title }}</h4>
</div>
<div class="item-col">
<ul class="list-content">
{% for item in bloc.items %}
<li>
{% if bloc.path is defined %}
<a href="{{ _self.href(bloc.path, bloc.key, item.id) }}">
<span class="{% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
{{ item|chill_entity_render_box({
'render': 'raw',
'addAltNames': false
}) }}
</span>
</a>
{% else %}
<span class="{% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
{{ item|chill_entity_render_box({
'render': 'raw',
'addAltNames': false
}) }}
</span>
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
{% if (with_display == 'row') %}
<div class="concerned-groups">
{% for bloc in blocs %}
{% for bloc in blocks %}
<div class="group">
{% if bloc.items|length > 0 %}
<h4>{{ bloc.title }}</h4>
@ -118,7 +122,7 @@
{% if (with_display == 'wrap-list') %}
<div class="concerned-groups wrap-list">
{% for bloc in blocs %}
{% for bloc in blocks %}
<div class="wl-row">
{% if bloc.items|length > 0 %}
<div class="wl-col title">

View File

@ -2,9 +2,11 @@
{% for activity in activities | slice(0,5) %}
{% set t = activity.type %}
<a href="{{ path('chill_activity_activity_show', { 'id': activity.id, 'person_id': person_id, 'accompanying_period_id': accompanying_course_id }) }}"></a>
<a href="{{ path('chill_activity_activity_show', { 'id': activity.id, 'person_id': person_id, 'accompanying_period_id': accompanying_course_id }) }}"
class="badge-link" title="{{ 'Show the activity'|trans }}">
{% include '@ChillActivity/Activity/activity-badge-title.html.twig' %}
{% include '@ChillActivity/Activity/activity-badge-title.html.twig' %}
</a>
{% endfor %}
</div>

View File

@ -9,7 +9,7 @@
{% block content -%}
<div class="activity-show">
{% include 'ChillActivityBundle:Activity:show.html.twig' with {'context': 'accompanyingCourse'} %}
{% include 'ChillActivityBundle:Activity:show.html.twig' with {'context': 'accompanyingCourse'} %}
</div>
{% endblock content %}

View File

@ -10,6 +10,9 @@
// Chill buttons
@import './scss/buttons';
// Chill badges
@import './scss/badge';
// Chill forms
@import './scss/forms';
@ -202,9 +205,9 @@ footer.footer {
}
}
/*
* SPECIFIC RULES
* GENERIC MAIN STYLES
* miscellaneous
*/
/// titles
@ -280,7 +283,6 @@ div.metadata {
}
/// chill help tooltip
.chill-help-tooltip {
&::before {
content: '\f05a';
@ -295,7 +297,6 @@ div.metadata {
/// display definition list
// with dt and dd on same line
dl.definition-inline {
dd {
display: inline;
@ -317,6 +318,19 @@ dl.definition-inline {
font-style: italic;
}
/// flash
div#flashMessages {
margin-top: 20px;
.flash-notice {
margin-top: 10px;
margin-bottom: 10px;
}
}
/*
* SPECIFIC RULES
*/
//// still used ?
// move from chillmain.css, converted to sass
@ -369,14 +383,6 @@ div#usefulbar {
}
}
div#flashMessages {
margin-top: 20px;
.flash-notice {
margin-top: 10px;
margin-bottom: 10px;
}
}
.personName {
font-variant: small-caps;
text-transform: capitalize;

View File

@ -0,0 +1,54 @@
/// mixin used in this sheet
@mixin remove_link {
cursor: pointer;
&:before {
font: normal normal normal 14px/1 ForkAwesome;
margin-left: 0.5em;
content: "\f00d"; // fa-times
color: var(--bs-danger);
text-decoration: none;
}
}
/*
* SUGGESTIONS LIST - A specific list of badges used to manage suggestions (with add/remove link)
* /!\ use bootstrap badge styles,
* cfr. src/Bundle/ChillMainBundle/Resources/public/module/bootstrap/_custom.scss
*/
ul.list-suggest {
list-style-type: none;
padding-left: 0;
li > span {
white-space: normal;
text-align: start;
margin-bottom: 3px;
}
&.add-items {
li {
cursor: pointer;
& > span:before {
font: normal normal normal 14px/1 ForkAwesome;
margin-right: 0.5em;
content: "\f067"; // fa-plus
color: var(--bs-success);
}
}
}
&.remove-items {
li {
a {
@include remove_link;
}
}
}
}
/// manage remove link if it isn't a list but a title
/// (cfr. in Vue AccompanyingCourseWorkEdit)
div.item-title {
a {
@include remove_link;
}
}

View File

@ -4,3 +4,12 @@
*/
/// A specific list of badges, use bootstrap badge styles
/// cfr. src/Bundle/ChillMainBundle/Resources/public/chill/scss/badge.scss
ul.list-suggest {
li > span {
@extend .badge;
@extend .bg-primary;
}
}

View File

@ -219,6 +219,7 @@ thirdparty: tiers
# circles / scopes
Choose the circle: Choisir le cercle
Scopes: Services
#export

View File

@ -95,7 +95,6 @@ div.person-view {
* Header custom for Accompanying Course
*/
div.banner {
div#header-accompanying_course-name {
background: none repeat scroll 0 0 $chill-accourse-context;
@ -117,6 +116,37 @@ div.banner {
color: $white;
padding-top: 1em;
padding-bottom: 1em;
/// AccompanyingCourse: HeaderSlider Carousel
button.carousel-control-prev,
button.carousel-control-next {
width: 8%;
opacity: inherit;
}
button.carousel-control-prev {
left: unset;
right: 0;
}
span.to-social-issues,
span.to-persons-associated {
display: inline-block;
border-radius: 15px;
width: 24px;
height: 24px;
box-shadow: 0 0 3px 1px grey;
opacity: 0.8;
&:hover {
opacity: 1;
}
}
span.to-social-issues {
background-color: #4bafe8;
border-left: 12px solid #32749a;
}
span.to-persons-associated {
background-color: #16d9b4;
border-right: 12px solid #ffffff;
}
}
}
@ -203,34 +233,11 @@ div.household-resume {
}
}
/// Horizontal list of persons (Accourse resume page)
div.accompanyingcourse-resume {
div.associated-persons {
font-size: 110%;
span.household {
display: inline-block;
border-radius: 8px;
border: 1px solid $white;
&:hover {
border: 1px solid $chill-beige;
i {
display: inline-block;
}
}
&.no-household:hover {
border: 1px solid $white;
}
i {
color: $chill-beige;
display: none;
}
padding: 0.3em;
margin-right: 2px;
}
}
}
/*
* GENERIC PERSON STYLES
* miscellaneous
*/
///
abbr.referrer { // still used ?
font-size: 70%;
padding-right: 0.4em;
@ -246,4 +253,4 @@ abbr.referrer { // still used ?
.created-updated {
border: 1px solid black;
padding: 10px;
}
}

View File

@ -87,26 +87,12 @@ div.accompanying_course_work-list {
&.result_list {
padding-left: 1em;
margin-bottom: 0;
li {
padding-left: 0.3em;
&::marker {
/*
content: '';
font-weight: bold;
font-size: 120%;
*/
font-family: ForkAwesome;
content: '\f04b';
font-size: 75%;
transform: rotate(45deg);
}
}
}
&.goal_title li::marker {
color: $social-issue-color;
&.goal_title {
@include list_marker_triangle($social-issue-color);
}
&.result_list li::marker {
color: $pink;
&.result_list {
@include list_marker_triangle($pink);
}
}
}

View File

@ -49,8 +49,6 @@ h2.badge-title {
width: 100%;
color: $dark;
a & { text-decoration: none; } // ?!? keep it ?
span.title_label {
border-radius: 0.35rem 0 0 0.35rem;
color: $white;
@ -75,13 +73,43 @@ h2.badge-title {
flex-grow: 1;
margin: 0 0 0 auto;
border-radius: 0 0.35rem 0.35rem 0;
background-color: $light;
background-color: $chill-llight-gray;
padding: 0.2em 1em;
ul.small_in_title {
margin-top: 0.5em;
margin: 0;
//margin-top: 0.5em;
font-size: 70%;
padding-left: 1rem;
&.evaluations {
@include list_marker_triangle($orange);
}
}
ul.columns { // XS:1 SM:2 MD:1 LG:2 XL:2 XXL:2
@include media-breakpoint-only(sm) {
columns: 2; -webkit-columns: 2; -moz-columns: 2;
}
@include media-breakpoint-up(lg) {
columns: 2; -webkit-columns: 2; -moz-columns: 2;
}
}
}
}
/// Theses links apply on badge as parent tag.
/// They don't look like button, picto or simple text links
a.badge-link {
color: unset;
text-decoration: unset;
& > h2.badge-title {
&:hover {
//box-shadow: 0 0 7px 0 $chill-gray;
//opacity: 0.8;
}
span.title_action {
&:hover {
background-color: $chill-ll-gray;
}
}
}
}
@ -128,35 +156,7 @@ div.activity-list {
}
}
/// AccompanyingCourse: HeaderSlider Carousel
div#header-accompanying_course-details {
button.carousel-control-prev,
button.carousel-control-next {
width: 8%;
opacity: inherit;
}
button.carousel-control-prev {
left: unset;
right: 0;
}
span.to-social-issues,
span.to-persons-associated {
display: inline-block;
border-radius: 15px;
width: 24px;
height: 24px;
box-shadow: 0 0 3px 1px grey;
opacity: 0.8;
&:hover {
opacity: 1;
}
}
span.to-social-issues {
background-color: #4bafe8;
border-left: 12px solid #32749a;
}
span.to-persons-associated {
background-color: #16d9b4;
border-right: 12px solid #ffffff;
}
}
/*
*/

View File

@ -37,3 +37,20 @@
margin: 0 0.3em 0 -1.05em;
}
}
///
/// Make list with items marker like a colored triangle
///
@mixin list_marker_triangle($color) {
& > li {
padding-left: 0.3em;
&::marker {
font-family: ForkAwesome;
content: '\f04b';
font-size: 75%;
transform: rotate(45deg);
color: $color;
}
}
}

View File

@ -0,0 +1,6 @@
import Masonry from 'masonry-layout/masonry';
let elem = document.querySelector('#dashboards');
let msnry = new Masonry( elem, {
// options
});

View File

@ -48,9 +48,7 @@ export default {
persons: this.persons.filter(p => p.current_household_id === h)
})
})
console.log(personsByHousehold)
//console.log(personsByHousehold)
return personsByHousehold
},
householdExists(id) {

View File

@ -20,10 +20,9 @@
</VueMultiselect>
<template v-if="referrersSuggested.length > 0">
<ul class="list-unstyled">
<ul class="list-suggest add-items">
<li v-for="u in referrersSuggested" @click="updateReferrer(u)">
<span class="badge bg-primary" style="cursor: pointer">
<i class="fa fa-plus fa-fw text-success"></i>
<span>
<user-render-box-badge :user="u"></user-render-box-badge>
</span>
</li>

View File

@ -35,7 +35,7 @@ const appMessages = {
title: "Origine de la demande",
label: "Origine de la demande",
placeholder: "Renseignez l'origine de la demande",
not_valid: "Indiquez une origine de la demande",
not_valid: "Indiquez une origine à la demande",
},
persons_associated: {
title: "Usagers concernés",
@ -126,7 +126,7 @@ const appMessages = {
participation_not_valid: "sélectionnez au minimum 1 usager",
socialIssue_not_valid: "sélectionnez au minimum une problématique sociale",
location_not_valid: "indiquez au minimum une localisation temporaire du parcours",
origin_not_valid: "indiquez une origine de la demande",
origin_not_valid: "Indiquez une origine à la demande",
set_a_scope: "indiquez au moins un service",
sure: "Êtes-vous sûr ?",
sure_description: "Une fois le changement confirmé, il ne sera plus possible de le remettre à l'état de brouillon !",

View File

@ -44,9 +44,9 @@
<!-- results which **are** attached to an objective -->
<div v-for="g in goalsPicked">
<div>
<div class="item-title" @click="removeGoal(g)">
<i class="fa fa-times"></i>
<div class="item-title">
{{ g.goal.title.fr }}
<a @click="removeGoal(g)"></a>
</div>
</div>
<div>
@ -61,10 +61,9 @@
<p>{{ $t('available_goals_text') }}</p>
<ul class="list-objectives">
<li v-for="g in availableForCheckGoal" class="badge bg-primary" @click="addGoal(g)">
<i class="fa fa-plus"></i>
{{ g.title.fr }}
<ul class="list-suggest add-items">
<li v-for="g in availableForCheckGoal" @click="addGoal(g)">
<span>{{ g.title.fr }}</span>
</li>
</ul>
</div>
@ -98,10 +97,9 @@
<div class="add_evaluation">
<div v-if="showAddEvaluation">
<p>{{ $t('available_evaluations_text') }}</p>
<ul class="list-evaluations">
<li v-for="e in evaluationsForAction" class="badge bg-primary" @click="addEvaluation(e)">
<i class="fa fa-plus"></i>
{{ e.title.fr }}
<ul class="list-suggest add-items">
<li v-for="e in evaluationsForAction" @click="addEvaluation(e)">
<span>{{ e.title.fr }}</span>
</li>
</ul>
</div>
@ -497,8 +495,8 @@ div#workEditor {
& > div.results_without_objective {
background: repeating-linear-gradient(
45deg,
$gray-500,
$gray-500 10px,
$gray-200,
$gray-200 10px,
$gray-100 10px,
$gray-100 20px
);
@ -537,31 +535,11 @@ div#workEditor {
font-size: 85%;
}
ul.list-evaluations,
ul.list-objectives,
ul.list-results {
list-style-type: none;
padding: 0;
li {
margin: 0.5rem;
&.badge {
padding-bottom: 0;
padding-top: 0;
padding-left: 0;
}
}
}
i.fa {
padding: 0.25rem;
color: $white;
&.fa-plus { background-color: $green; }
&.fa-times { background-color: $red; }
&.fa-pencil { background-color: $orange; }
&.fa-times { color: $red; }
}
}

View File

@ -1,9 +1,10 @@
<template>
<div>
<div class="item-title" @click="removeEvaluation(evaluation)">
<i class="fa fa-fw fa-times"></i>
<div class="item-title">
{{ evaluation.evaluation.title.fr }}
<a @click="removeEvaluation(evaluation)"></a>
</div>
<div v-if="!evaluation.editEvaluation">
<dl class="item-details definition-inline">

View File

@ -1,33 +1,57 @@
<template>
<div v-if="hasResult" class="addResult">
<p v-if="pickedResults.length ===0" class="chill-no-data-statement">
Aucun résultat associé
</p>
<ul class="list-results">
<li v-for="r in pickedResults" class="badge bg-primary" @click="removeResult(r)">
<i class="fa fa-times"></i>
{{ r.title.fr }}
</li>
<template v-if="isExpanded">
<li v-for="r in availableForCheckResults" class="badge bg-primary" @click="addResult(r)">
<i class="fa fa-plus"></i>
<ul class="list-suggest remove-items">
<li v-for="r in pickedResults">
<span>
{{ r.title.fr }}
</li>
</template>
</ul>
<ul class="record_actions">
<li v-if="isExpanded">
<button class="btn btn-hide" @click="toggleSelect">
<i class="fa fa-eye-slash"></i>
Masquer résultats et orientations disponibles
</button>
</li>
<li v-else>
<button class="btn btn-show" @click="toggleSelect">
Afficher résultats et orientations disponibles
</button>
<a @click="removeResult(r)"></a>
</span>
</li>
</ul>
<div class="accordion" id="expandedSuggestions">
<div class="accordion-item">
<h2 class="accordion-header" id="heading_expanded_suggestions">
<button v-if="isExpanded"
class="accordion-button"
type="button"
data-bs-toggle="collapse"
aria-expanded="true"
@click="toggleSelect">
Masquer résultats et orientations disponibles
</button>
<button v-else
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
aria-expanded="false"
@click="toggleSelect">
Afficher résultats et orientations disponibles
</button>
</h2>
<div class="accordion-collapse" id="collapse_expanded_suggestions"
aria-labelledby="heading_expanded_suggestions" data-bs-parent="#expandedSuggestions">
<template v-if="isExpanded">
<ul class="list-suggest add-items">
<li v-for="r in availableForCheckResults" @click="addResult(r)">
<span>{{ r.title.fr }}</span>
</li>
</ul>
</template>
</div>
</div>
</div>
</div>
<div v-if="!hasResult" class="noResult">
<div class="chill-no-data-statement">

View File

@ -4,65 +4,111 @@
{{ 'Resume Accompanying Course'|trans }}
{% endblock %}
{% macro button_person(person) %}
{% if person.isSharingHousehold %}
<li>
<a href="{{ chill_path_add_return_path('chill_person_household_summary', { 'household_id': person.getCurrentHousehold.id }) }}"
class="btn btn-sm btn-chill-beige" title="{{ 'Show household'|trans ~ ' n° ' ~ person.getCurrentHousehold.id }}">
<i class="fa fa-home"></i>
</a>
</li>
{% endif %}
{% macro insert_onthefly(type, entity) %}
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
action: 'show', displayBadge: true,
targetEntity: { name: type, id: entity.id },
buttonText: entity|chill_entity_render_string
} %}
{% endmacro %}
{% block js %}
{{ parent() }}
{{ encore_entry_script_tags('page_accompanying_course_index_person_locate') }}
{{ encore_entry_script_tags('page_accompanying_course_index_masonry') }}
{% endblock %}
{% block content %}
<div class="accompanyingcourse-resume row">
<div class="accompanyingcourse-resume">
{% if 'DRAFT' == accompanyingCourse.step %}
<div class="col-md-6 warnings mb-5">
{% include '@ChillPerson/AccompanyingCourse/_still_draft.html.twig' %}
</div>
{% endif %}
{% if 'DRAFT' != accompanyingCourse.step %}
{% if withoutHousehold|length > 0 %}
<div class="col-md-6 warnings mb-5">
{% include '@ChillPerson/AccompanyingCourse/_join_household.html.twig' %}
<div id="dashboards" class="row" data-masonry='{"percentPosition": true }'>
{% if 'DRAFT' == accompanyingCourse.step %}
<div class="col-4 warnings mb-4">
{% include '@ChillPerson/AccompanyingCourse/_still_draft.html.twig' %}
</div>
{% endif %}
{% endif %}
{% if accompanyingCourse.locationStatus == 'address' or accompanyingCourse.locationStatus == 'none' %}
<div class="col-md-6 warnings mb-5">
{% include '@ChillPerson/AccompanyingCourse/_warning_address.html.twig' %}
</div>
{% endif %}
<div class="col-md-6 location mb-5">
{% if accompanyingCourse.locationStatus == 'person' %}
<h2>{{ 'This course is located by'|trans }}</h2>
<h4>{{ accompanyingCourse.personLocation|chill_entity_render_string }}</h4>
{% elseif accompanyingCourse.locationStatus == 'address' %}
<h4>{{ 'This course has a temporarily location'|trans }}</h4>
{% if 'DRAFT' != accompanyingCourse.step %}
{% if withoutHousehold|length > 0 %}
<div class="col-4 warnings mb-4">
{% include '@ChillPerson/AccompanyingCourse/_join_household.html.twig' %}
</div>
{% endif %}
{% endif %}
{% if accompanyingCourse.locationStatus != 'none' %}
{{ accompanyingCourse.location|chill_entity_render_box }}
{% if accompanyingCourse.locationStatus == 'address'
or accompanyingCourse.locationStatus == 'none' %}
<div class="col-4 warnings mb-4">
{% include '@ChillPerson/AccompanyingCourse/_warning_address.html.twig' %}
</div>
{% endif %}
<div class="col col-sm-6 col-lg-4 location mb-4">
{% if accompanyingCourse.locationStatus == 'person' %}
<h2>{{ 'This course is located by'|trans }}</h2>
<h4>{{ accompanyingCourse.personLocation|chill_entity_render_string }}</h4>
{% elseif accompanyingCourse.locationStatus == 'address' %}
<h4>{{ 'This course has a temporarily location'|trans }}</h4>
{% endif %}
{% if accompanyingCourse.locationStatus != 'none' %}
{{ accompanyingCourse.location|chill_entity_render_box }}
{% endif %}
</div>
{% if accompanyingCourse.participations is not empty %}
<div class="col col-sm-6 col-lg-4 persons mb-4">
<h4 class="item-key">{{ 'Persons associated'|trans }}</h4>
{% for r in accompanyingCourse.participations %}
{{ _self.insert_onthefly('person', r.person) }}
{% endfor %}
</div>
{% endif %}
{% if accompanyingCourse.resources is not empty %}
<div class="col col-sm-6 col-lg-4 resources mb-4">
<h4 class="item-key">{{ 'Resources'|trans }}</h4>
{% for r in accompanyingCourse.resources %}
{% if r.person is not null %}
{{ _self.insert_onthefly('person', r.person) }}
{% elseif r.thirdParty is not null %}
{{ _self.insert_onthefly('thirdparty', r.thirdParty) }}
{% endif %}
{% endfor %}
</div>
{% endif %}
{% if accompanyingCourse.scopes is not empty %}
<div class="col col-sm-6 col-lg-4 scopes mb-4">
<h4 class="item-key">{{ 'Scopes'|trans }}</h4>
<div>
{% for s in accompanyingCourse.scopes %}
<span>{{ s.name|localize_translatable_string|capitalize }}</span>{% if not loop.last %}, {% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{% if accompanyingCourse.requestorPerson is not null or accompanyingCourse.requestorThirdParty is not null %}
<div class="col col-sm-6 col-lg-4 requestor mb-4">
{% if accompanyingCourse.requestorPerson is not null %}
<h4 class="item-key">{{ 'Requestor'|trans }}</h4>
{{ _self.insert_onthefly('person', accompanyingCourse.requestorPerson) }}
{% elseif accompanyingCourse.requestorThirdParty is not null %}
<h4 class="item-key">{{ 'Requestor'|trans }}</h4>
{{ _self.insert_onthefly('thirdparty', accompanyingCourse.requestorThirdParty) }}
{% endif %}
</div>
{% endif %}
</div>
<div class="social-actions mb-5">
<div class="social-actions my-4">
<h2 class="mb-3 d-none">{{ 'Last social actions'|trans }}</h2>
{% include 'ChillPersonBundle:AccompanyingCourseWork:list_recent_by_accompanying_period.html.twig' with {'buttonText': false } %}
</div>
{% block contentActivity %}
<div class="activities mb-5">
<div class="activities my-4">
{% set person = null %}
{% set person_id = null %}

View File

@ -1,6 +1,8 @@
<div class="accompanying_course_work-list">
{% for w in works | slice(0,5) %}
<a href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_edit', { 'id': w.id }) }}"></a>
<a href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_edit', { 'id': w.id }) }}"
class="badge-link" title="{{ 'crud.social_action.title_link'|trans }}">
<h2 class="badge-title">
<span class="title_label">
@ -9,7 +11,7 @@
<span class="title_action">
{{ w.socialAction|chill_entity_render_string }}
<ul class="small_in_title">
<ul class="small_in_title columns mt-3">
<li>
<span class="item-key">{{ 'accompanying_course_work.start_date'|trans ~ ' : ' }}</span>
<b>{{ w.startDate|format_date('short') }}</b>
@ -22,6 +24,50 @@
{% endif %}
</ul>
<ul class="small_in_title">
{% if w.handlingThierParty %}
<li>
<span class="item-key">{{ 'Thirdparty handling'|trans ~ ' : ' }}</span>
<span class="badge-thirdparty">{{ w.handlingThierParty|chill_entity_render_box }}</span>
</li>
{% endif %}
<li class="associated-persons">
<span class="item-key">{{ 'Participants'|trans ~ ' : ' }}</span>
{% for p in w.persons %}
<span class="badge-person">{{ p|chill_entity_render_box }}</span>
{% endfor %}
</li>
</ul>
<ul class="list-content my-3">
<li class="social-issues">
{{ w.socialAction.issue|chill_entity_render_box }}
</li>
</ul>
<ul class="small_in_title evaluations mb-3">
{% for e in w.accompanyingPeriodWorkEvaluations %}
<li>
<span class="item-key">{{ 'accompanying_course_work.social_evaluation'|trans ~ ' : ' }}</span>
{{ e.evaluation.title|localize_translatable_string }}
<ul class="columns">
{% if e.startDate %}
<li>
<span class="item-key">{{ 'accompanying_course_work.start_date'|trans ~ ' : ' }}</span>
<b>{{ e.startDate|format_date('short') }}</b>
</li>
{% endif %}
{% if e.endDate %}
<li>
<span class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
<b>{{ e.endDate|format_date('short') }}</b>
</li>
{% endif %}
</ul>
</li>
{% endfor %}
</ul>
<div class="metadata text-end" style="font-size: 60%">
{{ 'Last updated by'|trans }}
<span class="user">{{ w.updatedBy|chill_entity_render_box }}</span>:
@ -30,6 +76,8 @@
</span>
</h2>
</a>{# {{ dump(w) }} #}
{% endfor %}
</div>

View File

@ -17,4 +17,5 @@ module.exports = function(encore, entries)
encore.addEntry('page_household_edit_metadata', __dirname + '/Resources/public/page/household_edit_metadata/index.js');
encore.addEntry('page_person', __dirname + '/Resources/public/page/person/index.js');
encore.addEntry('page_accompanying_course_index_person_locate', __dirname + '/Resources/public/page/accompanying_course_index/person_locate.js');
encore.addEntry('page_accompanying_course_index_masonry', __dirname + '/Resources/public/page/accompanying_course_index/masonry.js');
};

View File

@ -205,6 +205,10 @@ See accompanying periods: Voir toutes les périodes d'accompagnement
See accompanying period: Voir la période
Edit accompanying period: Modifier la période
See this period: Voir cette période
Requestor: Demandeur
No requestor: Pas de demandeur
No resources: "Pas d'interlocuteurs privilégiés"
Persons associated: Usagers concernés
Referrer: Référent
Some peoples does not belong to any household currently. Add them to an household soon: Certaines personnes n'appartiennent à aucun ménage actuellement. Renseignez leur appartenance à un ménage dès que possible.
Add to household now: Ajouter à un ménage
@ -330,6 +334,7 @@ crud:
add_new: Ajouter une nouvelle action d'accompagnements
title_new: Nouvelle action d'accompagnements
title_edit: Modifier l'action d'accompagnements
title_link: Voir l'action d'accompagnement
social_goal:
index:
title: Liste des objectifs d'action d'accompagnements
@ -430,6 +435,7 @@ accompanying_course_work:
goal: Objectif - motif - dispositif
Any work: Aucune action d'accompagnement
remove: Supprimer une action d'accompagnement
social_evaluation: Évaluation
#
Person addresses: Adresses de résidence

View File

@ -85,3 +85,6 @@ crud:
3party_3party:
index:
add_new: Créer
Thirdparty handling: Tiers traitant
Thirdparty workers: Tiers intervenants