Merge branch 'post-prototypage' into 'master'

Post prototypage: vue household integration

See merge request Chill-Projet/chill-bundles!141
This commit is contained in:
Mathieu Jaumotte 2021-09-06 08:00:29 +00:00
commit 406426111a
33 changed files with 431 additions and 316 deletions

View File

@ -73,7 +73,7 @@
{% endif %}
{% if t.commentVisible %}
<dt class="inline">{{ 'Comment'|trans }}</dt>
<dt class="inline">{{ 'activity.comment'|trans }}</dt>
{%- if entity.comment.empty -%}
<dd><span class="chill-no-data-statement">{{ 'No comment associated'|trans }}</span></dd>
{%- else -%}
@ -120,17 +120,17 @@
{{ 'Edit'|trans }}
</a>
</li>
{# TODO
{% if is_granted('CHILL_ACTIVITY_DELETE', entity) %}
#}
<li>
<a href="{{ path('chill_activity_activity_delete', { 'id': entity.id, 'person_id' : person_id, 'accompanying_period_id': accompanying_course_id } ) }}" class="btn btn-delete">
{{ 'Delete'|trans }}
</a>
</li>
{#
{% endif %}
#}

View File

@ -19,6 +19,7 @@ $chill-theme-buttons: (
"view": $chill-blue,
"misc": $gray-300,
"cancel": $gray-300,
"choose": $gray-300
);
@each $button, $color in $chill-theme-buttons {
@ -68,6 +69,7 @@ $chill-theme-buttons: (
// &.btn-action::before,
&.btn-delete::before,
&.btn-remove::before,
&.btn-choose::before,
&.btn-cancel::before {
font: normal normal normal 14px/1 ForkAwesome;
margin-right: 0.5em;
@ -91,6 +93,7 @@ $chill-theme-buttons: (
&.btn-delete::before { content: "\f1f8"; } // fa-trash
&.btn-remove::before { content: "\f00d"; } // fa-times
&.btn-cancel::before { content: "\f060"; } // fa-arrow-left
&.btn-choose::before { content: "\f00c"; } // fa-check // f046 fa-check-square-o
}

View File

@ -4,6 +4,8 @@
<VueMultiselect
id="addressSelector"
v-model="value"
@search-change="listenInputSearch"
ref="addressSelector"
@select="selectAddress"
name="field"
track-by="id"
@ -17,7 +19,8 @@
:options="addresses">
</VueMultiselect>
</div>
<div class="custom-address row g-1" v-if="writeNewAddress || writeNewPostalCode">
<div class="custom-address row g-1" v-if="writeNewAddress || writeNewPostalCode || (isEnteredCustomAddress && !isAddressSelectorOpen)">
<div class="col-10">
<div class="form-floating">
<input class="form-control"
@ -60,6 +63,12 @@ export default {
writeNewPostalCode() {
return this.entity.selected.writeNew.postCode;
},
isAddressSelectorOpen() {
return this.$refs.addressSelector.$data.isOpen;
},
isEnteredCustomAddress() {
return this.$data.value !== null && typeof this.$data.value.text !== 'undefined';
},
addresses() {
return this.entity.loaded.addresses;
},
@ -90,6 +99,42 @@ export default {
this.entity.selected.address.streetNumber = value.streetNumber;
this.updateMapCenter(value.point);
},
listenInputSearch(query) {
//console.log('listenInputSearch', query, this.isAddressSelectorOpen);
if (this.isAddressSelectorOpen) {
this.$data.value = { text: query };
} else if (this.isEnteredCustomAddress) {
let addr = this.splitAddress(this.$data.value.text);
this.entity.selected.address.street = addr.street;
this.entity.selected.address.streetNumber = addr.number;
}
},
splitAddress(address) {
let substr = address
.split(',')
.map(s => s.trim());
if (substr.length === 1) {
substr = address.split(' ');
}
let decimal = [];
substr.forEach((s, i) => { decimal[i] = /^\d+$/.test(s) });
if (decimal[0] === true) {
return {
number: substr.shift(),
street: substr.join(' ')
}
}
else if (decimal[decimal.length - 1] === true) {
return {
number: substr.pop(),
street: substr.join(' ')
}
}
return {
number: '',
street: substr.join(' ')
}
},
addAddress() {
this.entity.selected.writeNew.address = true;
}

View File

@ -4,6 +4,8 @@
<VueMultiselect
id="citySelector"
v-model="value"
@search-change="listenInputSearch"
ref="citySelector"
@select="selectCity"
name="field"
track-by="id"
@ -18,7 +20,7 @@
</VueMultiselect>
</div>
<div class="custom-postcode row g-1" v-if="writeNewPostcode">
<div class="custom-postcode row g-1" v-if="writeNewPostcode || (isEnteredCustomCity && !isCitySelectorOpen)">
<div class="col-4">
<div class="form-floating">
<input class="form-control"
@ -59,6 +61,12 @@ export default {
writeNewPostcode() {
return this.entity.selected.writeNew.postcode;
},
isCitySelectorOpen() {
return this.$refs.citySelector.$data.isOpen;
},
isEnteredCustomCity() {
return this.$data.value !== null && typeof this.$data.value.text !== 'undefined';
},
cities() {
return this.entity.loaded.cities;
},
@ -81,7 +89,7 @@ export default {
},
methods: {
transName(value) {
return `${value.code}-${value.name}`
return (value.code && value.name) ? `${value.code}-${value.name}` : '';
},
selectCity(value) {
this.entity.selected.city = value;
@ -90,6 +98,45 @@ export default {
this.$emit('getReferenceAddresses', value);
this.focusOnAddress();
},
listenInputSearch(query) {
console.log('listenInputSearch', query, this.isCitySelectorOpen);
if (this.isCitySelectorOpen) {
this.$data.value = { text: query };
} else if (this.isEnteredCustomCity) {
let city = this.splitCity(this.$data.value.text);
this.$refs.citySelector.currentOptionLabel = '';
this.entity.selected.city = city;
this.entity.selected.postcode.name = city.name;
this.entity.selected.postcode.code = city.code;
}
},
splitCity(city) {
let substr = city
.split('-')
.map(s => s.trim());
if (substr.length === 1) {
substr = city.split(' ');
}
console.log('substr', substr);
let decimal = [];
substr.forEach((s, i) => { decimal[i] = /^\d+$/.test(s) });
if (decimal[0] === true) {
return {
code: substr.shift(),
name: substr.join(' ')
}
}
else if (decimal[decimal.length - 1] === true) {
return {
code: substr.pop(),
name: substr.join(' ')
}
}
return {
code: '',
name: substr.join(' ')
}
},
addPostcode() {
this.entity.selected.writeNew.postcode = true;
}

View File

@ -134,7 +134,9 @@ export default {
methods: {
focusOnAddress() {
const addressSelector = document.getElementById('addressSelector');
addressSelector.focus();
if (addressSelector !== null) {
addressSelector.focus();
}
},
updateMapCenter(point) {
//console.log('point', point);

View File

@ -48,7 +48,7 @@
<script>
import { dateToISO, ISOToDate, ISOToDatetime } from 'ChillMainAssets/chill/js/date.js';
import ShowAddress from './ShowAddress.vue';
import ShowAddress from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
export default {
name: 'ShowAddressPane',

View File

@ -24,7 +24,7 @@ const addressMessages = {
flat: 'Appartement',
buildingName: 'Nom du bâtiment',
extra: 'Complément d\'adresse',
distribution: 'Service particulier de distribution',
distribution: 'Cedex',
create_postal_code: 'Localité inconnue. Cliquez ici pour créer une nouvelle localité',
postalCode_name: 'Nom',
postalCode_code: 'Code postal',

View File

@ -16,7 +16,7 @@
</p>
</component>
<div v-if="isMultiline">
<div v-if="isMultiline === true">
<div v-if="address.floor">
<span class="floor">
<b>{{ $t('floor') }}</b>: {{ address.floor }}
@ -37,42 +37,20 @@
<b>{{ $t('flat') }}</b>: {{ address.flat }}
</span>
</div>
<div>
<div v-if="address.floor">
<span class="floor">
<b>{{ $t('floor') }}</b>: {{ address.floor }}
</span>
</div>
<div v-if="address.corridor">
<span class="corridor">
<b>{{ $t('corridor') }}</b>: {{ address.corridor }}
</span>
</div>
<div v-if="address.steps">
<span class="steps">
<b>{{ $t('steps') }}</b>: {{ address.steps }}
</span>
</div>
<div v-if="address.flat">
<span class="flat">
<b>{{ $t('flat') }}</b>: {{ address.flat }}
</span>
</div>
<div v-if="address.buildingName">
<div v-if="address.buildingName">
<span class="buildingName">
<b>{{ $t('buildingName') }}</b>: {{ address.buildingName }}
</span>
</div>
<div v-if="address.extra">
</div>
<div v-if="address.extra">
<span class="extra">
<b>{{ $t('extra') }}</b>: {{ address.extra }}
</span>
</div>
<div v-if="address.distribution">
</div>
<div v-if="address.distribution">
<span class="distribution">
<b>{{ $t('distribution') }}</b>: {{ address.distribution }}
</span>
</div>
</div>
</div>
@ -81,7 +59,7 @@
<script>
export default {
name: 'ShowAddress',
name: 'AddressRenderBox',
props: {
address: {
type: Object
@ -92,11 +70,12 @@ export default {
}
},
computed: {
component(){
return this.isMultiline == true ? "div" : "span";
component() {
return this.isMultiline === true ? "div" : "span";
},
multiline(){
return this.isMultiline == true ? "multiline" : "";
multiline() {
//console.log(this.isMultiline, typeof this.isMultiline);
return this.isMultiline === true ? "multiline" : "";
}
}
};

View File

@ -43,7 +43,7 @@ const messages = {
check_all: "cocher tout",
reset: "réinitialiser",
redirect: {
person: "Quitter la page et ouvrir le dossier",
person: "Quitter la page et ouvrir la fiche de l'usager",
thirdparty: "Quitter la page et voir le tiers",
}
},
@ -57,7 +57,7 @@ const messages = {
show: {
person: "Détails de l'usager",
thirdparty: "Détails du tiers",
file_person: "Ouvrir le dossier",
file_person: "Ouvrir la fiche de l'usager",
file_thirdparty: "Voir le Tiers",
},
edit: {
@ -81,7 +81,8 @@ const messages = {
type: {
thirdparty: "Tiers",
person: "Usager"
}
},
holder: "Titulaire"
}
}
};

View File

@ -139,7 +139,7 @@ class AccompanyingCourseController extends Controller
/**
* History page of Accompanying Course section
*
* the page show anti chronologic history with all actions, title of page is 'accompanying course details'
* the page show anti chronologic history with all actions, title of page is 'Accompanying Course History'
*
* @Route("/{_locale}/parcours/{accompanying_period_id}/history", name="chill_person_accompanying_course_history")
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})

View File

@ -244,7 +244,9 @@ final class PersonController extends AbstractController
'label' => 'Add the person'
])->add('createPeriod', SubmitType::class, [
'label' => 'Add the person and create an accompanying period'
]);
])->add('createHousehold', SubmitType::class, [
'label' => 'Add the person and create an household'
]); // TODO createHousehold form action
$form->handleRequest($request);

View File

@ -54,7 +54,7 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
return;
}
$menu->addChild($this->translator->trans('Accompanying Course Details'), [
$menu->addChild($this->translator->trans('Accompanying Course History'), [
'route' => 'chill_person_accompanying_course_history',
'routeParameters' => [
'accompanying_period_id' => $period->getId()

View File

@ -28,7 +28,7 @@
<script>
import {mapState} from "vuex";
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
import ShowAddress from "ChillMainAssets/vuejs/Address/components/ShowAddress";
import ShowAddress from "ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue";
export default {
name: "ButtonLocation",

View File

@ -63,7 +63,7 @@
<script>
import { mapState } from "vuex";
import AddAddress from 'ChillMainAssets/vuejs/Address/components/AddAddress.vue';
import ShowAddress from 'ChillMainAssets/vuejs/Address/components/ShowAddress.vue';
import ShowAddress from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
export default {
name: "CourseLocation",

View File

@ -1,5 +1,5 @@
<template>
<person-render-box
<person-render-box render="bloc"
:options="{
addInfo : true,
addId : false,

View File

@ -30,7 +30,7 @@
</template>
</third-party-render-box>
<person-render-box v-else-if="accompanyingCourse.requestor.type == 'person'"
<person-render-box render="bloc" v-else-if="accompanyingCourse.requestor.type == 'person'"
:person="accompanyingCourse.requestor"
:options="{
addLink: false,

View File

@ -1,5 +1,5 @@
<template>
<person-render-box
<person-render-box render="bloc"
v-if="resource.resource.type === 'person'"
:person="resource.resource"
:options="{ addInfo : true, addId : false, addEntity: true, addLink: false, addAltNames: true, addAge : false, hLevel : 3 }"

View File

@ -35,7 +35,7 @@
<ul>
<li v-for="p in personsReachables" :key="p.id">
<input type="checkbox" :value="p.id" v-model="personsPicked">
<person :person="p"></person>
<person-render-box render="badge" :person="p"></person-render-box>
</li>
</ul>
</div>
@ -124,7 +124,7 @@
import { mapState, mapActions, mapGetters } from 'vuex';
import VueMultiselect from 'vue-multiselect';
import { dateToISO, ISOToDate } from 'ChillMainAssets/chill/js/date.js';
import Person from 'ChillPersonAssets/vuejs/_components/Person/Person.vue';
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
const i18n = {
messages: {
@ -145,7 +145,7 @@ export default {
name: 'App',
components: {
VueMultiselect,
Person,
PersonRenderBox,
},
methods: {
submit() {

View File

@ -122,7 +122,7 @@
<ul>
<li v-for="p in personsReachables" :key="p.id">
<input v-model="personsPicked" :value="p.id" type="checkbox">
<person :person="p"></person>
<person-render-box render="badge" :person="p"></person-render-box>
</li>
</ul>
</div>
@ -229,9 +229,9 @@ import CKEditor from '@ckeditor/ckeditor5-vue';
import ClassicEditor from 'ChillMainAssets/module/ckeditor5/index.js';
import AddResult from './components/AddResult.vue';
import AddEvaluation from './components/AddEvaluation.vue';
import Person from 'ChillPersonAssets/vuejs/_components/Person/Person.vue';
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
import ShowAddress from 'ChillMainAssets/vuejs/Address/components/ShowAddress.vue';
import ShowAddress from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
const i18n = {
messages: {
@ -274,7 +274,7 @@ export default {
AddResult,
AddEvaluation,
AddPersons,
Person,
PersonRenderBox,
ShowAddress,
},
i18n,

View File

@ -25,7 +25,7 @@
<div class="item-row">
<div class="item-col">
<div>
<person :person="conc.person"></person>
<person-render-box render="badge" :person="conc.person"></person-render-box>
</div>
<div v-if="conc.person.birthdate !== null">
{{ $t('person.born', {'gender': conc.person.gender} ) }}
@ -126,7 +126,7 @@ div.person {
<script>
import { mapGetters } from 'vuex';
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
import Person from 'ChillPersonAssets/vuejs/_components/Person/Person.vue';
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
import MemberDetails from './MemberDetails.vue';
import { ISOToDatetime } from 'ChillMainAssets/chill/js/date.js';
@ -135,7 +135,7 @@ export default {
components: {
AddPersons,
MemberDetails,
Person,
PersonRenderBox,
},
computed: {
...mapGetters([

View File

@ -2,23 +2,29 @@
<h2>{{ $t('household_members_editor.household_part') }}</h2>
<div v-if="hasHousehold">
<div>
<household-viewer :household="household"></household-viewer>
<div class="flex-table">
<div class="item-bloc">
<household-render-box :household="household" :isAddressMultiline="true"></household-render-box>
</div>
</div>
<div v-if="isHouseholdNew && !hasHouseholdAddress">
<h3 >À quelle adresse habite ce ménage ?</h3>
<h3>{{ $t('household_members_editor.household.where_live_the_household') }}</h3>
<div v-if="filterAddressesSuggestion.length > 0" class="flex-table householdAddressSuggestionList">
<div v-for="a in filterAddressesSuggestion" class="item-bloc">
<show-address :address="a"></show-address>
<button class="btn btn-action" @click="setHouseholdAddress(a)">
Le ménage habite cette adresse
</button>
<ul class="record_actions">
<li>
<button class="btn btn-action" @click="setHouseholdAddress(a)">
{{ $t('household_members_editor.household.household_live_to_this_address') }}
</button>
</li>
</ul>
</div>
</div>
<div v-else>
<span class="chill-no-data-statement">Aucune adresse à suggérer</span>
<div v-else>
<span class="chill-no-data-statement">{{ $t('household_members_editor.household.no_suggestions') }}</span>
</div>
<ul class="record_actions">
@ -39,7 +45,7 @@
<ul class="record_actions">
<li >
<button class="btn btn-misc" @click="removeHouseholdAddress">
Supprimer cette adresse
{{ $t('household_members_editor.household.delete_this_address') }}
</button>
</li>
</ul>
@ -54,20 +60,20 @@
</div>
<ul v-if="allowChangeHousehold" class="record_actions">
<li v-if="!showHouseholdSuggestion">
<li v-if="!showHouseholdSuggestion" class="cancel">
<button
class="btn btn-misc"
@click="toggleHouseholdSuggestion"
>
><i class="fa fa-fw fa-caret-right"></i>
{{ $tc('household_members_editor.show_household_suggestion',
countHouseholdSuggestion) }}
</button>
</li>
<li v-if="showHouseholdSuggestion && hasHouseholdSuggestion">
<li v-if="showHouseholdSuggestion && hasHouseholdSuggestion" class="cancel">
<button
class="btn btn-misc"
@click="toggleHouseholdSuggestion"
>
><i class="fa fa-fw fa-caret-down"></i>
{{ $t('household_members_editor.hide_household_suggestion') }}
</button>
</li>
@ -95,74 +101,37 @@
<div class="householdSuggestions">
<div v-if="showHouseholdSuggestion && hasHouseholdSuggestion">
<p>{{ $t('household_members_editor.household_for_participants_accompanying_period') }}:</p>
<div class="householdSuggestionList">
<div
v-for="h in filterHouseholdSuggestionByAccompanyingPeriod"
class="item"
>
<household-viewer :household="h"></household-viewer>
<h3>{{ $t('household_members_editor.suggestions') }}</h3>
<p>{{ $t('household_members_editor.household_for_participants_accompanying_period') }}:</p>
<div class="flex-table householdSuggestionList">
<div v-for="h in filterHouseholdSuggestionByAccompanyingPeriod" class="item-bloc">
<household-render-box :household="h"></household-render-box>
<ul class="record_actions">
<li>
<button class="btn btn-misc" @click="selectHousehold(h)">
<button class="btn btn-sm btn-choose" @click="selectHousehold(h)">
{{ $t('household_members_editor.select_household') }}
</button>
</li>
</ul>
</div >
</div>
</div>
</div>
</div>
</template>
<style lang="scss">
div.householdAddressSuggestionList {
/*
display: flex;
list-style-type: none;
padding: 0;
*/
& > li {
}
}
.householdSuggestionList {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
& > .item {
margin-bottom: 0.8rem;
width: calc(50% - 1rem);
border: 1px solid var(--chill-light-gray);
padding: 0.5rem 0.5rem 0 0.5rem;
ul.record_actions {
margin-bottom: 0;
}
}
}
</style>
<script>
import { mapGetters, mapState } from 'vuex';
import HouseholdViewer from 'ChillPersonAssets/vuejs/_components/Household/Household.vue';
import ShowAddress from 'ChillMainAssets/vuejs/Address/components/ShowAddress.vue';
import HouseholdRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue';
import ShowAddress from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
import AddAddress from 'ChillMainAssets/vuejs/Address/components/AddAddress.vue';
export default {
name: 'Household',
components: {
HouseholdViewer,
HouseholdRenderBox,
ShowAddress,
AddAddress,
},
@ -272,3 +241,42 @@ export default {
};
</script>
<style lang="scss">
div#household_members_editor div,
div.householdSuggestionList {
&.flex-table div.item-bloc div.item-row div.item-col {
&:first-child {
width: 25%;
}
&:last-child {
display: initial;
}
}
}
/*
div.householdAddressSuggestionList {
display: flex;
list-style-type: none;
padding: 0;
& > li {}
}
.householdSuggestionList {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
& > .item {
margin-bottom: 0.8rem;
width: calc(50% - 1rem);
border: 1px solid var(--chill-light-gray);
padding: 0.5rem 0.5rem 0 0.5rem;
ul.record_actions {
margin-bottom: 0;
}
}
}
*/
</style>

View File

@ -3,7 +3,7 @@
<div class="item-row">
<div class="item-col">
<div>
<person :person="conc.person"></person>
<person-render-box render="badge" :person="conc.person"></person-render-box>
<span v-if="isHolder" class="badge bg-primary holder">
{{ $t('household_members_editor.holder') }}
</span>
@ -73,14 +73,14 @@ div.participation-details {
<script>
import { mapGetters } from 'vuex';
import Person from 'ChillPersonAssets/vuejs/_components/Person/Person.vue';
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
import CKEditor from '@ckeditor/ckeditor5-vue';
import ClassicEditor from 'ChillMainAssets/module/ckeditor5/index.js';
export default {
name: 'MemberDetails',
components: {
Person,
PersonRenderBox,
ckeditor: CKEditor.component,
},
props: [

View File

@ -7,10 +7,14 @@ const appMessages = {
household: {
no_household_choose_one: "Aucun ménage de destination. Choisissez un ménage. Les usagers concernés par la modification apparaitront ensuite.",
new_household: "Nouveau ménage",
create_household: "Créer un ménage",
create_household: "Créer un ménage de destination",
search_household: "Chercher un ménage",
will_leave_any_household: "Ne rejoignent pas de ménage",
leave_without_household: "Sans nouveau ménage"
leave_without_household: "Sans nouveau ménage",
where_live_the_household: "À quelle adresse habite ce ménage ?",
household_live_to_this_address: "Le ménage habite cette adresse",
no_suggestions: "Aucune adresse à suggérer",
delete_this_address: "Supprimer cette adresse",
},
concerned: {
title: "Nouveaux membres du ménage",
@ -29,10 +33,11 @@ const appMessages = {
remove_position: "Retirer des {position}",
remove_concerned: "Ne plus transférer",
household_part: "Ménage de destination",
suggestions: "Suggestions",
hide_household_suggestion: "Masquer les suggestions",
show_household_suggestion: 'Aucune suggestion | Afficher une suggestion | Afficher {count} suggestions',
household_for_participants_accompanying_period: "Ces ménages partagent le même parcours",
select_household: "Choisir ce ménage",
select_household: "Sélectionner",
dates_title: "Période de validité",
dates: {
start_date: "Début de validité",

View File

@ -0,0 +1,126 @@
<template>
<section class="chill-entity entity-household">
<div class="item-row">
<div class="item-col">
<!-- identifier -->
<div v-if="isHouseholdNew()" class="h4">
<i class="fa fa-home"></i>
{{ $t('new_household') }}
</div>
<div v-else class="h4">
<i class="fa fa-home"></i>
{{ $t('household_number', { number: household.id } ) }}
</div>
</div>
<div class="item-col">
<ul class="list-content">
<!-- member part -->
<li v-if="hasCurrentMembers" class="members" :title="$t('current_members')">
<template v-for="m in currentMembers()" :key="m.id">
<person-render-box render="badge"
:person="m.person"
:options="{
isHolder: m.holder,
addLink: true
}">
</person-render-box>
</template>
</li>
<li v-else class="members" :title="$t('current_members')">
<p class="chill-no-data-statement">{{ $t('no_members_yet') }}</p>
</li>
<!-- address part -->
<li v-if="hasAddress()">
<show-address :address="household.current_address" :isMultiline="isMultiline"></show-address>
</li>
<li v-else>
<span class="chill-no-data-statement">{{ $t('no_current_address') }}</span>
</li>
</ul>
</div>
</div>
</section>
</template>
<script>
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
import ShowAddress from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
const i18n = {
"messages": {
"fr": {
"household_number": "Ménage n°{number}",
"current_members": "Membres actuels",
"no_current_address": "Sans adresse actuellement",
"new_household": "Nouveau ménage",
"no_members_yet": "Aucun membre actuellement",
"holder": "titulaire",
}
}
};
export default {
name: 'HouseholdRenderBox',
props: ['household', 'isAddressMultiline'],
components: {
PersonRenderBox,
ShowAddress,
},
i18n,
computed: {
isMultiline() {
return (typeof this.isAddressMultiline !== 'undefined') ? this.isAddressMultiline : false;
}
},
methods: {
hasCurrentMembers() {
return this.household.current_members_id.length > 0;
},
currentMembers() {
return this.household.members.filter(m => this.household.current_members_id.includes(m.id))
.sort((a, b) => {
if (a.position.ordering < b.position.ordering) {
return -1;
}
if (a.position.ordering > b.position.ordering) {
return 1;
}
if (a.holder && !b.holder) {
return -1;
}
if (!a.holder && b.holder) {
return 1;
}
return 0;
});
},
currentMembersLength() {
return this.household.current_members_id.length;
},
isHouseholdNew() {
return !Number.isInteger(this.household.id);
},
hasAddress() {
return this.household.current_address !== null;
}
}
};
</script>
<style lang="scss">
section.chill-entity {
&.entity-household {
ul.list-content li::marker {
content: '';
}
}
}
</style>

View File

@ -1,14 +1,14 @@
<template>
<div class="item-bloc">
<div v-if="render === 'bloc'" class="item-bloc">
<section class="chill-entity entity-person">
<div class="item-row entity-bloc">
<div class="item-row entity-bloc">
<div class="item-col">
<div class="entity-label">
<div :class="'denomination h' + options.hLevel">
<a v-if="this.options.addLink == true" href="#">
<a v-if="options.addLink === true" :href="getUrl">
<span class="firstname">{{ person.firstName }}</span>
<span class="lastname">{{ person.lastName }}</span>
<span v-if="person.altNames && options.addAltNames == true" class="altnames">
@ -84,21 +84,39 @@
<slot name="record-actions"></slot>
</div>
</div>
</div>
</section>
</div>
</div>
<span v-if="render === 'badge'" class="chill-entity entity-person badge-person">
<a v-if="options.addLink === true" :href="getUrl">
<span v-if="options.isHolder" class="fa-stack fa-holder" :title="$t('renderbox.holder')">
<i class="fa fa-circle fa-stack-1x text-success"></i>
<i class="fa fa-stack-1x">T</i>
</span>
{{ person.text }}
</a>
<span v-else>
<span v-if="options.isHolder" class="fa-stack fa-holder" :title="$t('renderbox.holder')">
<i class="fa fa-circle fa-stack-1x text-success"></i>
<i class="fa fa-stack-1x">T</i>
</span>
{{ person.text }}
</span>
</span>
</template>
<script>
import {dateToISO} from 'ChillMainAssets/chill/js/date.js';
import ShowAddress from 'ChillMainAssets/vuejs/Address/components/ShowAddress.vue';
import ShowAddress from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
export default {
name: "PersonRenderBox",
components: {
ShowAddress
},
props: ['person', 'options'],
props: ['person', 'options', 'render'],
computed: {
getGender: function() {
return this.person.gender == 'woman' ? 'renderbox.birthday.woman' : 'renderbox.birthday.man';
@ -118,8 +136,10 @@ export default {
return dateToISO(date);
},
deathdate: function(){
var date = new Date(this.person.deathdate.datetime);
return dateToISO(date);
if (typeof this.person.deathdate !== 'undefined') {
var date = new Date(this.person.deathdate.datetime);
return dateToISO(date);
}
},
altNameLabel: function(){
for(let i = 0; i < this.person.altNames.length; i++){
@ -131,12 +151,26 @@ export default {
return this.person.altNames[i].key
}
},
getUrl() {
return `/fr/person/${this.person.id}/general`;
}
}
}
</script>
<style lang='scss'>
span.fa-holder {
width: 1em;
margin: -10px 0.3em -8px 0;
i:last-child {
font-weight: 900;
color: white;
font-size: 70%;
font-family: "Open Sans Extrabold";
}
}
.lastname:before{
content: " "
}
@ -149,6 +183,7 @@ div.flex-table {
}
div.item-col:last-child {
justify-content: flex-start;
}
}
}

View File

@ -1,139 +0,0 @@
<template>
<div class="chill-entity chill-entity__household">
<!-- identifier -->
<div v-if="isHouseholdNew()" class="identifier">
<i class="fa fa-home"></i>
{{ $t('new_household') }}
</div>
<div v-else class="identifier">
<i class="fa fa-home"></i>
{{ $t('household_number', { number: household.id } ) }}
</div>
<!-- member part -->
<div v-if="hasCurrentMembers" class="members">
<span class="current-members">{{ $t('current_members') }}: </span>
<template v-for="(m, index) in currentMembers()" :key="m.id">
<person :person="m.person"></person>
<span v-if="m.holder">
&nbsp;<span class="badge bg-primary">{{ $t('holder') }}</span>
</span>
<span v-if="index != (currentMembersLength() - 1)">, </span>
</template>
</div>
<div v-else class="members">
<p class="chill-no-data-statement">{{ $t('no_members_yet') }}</p>
</div>
<!-- address part -->
<div v-if="hasAddress()" class="where">
<i class="fa fa-where"></i>
<show-address :address="household.current_address"></show-address>
</div>
<div v-else class="where">
<i class="fa fa-where"></i>
<p class="chill-no-data-statement">{{ $t('no_current_address') }}</p>
</div>
</div>
</template>
<style lang="scss">
.chill-entity__household {
display: grid;
grid-template-areas:
"identifier identifier where"
"who who where"
;
grid-template-columns:
auto auto 30%
;
.identifier {
grid-area: identifier;
font-size: 1.3em;
font-weight: 700;
color: var(--chill-blue);
}
.members {
grid-area: who;
.current-members {
font-weight: 700;
}
}
.where {
grid-area: where
}
}
</style>
<script>
import Person from 'ChillPersonAssets/vuejs/_components/Person/Person.vue';
import ShowAddress from 'ChillMainAssets/vuejs/Address/components/ShowAddress.vue';
const i18n = {
"messages":
{
"fr":
{
"household_number": "Ménage #{number}",
"current_members": "Membres actuels",
"no_current_address": "Sans adresse actuellement",
"new_household": "Nouveau ménage",
"no_members_yet": "Aucun membre actuellement",
"holder": "titulaire",
}
}
}
;
export default {
name: 'Household',
props: ['household'],
components: {
Person,
ShowAddress,
},
i18n,
methods: {
hasCurrentMembers() {
return this.household.current_members_id.length > 0;
},
currentMembers() {
return this.household.members.filter(m => this.household.current_members_id.includes(m.id))
.sort((a, b) => {
if (a.position.ordering < b.position.ordering) {
return -1;
}
if (a.position.ordering > b.position.ordering) {
return 1;
}
if (a.holder && !b.holder) {
return -1;
}
if (!a.holder && b.holder) {
return 1;
}
return 0;
});
},
currentMembersLength() {
return this.household.current_members_id.length;
},
isHouseholdNew() {
return !Number.isInteger(this.household.id);
},
hasAddress() {
return this.household.current_address !== null;
}
}
};
</script>

View File

@ -1,7 +1,7 @@
<template>
<div v-if="action === 'show'">
<div class="flex-table">
<person-render-box
<person-render-box render="bloc"
:person="person"
:options="{
addInfo: true,

View File

@ -1,16 +0,0 @@
<template>
<span class="chill-entity chill-entity__person">
<span class="chill-entity__person__text chill_denomination">
{{ person.text }}
</span>
</span>
</template>
<script>
export default {
name: 'Person',
props: ['person']
}
</script>

View File

@ -1,7 +1,7 @@
{% extends '@ChillPerson/AccompanyingCourse/layout.html.twig' %}
{% block title %}
{{ 'Accompanying Course Details'|trans }}
{{ 'Accompanying Course History'|trans }}
{% endblock %}
{% block content %}
@ -15,8 +15,8 @@
Il faudrait peut-être modifier son adresse comme ceci: `/fr/parcours/{id}/timeline`
</p>
{# start test flex-table
{# start test flex-table
<div class="flex-table">
{% for p in accompanyingCourse.participations %}
<div class="item-bloc">
@ -52,16 +52,16 @@
<li><button type="button" class="btn btn-edit"></button></li>
</ul>
</div>
</div>
<div class="item-row">
Lorem ipsum dolor sit amet, incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, incididunt ut labore et dolore magna aliqua.
</div>
<div class="item-row">
Rhoncus est pellentesque elit eu ultrices vitae auctor.
Rhoncus est pellentesque elit eu ultrices vitae auctor.
</div>
<div class="item-row">
Facilisis gravida neque convallis a cras semper auctor neque.
Facilisis gravida neque convallis a cras semper auctor neque.
</div>
</div>
{% endfor %}
@ -70,5 +70,5 @@
{# end test flex-table #}
{# ==> insert accompanyingCourse vue component #}
<div id="accompanying-course"></div>
<div id="accompanying-course"></div>
{% endblock %}

View File

@ -4,7 +4,7 @@
{% block title 'household.Edit household members'|trans %}
{% block content %}
<div class="col-md-10 col-xxl household-members">
<div class="household-members">
<h1>{{ block('title') }}</h1>
<div id="household_members_editor"></div>

View File

@ -64,10 +64,10 @@
{{ form_start(form) }}
{{ form_row(form.firstName, { 'label' : 'First name'|trans }) }}
{{ form_row(form.lastName, { 'label' : 'Last name'|trans }) }}
{{ form_row(form.firstName, { 'label' : 'First name'|trans }) }}
{% if form.altNames is defined %}
{{ form_widget(form.altNames) }}
{% endif %}
@ -76,12 +76,28 @@
{{ form_row(form.gender, { 'label' : 'Gender'|trans }) }}
<div style="display: none">
{# TODO remove this field (vendee) #}
{{ form_row(form.center, { 'label' : 'Center'|trans }) }}
</div>
<ul class="record_actions sticky-form-buttons">
<li>
{{ form_widget(form.editPerson, { 'attr': { 'class': 'btn btn-create' }}) }}
</li>
<li>
{{ form_widget(form.createPeriod, { 'attr': { 'class': 'btn btn-create' }}) }}
<li class="dropdown">
<a class="btn btn-create dropdown-toggle"
href="#" role="button" id="newPersonMore" data-bs-toggle="dropdown" aria-expanded="false">
{{ 'Add the person'|trans }}
</a>
<ul class="dropdown-menu" aria-labelledby="newPersonMore">
<li>
{{ form_widget(form.editPerson, { 'attr': { 'class': 'dropdown-item' }}) }}
</li>
<li>
{{ form_widget(form.createPeriod, { 'attr': { 'class': 'dropdown-item' }}) }}
</li>
<li>
{{ form_widget(form.createHousehold, { 'attr': { 'class': 'dropdown-item' }}) }}
</li>
</ul>
</li>
</ul>

View File

@ -119,7 +119,8 @@ address_country_code: Code pays
'Alreay existing person': 'Dossiers déjà encodés'
'Add the person': 'Ajouter la personne'
'Add the person and create an accompanying period': "Ajouter la personne et créer une période d'accompagnement"
'Add the person and create an accompanying period': "Créer la personne ET créer une période d'accompagnement"
'Add the person and create an household': "Créer la personne ET créer un ménage"
Show person: Voir le dossier de la personne
'Confirm the creation': 'Confirmer la création'
'You will create this person': 'Vous allez créer le dossier suivant'
@ -372,7 +373,7 @@ Confirmed: en file active
# Accompanying Course
Accompanying Course: Parcours d'accompagnement
Accompanying Course Details: Détails du parcours
Accompanying Course History: Historique du parcours
Resume Accompanying Course: Résumé du parcours
Show Accompanying Course: Voir le parcours
Edit Accompanying Course: Modifier le parcours

View File

@ -57,7 +57,7 @@
</template>
<script>
import ShowAddress from 'ChillMainAssets/vuejs/Address/components/ShowAddress.vue';
import ShowAddress from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
import {dateToISO} from 'ChillMainAssets/chill/js/date.js';
export default {