mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-12 13:24:25 +00:00
Merge remote-tracking branch 'origin/master' into small_issues_421_424
This commit is contained in:
commit
43ef31b93f
10
CHANGELOG.md
10
CHANGELOG.md
@ -11,12 +11,20 @@ and this project adheres to
|
|||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
<!-- write down unreleased development here -->
|
<!-- write down unreleased development here -->
|
||||||
|
* [person] accompanying course: optimisation: do not fetch some resources for the banner (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/409)
|
||||||
|
* [person] accompanying course: close modal when edit participation (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/420)
|
||||||
|
* [person] accompanying course: treat validation error when editing on-the-fly entities (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/420)
|
||||||
|
* [activity] show activity attendee (présence) in the activity list (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/412)
|
||||||
|
* [activity] admin: change validation rule for social action visible field (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/413)
|
||||||
* [parcours]: component added to change the opening date of a parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/411)
|
* [parcours]: component added to change the opening date of a parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/411)
|
||||||
* [search]: listing of parcours display changed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/410)
|
* [search]: listing of parcours display changed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/410)
|
||||||
* [user]: page with accompanying periods to which is user is referent (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/408)
|
* [user]: page with accompanying periods to which is user is referent (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/408)
|
||||||
* [person]: Comment on marital status is possible even if marital status is not defined (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/421)
|
* [person]: Comment on marital status is possible even if marital status is not defined (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/421)
|
||||||
* [parcours]: In the list of person results the requestor is not displayed if defined as anonymous (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/424)
|
* [parcours]: In the list of person results the requestor is not displayed if defined as anonymous (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/424)
|
||||||
* [bugfix]: modal closes and newly created person/thirdparty is selected when multiple persons/thirdparties are created through the modal (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/429)
|
* [bugfix]: modal closes and newly created person/thirdparty is selected when multiple persons/thirdparties are created through the modal (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/429)
|
||||||
|
* [person] age added to renderstring + renderbox/ vue component created to display person text (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/389)
|
||||||
|
* [household member editor] allow to push to existing household
|
||||||
|
|
||||||
|
|
||||||
## Test releases
|
## Test releases
|
||||||
|
|
||||||
@ -34,10 +42,10 @@ and this project adheres to
|
|||||||
|
|
||||||
### test release 2021-01-26
|
### test release 2021-01-26
|
||||||
|
|
||||||
|
>>>>>>> origin/master
|
||||||
* [parcours] comments truncated if too long + link added (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/406)
|
* [parcours] comments truncated if too long + link added (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/406)
|
||||||
* [person]: possibility to add person resources (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/382)
|
* [person]: possibility to add person resources (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/382)
|
||||||
* [person ressources]: module added
|
* [person ressources]: module added
|
||||||
* [parcours] bugfix if deathdate is not defined (eg. for a thirdparty) parcours is still displayed. Gave error before.
|
|
||||||
|
|
||||||
|
|
||||||
### test release 2022-01-24
|
### test release 2022-01-24
|
||||||
|
@ -16,6 +16,7 @@ use InvalidArgumentException;
|
|||||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
use Symfony\Component\Serializer\Annotation\Groups;
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ActivityType.
|
* Class ActivityType.
|
||||||
@ -193,7 +194,6 @@ class ActivityType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="smallint", nullable=false, options={"default": 1})
|
* @ORM\Column(type="smallint", nullable=false, options={"default": 1})
|
||||||
* @Assert\EqualTo(propertyPath="socialIssuesVisible", message="This parameter must be equal to social issue parameter")
|
|
||||||
*/
|
*/
|
||||||
private int $socialActionsVisible = self::FIELD_INVISIBLE;
|
private int $socialActionsVisible = self::FIELD_INVISIBLE;
|
||||||
|
|
||||||
@ -263,6 +263,23 @@ class ActivityType
|
|||||||
*/
|
*/
|
||||||
private int $userVisible = self::FIELD_REQUIRED;
|
private int $userVisible = self::FIELD_REQUIRED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Assert\Callback
|
||||||
|
*
|
||||||
|
* @param mixed $payload
|
||||||
|
*/
|
||||||
|
public function checkSocialActionsVisibility(ExecutionContextInterface $context, $payload)
|
||||||
|
{
|
||||||
|
if ($this->socialIssuesVisible !== $this->socialActionsVisible) {
|
||||||
|
if (!($this->socialIssuesVisible === 2 && $this->socialActionsVisible === 1)) {
|
||||||
|
$context
|
||||||
|
->buildViolation('The socialActionsVisible value is not compatible with the socialIssuesVisible value')
|
||||||
|
->atPath('socialActionsVisible')
|
||||||
|
->addViolation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get active
|
* Get active
|
||||||
* return true if the type is active.
|
* return true if the type is active.
|
||||||
|
@ -1,45 +1,48 @@
|
|||||||
<template>
|
<template>
|
||||||
<teleport to="#add-persons" v-if="isComponentVisible">
|
<teleport to="#add-persons" v-if="isComponentVisible">
|
||||||
|
|
||||||
<div class="flex-bloc concerned-groups" :class="getContext">
|
<div class="flex-bloc concerned-groups" :class="getContext">
|
||||||
<persons-bloc
|
<persons-bloc
|
||||||
v-for="bloc in contextPersonsBlocs"
|
v-for="bloc in contextPersonsBlocs"
|
||||||
v-bind:key="bloc.key"
|
v-bind:key="bloc.key"
|
||||||
v-bind:bloc="bloc"
|
v-bind:bloc="bloc"
|
||||||
v-bind:blocWidth="getBlocWidth"
|
v-bind:blocWidth="getBlocWidth"
|
||||||
v-bind:setPersonsInBloc="setPersonsInBloc">
|
v-bind:setPersonsInBloc="setPersonsInBloc">
|
||||||
</persons-bloc>
|
</persons-bloc>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0">
|
<div v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0">
|
||||||
<ul class="list-suggest add-items inline">
|
<ul class="list-suggest add-items inline">
|
||||||
<li v-for="(p, i) in suggestedEntities" @click="addSuggestedEntity(p)" :key="`suggestedEntities-${i}`">
|
<li v-for="(p, i) in suggestedEntities" @click="addSuggestedEntity(p)" :key="`suggestedEntities-${i}`">
|
||||||
<span>{{ p.text }}</span>
|
<person-text v-if="p.type === 'person'" :person="p"></person-text>
|
||||||
</li>
|
<span v-else>{{ p.text }}</span>
|
||||||
</ul>
|
</li>
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<add-persons
|
<add-persons
|
||||||
buttonTitle="activity.add_persons"
|
buttonTitle="activity.add_persons"
|
||||||
modalTitle="activity.add_persons"
|
modalTitle="activity.add_persons"
|
||||||
v-bind:key="addPersons.key"
|
v-bind:key="addPersons.key"
|
||||||
v-bind:options="addPersonsOptions"
|
v-bind:options="addPersonsOptions"
|
||||||
@addNewPersons="addNewPersons"
|
@addNewPersons="addNewPersons"
|
||||||
ref="addPersons">
|
ref="addPersons">
|
||||||
</add-persons>
|
</add-persons>
|
||||||
|
|
||||||
</teleport>
|
</teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState, mapGetters } from 'vuex';
|
import { mapState, mapGetters } from 'vuex';
|
||||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||||
import PersonsBloc from './ConcernedGroups/PersonsBloc.vue';
|
import PersonsBloc from './ConcernedGroups/PersonsBloc.vue';
|
||||||
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ConcernedGroups",
|
name: "ConcernedGroups",
|
||||||
components: {
|
components: {
|
||||||
AddPersons,
|
AddPersons,
|
||||||
PersonsBloc
|
PersonsBloc,
|
||||||
|
PersonText
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -1,21 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<li>
|
<li>
|
||||||
<span :title="person.text">
|
<span :title="person.text">
|
||||||
<span class="chill_denomination" @click.prevent="$emit('remove', person)">{{ textCutted }}</span>
|
<span class="chill_denomination" @click.prevent="$emit('remove', person)">
|
||||||
|
<person-text :person="person" :isCut="true"></person-text>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PersonBadge",
|
name: "PersonBadge",
|
||||||
props: ['person'],
|
props: ['person'],
|
||||||
computed: {
|
components: {
|
||||||
textCutted() {
|
PersonText
|
||||||
let more = (this.person.text.length > 15) ?'…' : '';
|
|
||||||
return this.person.text.slice(0,15) + more;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
// computed: {
|
||||||
|
// textCutted() {
|
||||||
|
// let more = (this.person.text.length > 15) ?'…' : '';
|
||||||
|
// return this.person.text.slice(0,15) + more;
|
||||||
|
// }
|
||||||
|
// },
|
||||||
emits: ['remove'],
|
emits: ['remove'],
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -41,6 +41,17 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if activity.attendee and t.attendeeVisible %}
|
||||||
|
<div class="wl-row">
|
||||||
|
<div class="wl-col title"><h3>{{ 'Attendee'|trans }}</h3></div>
|
||||||
|
<div class="wl-col list">
|
||||||
|
<p class="wl-item">
|
||||||
|
{{ activity.attendee.name|localize_translatable_string }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if activity.sentReceived is not empty and t.sentReceivedVisible %}
|
{% if activity.sentReceived is not empty and t.sentReceivedVisible %}
|
||||||
<div class="wl-row">
|
<div class="wl-row">
|
||||||
<div class="wl-col title"><h3>{{ 'Sent received'|trans }}</h3></div>
|
<div class="wl-col title"><h3>{{ 'Sent received'|trans }}</h3></div>
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
<li class="associated-persons">
|
<li class="associated-persons">
|
||||||
<span class="item-key">{{ 'Participants'|trans ~ ' : ' }}</span>
|
<span class="item-key">{{ 'Participants'|trans ~ ' : ' }}</span>
|
||||||
{% for p in activity.personsAssociated %}
|
{% for p in activity.personsAssociated %}
|
||||||
<span class="badge-person">{{ p|chill_entity_render_box }}</span>
|
<span class="badge-person">{{ p|chill_entity_render_box({'addAgeBadge': true}) }}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -165,11 +165,7 @@
|
|||||||
<dt class="inline">{{ 'Attendee'|trans }}</dt>
|
<dt class="inline">{{ 'Attendee'|trans }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
{% if entity.attendee is not null %}
|
{% if entity.attendee is not null %}
|
||||||
{% if entity.attendee %}
|
{{ entity.attendee.name|localize_translatable_string }}
|
||||||
{{ 'present'|trans|capitalize }}
|
|
||||||
{% else %}
|
|
||||||
{{ 'not present'|trans|capitalize }}
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="chill-no-data-statement">{{ 'None'|trans|capitalize }}</span>
|
<span class="chill-no-data-statement">{{ 'None'|trans|capitalize }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -20,3 +20,4 @@ For this type of activity, you must add at least one social action: Pour ce type
|
|||||||
|
|
||||||
# admin
|
# admin
|
||||||
This parameter must be equal to social issue parameter: Ce paramètre doit être égal au paramètre "Visibilité du champs Problématiques sociales"
|
This parameter must be equal to social issue parameter: Ce paramètre doit être égal au paramètre "Visibilité du champs Problématiques sociales"
|
||||||
|
The socialActionsVisible value is not compatible with the socialIssuesVisible value: Cette valeur du paramètre "Visibilité du champs Actions sociales" n'est pas compatible avec la valeur du paramètre "Visibilité du champs Problématiques sociales"
|
@ -12,6 +12,7 @@
|
|||||||
display: block;
|
display: block;
|
||||||
top: calc(50% - 7px);
|
top: calc(50% - 7px);
|
||||||
right: 10px;
|
right: 10px;
|
||||||
|
line-height: 11px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,14 +63,19 @@ ul.list-suggest {
|
|||||||
& span:hover {
|
& span:hover {
|
||||||
color: $chill-l-gray;
|
color: $chill-l-gray;
|
||||||
}
|
}
|
||||||
|
.person-text {
|
||||||
|
span {
|
||||||
|
padding-left: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.remove-items {
|
&.remove-items {
|
||||||
li {
|
li {
|
||||||
position: relative;
|
position: relative;
|
||||||
span {
|
& > span {
|
||||||
display: block;
|
display: block;
|
||||||
padding-right: .75rem;
|
padding-right: 1.75rem;
|
||||||
@include remove_link;
|
@include remove_link;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ $chill-theme-buttons: (
|
|||||||
"cancel": $gray-300,
|
"cancel": $gray-300,
|
||||||
"choose": $gray-300,
|
"choose": $gray-300,
|
||||||
"notify": $gray-300,
|
"notify": $gray-300,
|
||||||
|
"search": $gray-300,
|
||||||
"unlink": $chill-red,
|
"unlink": $chill-red,
|
||||||
"tpchild": $chill-pink,
|
"tpchild": $chill-pink,
|
||||||
);
|
);
|
||||||
@ -80,6 +81,7 @@ $chill-theme-buttons: (
|
|||||||
&.btn-notify::before,
|
&.btn-notify::before,
|
||||||
&.btn-tpchild::before,
|
&.btn-tpchild::before,
|
||||||
&.btn-download::before,
|
&.btn-download::before,
|
||||||
|
&.btn-search::before,
|
||||||
&.btn-cancel::before {
|
&.btn-cancel::before {
|
||||||
font: normal normal normal 14px/1 ForkAwesome;
|
font: normal normal normal 14px/1 ForkAwesome;
|
||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
@ -108,6 +110,7 @@ $chill-theme-buttons: (
|
|||||||
&.btn-notify::before { content: "\f1d8"; } // fa-paper-plane
|
&.btn-notify::before { content: "\f1d8"; } // fa-paper-plane
|
||||||
&.btn-tpchild::before { content: "\f007"; } // fa-user
|
&.btn-tpchild::before { content: "\f007"; } // fa-user
|
||||||
&.btn-download::before { content: "\f019"; } // fa-download
|
&.btn-download::before { content: "\f019"; } // fa-download
|
||||||
|
&.btn-search::before { content: "\f002"; } // fa-search
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,6 +24,11 @@
|
|||||||
{{ $t('user')}}
|
{{ $t('user')}}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<span v-if="entity.type === 'household'" class="badge rounded-pill bg-user">
|
||||||
|
{{ $t('household')}}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -40,7 +45,8 @@ export default {
|
|||||||
company: "Personne morale",
|
company: "Personne morale",
|
||||||
contact: "Personne physique",
|
contact: "Personne physique",
|
||||||
},
|
},
|
||||||
user: 'TMS'
|
user: 'TMS',
|
||||||
|
household: 'Ménage',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,14 +61,15 @@ const messages = {
|
|||||||
woman: "Née le"
|
woman: "Née le"
|
||||||
},
|
},
|
||||||
deathdate: "Date de décès",
|
deathdate: "Date de décès",
|
||||||
years_old: "ans",
|
|
||||||
household_without_address: "Le ménage de l'usager est sans adresse",
|
household_without_address: "Le ménage de l'usager est sans adresse",
|
||||||
no_data: "Aucune information renseignée",
|
no_data: "Aucune information renseignée",
|
||||||
type: {
|
type: {
|
||||||
thirdparty: "Tiers",
|
thirdparty: "Tiers",
|
||||||
person: "Usager"
|
person: "Usager"
|
||||||
},
|
},
|
||||||
holder: "Titulaire"
|
holder: "Titulaire",
|
||||||
|
years_old: "an | {n} an | {n} ans",
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -42,6 +42,3 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
></span>
|
></span>
|
||||||
|
|
||||||
{{ encore_entry_script_tags('vue_onthefly') }}
|
|
||||||
{{ encore_entry_link_tags('vue_onthefly') }}
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
{{ encore_entry_link_tags('mod_ckeditor5') }}
|
{{ encore_entry_link_tags('mod_ckeditor5') }}
|
||||||
{{ encore_entry_link_tags('chill') }}
|
{{ encore_entry_link_tags('chill') }}
|
||||||
{{ encore_entry_link_tags('mod_blur') }}
|
{{ encore_entry_link_tags('mod_blur') }}
|
||||||
|
{{ encore_entry_link_tags('vue_onthefly') }}
|
||||||
{% block css %}<!-- nothing added to css -->{% endblock %}
|
{% block css %}<!-- nothing added to css -->{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -94,6 +95,7 @@
|
|||||||
{{ encore_entry_script_tags('mod_ckeditor5') }}
|
{{ encore_entry_script_tags('mod_ckeditor5') }}
|
||||||
{{ encore_entry_script_tags('mod_blur') }}
|
{{ encore_entry_script_tags('mod_blur') }}
|
||||||
{{ encore_entry_script_tags('chill') }}
|
{{ encore_entry_script_tags('chill') }}
|
||||||
|
{{ encore_entry_script_tags('vue_onthefly') }}
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.addEventListener('DOMContentLoaded', function(e) {
|
window.addEventListener('DOMContentLoaded', function(e) {
|
||||||
|
@ -22,6 +22,10 @@ class SearchApiQuery
|
|||||||
|
|
||||||
private array $fromClauseParams = [];
|
private array $fromClauseParams = [];
|
||||||
|
|
||||||
|
private bool $isDistinct = false;
|
||||||
|
|
||||||
|
private ?string $isDistinctKey = null;
|
||||||
|
|
||||||
private ?string $jsonbMetadata = null;
|
private ?string $jsonbMetadata = null;
|
||||||
|
|
||||||
private array $jsonbMetadataParams = [];
|
private array $jsonbMetadataParams = [];
|
||||||
@ -105,6 +109,11 @@ class SearchApiQuery
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDistinct(): bool
|
||||||
|
{
|
||||||
|
return $this->isDistinct;
|
||||||
|
}
|
||||||
|
|
||||||
public function getFromClause(): string
|
public function getFromClause(): string
|
||||||
{
|
{
|
||||||
return $this->fromClause;
|
return $this->fromClause;
|
||||||
@ -139,6 +148,14 @@ class SearchApiQuery
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setDistinct(bool $distinct, string $distinctKey): self
|
||||||
|
{
|
||||||
|
$this->isDistinct = $distinct;
|
||||||
|
$this->isDistinctKey = $distinctKey;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setFromClause(string $fromClause, array $params = []): self
|
public function setFromClause(string $fromClause, array $params = []): self
|
||||||
{
|
{
|
||||||
$this->fromClause = $fromClause;
|
$this->fromClause = $fromClause;
|
||||||
@ -185,7 +202,11 @@ class SearchApiQuery
|
|||||||
private function buildSelectClause(bool $countOnly = false): string
|
private function buildSelectClause(bool $countOnly = false): string
|
||||||
{
|
{
|
||||||
if ($countOnly) {
|
if ($countOnly) {
|
||||||
return 'count(*) AS c';
|
if (!$this->isDistinct) {
|
||||||
|
return 'count(*) AS c';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'count(distinct ' . $this->isDistinctKey . ') AS c';
|
||||||
}
|
}
|
||||||
|
|
||||||
$selects = $this->getSelectClauses();
|
$selects = $this->getSelectClauses();
|
||||||
@ -202,7 +223,7 @@ class SearchApiQuery
|
|||||||
$selects[] = strtr('{pertinence} AS pertinence', ['{pertinence}' => $this->pertinence]);
|
$selects[] = strtr('{pertinence} AS pertinence', ['{pertinence}' => $this->pertinence]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return implode(', ', $selects);
|
return ($this->isDistinct ? 'DISTINCT ' : '') . implode(', ', $selects);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildSelectParams(bool $count = false): array
|
private function buildSelectParams(bool $count = false): array
|
||||||
|
@ -134,6 +134,7 @@ paths:
|
|||||||
- search
|
- search
|
||||||
- person
|
- person
|
||||||
- thirdparty
|
- thirdparty
|
||||||
|
- household
|
||||||
description: >
|
description: >
|
||||||
The search is performed across multiple entities. The entities must be listed into
|
The search is performed across multiple entities. The entities must be listed into
|
||||||
`type` parameters.
|
`type` parameters.
|
||||||
@ -159,6 +160,7 @@ paths:
|
|||||||
- person
|
- person
|
||||||
- thirdparty
|
- thirdparty
|
||||||
- user
|
- user
|
||||||
|
- household
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: "OK"
|
description: "OK"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<i class="fa fa-home fa-fw text-light" :title="$t('persons_associated.show_household_number', { id: h.id })"></i>
|
<i class="fa fa-home fa-fw text-light" :title="$t('persons_associated.show_household_number', { id: h.id })"></i>
|
||||||
</a>
|
</a>
|
||||||
<span v-for="person in h.persons" class="me-1" :key="person.id">
|
<span v-for="person in h.persons" class="me-1" :key="person.id">
|
||||||
<on-the-fly :type="person.type" :id="person.id" :buttonText="person.text" :displayBadge="'true' === 'true'" action="show"></on-the-fly>
|
<on-the-fly :type="person.type" :id="person.id" :buttonText="person.textAge" :displayBadge="'true' === 'true'" action="show"></on-the-fly>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
:value="p.person.id"
|
:value="p.person.id"
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label">
|
<label class="form-check-label">
|
||||||
{{ p.person.text }}
|
<person-text :person="p.person"></person-text>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" name="expand_suggestions" value="true">
|
<input type="hidden" name="expand_suggestions" value="true">
|
||||||
@ -50,9 +50,9 @@
|
|||||||
<div v-if="suggestedPersons.length > 0">
|
<div v-if="suggestedPersons.length > 0">
|
||||||
<ul class="list-suggest add-items inline">
|
<ul class="list-suggest add-items inline">
|
||||||
<li v-for="p in suggestedPersons" :key="p.id" @click="addSuggestedPerson(p)">
|
<li v-for="p in suggestedPersons" :key="p.id" @click="addSuggestedPerson(p)">
|
||||||
<span>{{ p.text }}</span>
|
<person-text :person="p"></person-text>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -76,12 +76,14 @@
|
|||||||
import {mapGetters, mapState} from 'vuex';
|
import {mapGetters, mapState} from 'vuex';
|
||||||
import ParticipationItem from "./PersonsAssociated/ParticipationItem.vue";
|
import ParticipationItem from "./PersonsAssociated/ParticipationItem.vue";
|
||||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||||
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PersonsAssociated',
|
name: 'PersonsAssociated',
|
||||||
components: {
|
components: {
|
||||||
ParticipationItem,
|
ParticipationItem,
|
||||||
AddPersons
|
AddPersons,
|
||||||
|
PersonText
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -110,15 +112,15 @@ export default {
|
|||||||
)
|
)
|
||||||
// filter persons appearing twice in requestor and resources
|
// filter persons appearing twice in requestor and resources
|
||||||
.filter(
|
.filter(
|
||||||
(e, index, suggested) => {
|
(e, index, suggested) => {
|
||||||
for (let i = 0; i < suggested.length; i = i+1) {
|
for (let i = 0; i < suggested.length; i = i+1) {
|
||||||
if (i < index && e.id === suggested[i].id) {
|
if (i < index && e.id === suggested[i].id) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li><on-the-fly :type="participation.person.type" :id="participation.person.id" action="show"></on-the-fly></li>
|
<li><on-the-fly :type="participation.person.type" :id="participation.person.id" action="show"></on-the-fly></li>
|
||||||
<li><on-the-fly :type="participation.person.type" :id="participation.person.id" action="edit" @saveFormOnTheFly="saveFormOnTheFly"></on-the-fly></li>
|
<li><on-the-fly :type="participation.person.type" :id="participation.person.id" action="edit" @saveFormOnTheFly="saveFormOnTheFly" :canCloseModal="canCloseOnTheFlyModal"></on-the-fly></li>
|
||||||
<li>
|
<li>
|
||||||
<button v-if="!participation.endDate"
|
<button v-if="!participation.endDate"
|
||||||
class="btn btn-sm btn-remove"
|
class="btn btn-sm btn-remove"
|
||||||
@ -63,6 +63,7 @@ import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
|
|||||||
import ButtonLocation from '../ButtonLocation.vue';
|
import ButtonLocation from '../ButtonLocation.vue';
|
||||||
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
||||||
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
|
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
|
||||||
|
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ParticipationItem',
|
name: 'ParticipationItem',
|
||||||
@ -88,7 +89,8 @@ export default {
|
|||||||
addAge: false,
|
addAge: false,
|
||||||
hLevel: 1
|
hLevel: 1
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
canCloseOnTheFlyModal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -110,14 +112,53 @@ export default {
|
|||||||
saveFormOnTheFly(payload) {
|
saveFormOnTheFly(payload) {
|
||||||
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
||||||
payload.target = 'participation';
|
payload.target = 'participation';
|
||||||
this.$store.dispatch('patchOnTheFly', payload)
|
|
||||||
.catch(({name, violations}) => {
|
let body = { type: payload.type };
|
||||||
if (name === 'ValidationException' || name === 'AccessException') {
|
if (payload.type === 'person') {
|
||||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
body.firstName = payload.data.firstName;
|
||||||
} else {
|
body.lastName = payload.data.lastName;
|
||||||
this.$toast.open({message: 'An error occurred'})
|
if (payload.data.birthdate !== null) { body.birthdate = payload.data.birthdate; }
|
||||||
}
|
body.phonenumber = payload.data.phonenumber;
|
||||||
});
|
body.mobilenumber = payload.data.mobilenumber;
|
||||||
|
body.gender = payload.data.gender;
|
||||||
|
|
||||||
|
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
|
||||||
|
.then(response => {
|
||||||
|
this.$store.dispatch('addPerson', { target: payload.target, body: response })
|
||||||
|
this.canCloseOnTheFlyModal = true;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (error.name === 'ValidationException') {
|
||||||
|
for (let v of error.violations) {
|
||||||
|
this.$toast.open({message: v });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$toast.open({message: 'An error occurred'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (payload.type === 'thirdparty') {
|
||||||
|
body.name = payload.data.text;
|
||||||
|
body.email = payload.data.email;
|
||||||
|
body.telephone = payload.data.phonenumber;
|
||||||
|
body.address = { id: payload.data.address.address_id };
|
||||||
|
|
||||||
|
makeFetch('PATCH', `/api/1.0/third-party/third-party/${payload.data.id}.json`, body)
|
||||||
|
.then(response => {
|
||||||
|
this.$store.dispatch('addThirdparty', { target: payload.target, body: response })
|
||||||
|
this.canCloseOnTheFlyModal = true;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (error.name === 'ValidationException') {
|
||||||
|
for (let v of error.violations) {
|
||||||
|
this.$toast.open({message: v });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$toast.open({message: 'An error occurred'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,8 @@
|
|||||||
addInfo: true,
|
addInfo: true,
|
||||||
hLevel: 3,
|
hLevel: 3,
|
||||||
isMultiline: true,
|
isMultiline: true,
|
||||||
isConfidential: false
|
isConfidential: false,
|
||||||
|
addAge: true,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<template v-slot:record-actions>
|
<template v-slot:record-actions>
|
||||||
@ -113,7 +114,7 @@
|
|||||||
<template v-slot:record-actions>
|
<template v-slot:record-actions>
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li><on-the-fly :type="accompanyingCourse.requestor.type" :id="accompanyingCourse.requestor.id" action="show"></on-the-fly></li>
|
<li><on-the-fly :type="accompanyingCourse.requestor.type" :id="accompanyingCourse.requestor.id" action="show"></on-the-fly></li>
|
||||||
<li><on-the-fly :type="accompanyingCourse.requestor.type" :id="accompanyingCourse.requestor.id" action="edit" @saveFormOnTheFly="saveFormOnTheFly"></on-the-fly></li>
|
<li><on-the-fly :type="accompanyingCourse.requestor.type" :id="accompanyingCourse.requestor.id" action="edit" @saveFormOnTheFly="saveFormOnTheFly" :canCloseModal="canCloseOnTheFlyModal"></on-the-fly></li>
|
||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
</person-render-box>
|
</person-render-box>
|
||||||
@ -136,9 +137,10 @@
|
|||||||
<div v-if="accompanyingCourse.requestor === null && suggestedEntities.length > 0">
|
<div v-if="accompanyingCourse.requestor === null && suggestedEntities.length > 0">
|
||||||
<ul class="list-suggest add-items inline">
|
<ul class="list-suggest add-items inline">
|
||||||
<li v-for="p in suggestedEntities" :key="uniqueId(p)" @click="addSuggestedEntity(p)">
|
<li v-for="p in suggestedEntities" :key="uniqueId(p)" @click="addSuggestedEntity(p)">
|
||||||
<span>{{ p.text }}</span>
|
<person-text v-if="p.type === 'person'" :person="p"></person-text>
|
||||||
</li>
|
<span v-else>{{ p.text }}</span>
|
||||||
</ul>
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -162,6 +164,9 @@ import PersonRenderBox from '../../_components/Entity/PersonRenderBox.vue';
|
|||||||
import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue';
|
import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue';
|
||||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
|
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
|
||||||
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Requestor',
|
name: 'Requestor',
|
||||||
@ -170,7 +175,8 @@ export default {
|
|||||||
OnTheFly,
|
OnTheFly,
|
||||||
PersonRenderBox,
|
PersonRenderBox,
|
||||||
ThirdPartyRenderBox,
|
ThirdPartyRenderBox,
|
||||||
Confidential
|
Confidential,
|
||||||
|
PersonText
|
||||||
},
|
},
|
||||||
props: ['isAnonymous'],
|
props: ['isAnonymous'],
|
||||||
data() {
|
data() {
|
||||||
@ -182,7 +188,8 @@ export default {
|
|||||||
priority: null,
|
priority: null,
|
||||||
uniq: true,
|
uniq: true,
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
canCloseOnTheFlyModal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -246,14 +253,52 @@ export default {
|
|||||||
saveFormOnTheFly(payload) {
|
saveFormOnTheFly(payload) {
|
||||||
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
||||||
payload.target = 'requestor';
|
payload.target = 'requestor';
|
||||||
this.$store.dispatch('patchOnTheFly', payload)
|
|
||||||
.catch(({name, violations}) => {
|
let body = { type: payload.type };
|
||||||
if (name === 'ValidationException' || name === 'AccessException') {
|
if (payload.type === 'person') {
|
||||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
body.firstName = payload.data.firstName;
|
||||||
} else {
|
body.lastName = payload.data.lastName;
|
||||||
this.$toast.open({message: 'An error occurred'})
|
if (payload.data.birthdate !== null) { body.birthdate = payload.data.birthdate; }
|
||||||
}
|
body.phonenumber = payload.data.phonenumber;
|
||||||
});
|
body.mobilenumber = payload.data.mobilenumber;
|
||||||
|
body.gender = payload.data.gender;
|
||||||
|
|
||||||
|
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
|
||||||
|
.then(response => {
|
||||||
|
this.$store.dispatch('addPerson', { target: payload.target, body: response })
|
||||||
|
this.canCloseOnTheFlyModal = true;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (error.name === 'ValidationException') {
|
||||||
|
for (let v of error.violations) {
|
||||||
|
this.$toast.open({message: v });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$toast.open({message: 'An error occurred'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (payload.type === 'thirdparty') {
|
||||||
|
body.name = payload.data.text;
|
||||||
|
body.email = payload.data.email;
|
||||||
|
body.telephone = payload.data.phonenumber;
|
||||||
|
body.address = { id: payload.data.address.address_id };
|
||||||
|
|
||||||
|
makeFetch('PATCH', `/api/1.0/third-party/third-party/${payload.data.id}.json`, body)
|
||||||
|
.then(response => {
|
||||||
|
this.$store.dispatch('addThirdparty', { target: payload.target, body: response })
|
||||||
|
this.canCloseOnTheFlyModal = true;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (error.name === 'ValidationException') {
|
||||||
|
for (let v of error.violations) {
|
||||||
|
this.$toast.open({message: v });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$toast.open({message: 'An error occurred'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
addSuggestedEntity(e) {
|
addSuggestedEntity(e) {
|
||||||
this.$store.dispatch('addRequestor', { result: e, type: e.type })
|
this.$store.dispatch('addRequestor', { result: e, type: e.type })
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
<div v-if="suggestedEntities.length > 0">
|
<div v-if="suggestedEntities.length > 0">
|
||||||
<ul class="list-suggest add-items inline">
|
<ul class="list-suggest add-items inline">
|
||||||
<li v-for="p in suggestedEntities" :key="uniqueId(p)" @click="addSuggestedEntity(p)">
|
<li v-for="p in suggestedEntities" :key="uniqueId(p)" @click="addSuggestedEntity(p)">
|
||||||
<span>{{ p.text }}</span>
|
<person-text v-if="p.type === 'person'" :person="p"></person-text>
|
||||||
|
<span v-else>{{ p.text }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -45,12 +46,15 @@
|
|||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||||
import ResourceItem from './Resources/ResourceItem.vue';
|
import ResourceItem from './Resources/ResourceItem.vue';
|
||||||
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Resources',
|
name: 'Resources',
|
||||||
components: {
|
components: {
|
||||||
AddPersons,
|
AddPersons,
|
||||||
ResourceItem
|
ResourceItem,
|
||||||
|
PersonText
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -34,7 +34,8 @@
|
|||||||
:type="resource.resource.type"
|
:type="resource.resource.type"
|
||||||
:id="resource.resource.id"
|
:id="resource.resource.id"
|
||||||
action="edit"
|
action="edit"
|
||||||
@saveFormOnTheFly="saveFormOnTheFly">
|
@saveFormOnTheFly="saveFormOnTheFly"
|
||||||
|
:canCloseModal="canCloseOnTheFlyModal">
|
||||||
</on-the-fly>
|
</on-the-fly>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@ -80,7 +81,8 @@
|
|||||||
:type="resource.resource.type"
|
:type="resource.resource.type"
|
||||||
:id="resource.resource.id"
|
:id="resource.resource.id"
|
||||||
action="edit"
|
action="edit"
|
||||||
@saveFormOnTheFly="saveFormOnTheFly">
|
@saveFormOnTheFly="saveFormOnTheFly"
|
||||||
|
:canCloseModal="canCloseOnTheFlyModal">
|
||||||
</on-the-fly>
|
</on-the-fly>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@ -101,6 +103,7 @@ import ButtonLocation from '../ButtonLocation.vue';
|
|||||||
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
||||||
import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue';
|
import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue';
|
||||||
import WriteComment from './WriteComment';
|
import WriteComment from './WriteComment';
|
||||||
|
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ResourceItem',
|
name: 'ResourceItem',
|
||||||
@ -113,6 +116,11 @@ export default {
|
|||||||
},
|
},
|
||||||
props: ['resource'],
|
props: ['resource'],
|
||||||
emits: ['remove'],
|
emits: ['remove'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
canCloseOnTheFlyModal: false
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
parent() {
|
parent() {
|
||||||
return {
|
return {
|
||||||
@ -136,14 +144,52 @@ export default {
|
|||||||
saveFormOnTheFly(payload) {
|
saveFormOnTheFly(payload) {
|
||||||
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
||||||
payload.target = 'resource';
|
payload.target = 'resource';
|
||||||
this.$store.dispatch('patchOnTheFly', payload)
|
|
||||||
.catch(({name, violations}) => {
|
let body = { type: payload.type };
|
||||||
if (name === 'ValidationException' || name === 'AccessException') {
|
if (payload.type === 'person') {
|
||||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
body.firstName = payload.data.firstName;
|
||||||
} else {
|
body.lastName = payload.data.lastName;
|
||||||
this.$toast.open({message: 'An error occurred'})
|
if (payload.data.birthdate !== null) { body.birthdate = payload.data.birthdate; }
|
||||||
}
|
body.phonenumber = payload.data.phonenumber;
|
||||||
});
|
body.mobilenumber = payload.data.mobilenumber;
|
||||||
|
body.gender = payload.data.gender;
|
||||||
|
|
||||||
|
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
|
||||||
|
.then(response => {
|
||||||
|
this.$store.dispatch('addPerson', { target: payload.target, body: response })
|
||||||
|
this.canCloseOnTheFlyModal = true;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (error.name === 'ValidationException') {
|
||||||
|
for (let v of error.violations) {
|
||||||
|
this.$toast.open({message: v });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$toast.open({message: 'An error occurred'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (payload.type === 'thirdparty') {
|
||||||
|
body.name = payload.data.text;
|
||||||
|
body.email = payload.data.email;
|
||||||
|
body.telephone = payload.data.phonenumber;
|
||||||
|
body.address = { id: payload.data.address.address_id };
|
||||||
|
|
||||||
|
makeFetch('PATCH', `/api/1.0/third-party/third-party/${payload.data.id}.json`, body)
|
||||||
|
.then(response => {
|
||||||
|
this.$store.dispatch('addThirdparty', { target: payload.target, body: response })
|
||||||
|
this.canCloseOnTheFlyModal = true;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (error.name === 'ValidationException') {
|
||||||
|
for (let v of error.violations) {
|
||||||
|
this.$toast.open({message: v });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$toast.open({message: 'An error occurred'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
updateComment(resource) {
|
updateComment(resource) {
|
||||||
console.log('updateComment', resource);
|
console.log('updateComment', resource);
|
||||||
|
@ -13,7 +13,7 @@ const root = window.vueRootComponent;
|
|||||||
* Load all App component, for AccompanyingCourse edition page
|
* Load all App component, for AccompanyingCourse edition page
|
||||||
*/
|
*/
|
||||||
if (root === 'app') {
|
if (root === 'app') {
|
||||||
initPromise.then(store => {
|
initPromise(root).then(store => {
|
||||||
|
|
||||||
const i18n = _createI18n(appMessages);
|
const i18n = _createI18n(appMessages);
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ if (root === 'app') {
|
|||||||
* Load only Banner sub-component, for all others AccompanyingCourse page
|
* Load only Banner sub-component, for all others AccompanyingCourse page
|
||||||
*/
|
*/
|
||||||
if (root === 'banner') {
|
if (root === 'banner') {
|
||||||
initPromise.then(store => {
|
initPromise(root).then(store => {
|
||||||
|
|
||||||
const i18n = _createI18n(appMessages);
|
const i18n = _createI18n(appMessages);
|
||||||
|
|
||||||
|
@ -14,10 +14,14 @@ import { datetimeToISO, ISOToDate, ISOToDatetime } from 'ChillMainAssets/chill/j
|
|||||||
const debug = process.env.NODE_ENV !== 'production';
|
const debug = process.env.NODE_ENV !== 'production';
|
||||||
const id = window.accompanyingCourseId;
|
const id = window.accompanyingCourseId;
|
||||||
|
|
||||||
let scopesPromise = fetchScopes();
|
let getScopesPromise = (root) => {
|
||||||
|
if (root === 'app') {
|
||||||
|
return fetchScopes();
|
||||||
|
}
|
||||||
|
}
|
||||||
let accompanyingCoursePromise = getAccompanyingCourse(id);
|
let accompanyingCoursePromise = getAccompanyingCourse(id);
|
||||||
|
|
||||||
let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
|
let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCoursePromise])
|
||||||
.then(([scopes, accompanyingCourse]) => new Promise((resolve, reject) => {
|
.then(([scopes, accompanyingCourse]) => new Promise((resolve, reject) => {
|
||||||
|
|
||||||
const store = createStore({
|
const store = createStore({
|
||||||
@ -291,6 +295,12 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
|
|||||||
commit('removeParticipation', payload);
|
commit('removeParticipation', payload);
|
||||||
// fetch DELETE request...
|
// fetch DELETE request...
|
||||||
},
|
},
|
||||||
|
addPerson({ commit }, payload) {
|
||||||
|
commit('updatePerson', { target: payload.target, person: payload.body });
|
||||||
|
},
|
||||||
|
addThirdparty({ commit }, payload) {
|
||||||
|
commit('updateThirdparty', { target: payload.target, thirdparty: payload.body });
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Add/close participation
|
* Add/close participation
|
||||||
*/
|
*/
|
||||||
@ -810,8 +820,11 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
store.dispatch('fetchReferrersSuggested');
|
if (root === 'app') {
|
||||||
store.dispatch('fetchUsers');
|
store.dispatch('fetchReferrersSuggested');
|
||||||
|
store.dispatch('fetchUsers');
|
||||||
|
}
|
||||||
|
|
||||||
resolve(store);
|
resolve(store);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -57,8 +57,12 @@
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="p in personsReachables" :key="p.id">
|
<li v-for="p in personsReachables" :key="p.id">
|
||||||
<input type="checkbox" :value="p.id" v-model="personsPicked">
|
<div class="form-check">
|
||||||
<person-render-box render="badge" :options="{}" :person="p"></person-render-box>
|
<input type="checkbox" :value="p.id" v-model="personsPicked" class="form-check-input" :id="'person_check'+p.id">
|
||||||
|
<label class="form-check-label" :for="'person_check' + p.id">
|
||||||
|
<person-text :person="p"></person-text>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -124,7 +128,7 @@
|
|||||||
import { mapState, mapActions, mapGetters } from 'vuex';
|
import { mapState, mapActions, mapGetters } from 'vuex';
|
||||||
import VueMultiselect from 'vue-multiselect';
|
import VueMultiselect from 'vue-multiselect';
|
||||||
import { dateToISO, ISOToDate } from 'ChillMainAssets/chill/js/date.js';
|
import { dateToISO, ISOToDate } from 'ChillMainAssets/chill/js/date.js';
|
||||||
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
const i18n = {
|
const i18n = {
|
||||||
messages: {
|
messages: {
|
||||||
@ -146,7 +150,7 @@ export default {
|
|||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
VueMultiselect,
|
VueMultiselect,
|
||||||
PersonRenderBox,
|
PersonText,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
submit() {
|
submit() {
|
||||||
|
@ -141,10 +141,12 @@
|
|||||||
|
|
||||||
<ul class="list-unstyled">
|
<ul class="list-unstyled">
|
||||||
<li v-for="p in personsReachables" :key="p.id">
|
<li v-for="p in personsReachables" :key="p.id">
|
||||||
<label :for="p.id">
|
<div class="form-check">
|
||||||
<input v-model="personsPicked" :value="p.id" :id="p.id" type="checkbox" class="me-2">
|
<input v-model="personsPicked" :value="p.id" type="checkbox" class="me-2 form-check-input" :id="'person_check'+p.id">
|
||||||
{{ p.text }}
|
<label :for="'person_check'+p.id" class="form-check-label">
|
||||||
|
<person-text :person="p"></person-text>
|
||||||
</label>
|
</label>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -281,6 +283,7 @@ import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/
|
|||||||
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
|
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
|
||||||
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
|
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
|
||||||
import PickWorkflow from 'ChillMainAssets/vuejs/_components/EntityWorkflow/PickWorkflow.vue';
|
import PickWorkflow from 'ChillMainAssets/vuejs/_components/EntityWorkflow/PickWorkflow.vue';
|
||||||
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
const i18n = {
|
const i18n = {
|
||||||
messages: {
|
messages: {
|
||||||
@ -329,7 +332,8 @@ export default {
|
|||||||
ThirdPartyRenderBox,
|
ThirdPartyRenderBox,
|
||||||
PickTemplate,
|
PickTemplate,
|
||||||
PickWorkflow,
|
PickWorkflow,
|
||||||
OnTheFly
|
OnTheFly,
|
||||||
|
PersonText,
|
||||||
},
|
},
|
||||||
i18n,
|
i18n,
|
||||||
data() {
|
data() {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<ul class="list-suggest remove-items inline">
|
<ul class="list-suggest remove-items inline">
|
||||||
<li v-for="c in concerned" :key="c.person.id" @click="removeConcerned(c)">
|
<li v-for="c in concerned" :key="c.person.id" @click="removeConcerned(c)">
|
||||||
<span>{{ c.person.text }}</span>
|
<span><person-text :person="c.person"></person-text></span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -57,12 +57,14 @@
|
|||||||
import { mapState, mapGetters } from 'vuex';
|
import { mapState, mapGetters } from 'vuex';
|
||||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||||
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
||||||
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Concerned',
|
name: 'Concerned',
|
||||||
components: {
|
components: {
|
||||||
AddPersons,
|
AddPersons,
|
||||||
PersonRenderBox,
|
PersonRenderBox,
|
||||||
|
PersonText,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
...mapState([
|
||||||
|
@ -61,6 +61,16 @@
|
|||||||
<li v-if="hasHousehold">
|
<li v-if="hasHousehold">
|
||||||
<button @click="resetMode" class="btn btn-sm btn-misc">{{ $t('household_members_editor.household.reset_mode')}}</button>
|
<button @click="resetMode" class="btn btn-sm btn-misc">{{ $t('household_members_editor.household.reset_mode')}}</button>
|
||||||
</li>
|
</li>
|
||||||
|
<li v-if="!hasHousehold">
|
||||||
|
<add-persons
|
||||||
|
modalTitle="Chercher un ménage existant"
|
||||||
|
buttonTitle="Chercher un ménage existant"
|
||||||
|
v-bind:key="addPersons.key"
|
||||||
|
v-bind:options="addPersons.options"
|
||||||
|
@addNewPersons="pickHouseholdFound"
|
||||||
|
ref="pickHousehold"> <!-- to cast child method -->
|
||||||
|
</add-persons>
|
||||||
|
</li>
|
||||||
<li v-if="!hasHousehold">
|
<li v-if="!hasHousehold">
|
||||||
<button @click="setModeNew" class="btn btn-sm btn-create">{{ $t('household_members_editor.household.create_household') }}</button>
|
<button @click="setModeNew" class="btn btn-sm btn-create">{{ $t('household_members_editor.household.create_household') }}</button>
|
||||||
</li>
|
</li>
|
||||||
@ -77,16 +87,30 @@
|
|||||||
import { mapGetters, mapState } from 'vuex';
|
import { mapGetters, mapState } from 'vuex';
|
||||||
import HouseholdRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue';
|
import HouseholdRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue';
|
||||||
import CurrentHousehold from './CurrentHousehold';
|
import CurrentHousehold from './CurrentHousehold';
|
||||||
|
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Household',
|
name: 'Household',
|
||||||
components: {
|
components: {
|
||||||
|
AddPersons,
|
||||||
CurrentHousehold,
|
CurrentHousehold,
|
||||||
HouseholdRenderBox,
|
HouseholdRenderBox,
|
||||||
},
|
},
|
||||||
emits: ['readyToGo'],
|
emits: ['readyToGo'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
addPersons: {
|
||||||
|
key: 'household_find',
|
||||||
|
options: {
|
||||||
|
type: ['household'],
|
||||||
|
priority: null,
|
||||||
|
uniq: true,
|
||||||
|
button: {
|
||||||
|
size: 'btn-sm',
|
||||||
|
type: 'btn-search',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
addAddress: {
|
addAddress: {
|
||||||
key: 'household_new',
|
key: 'household_new',
|
||||||
options: {
|
options: {
|
||||||
@ -166,6 +190,13 @@ export default {
|
|||||||
this.$store.dispatch('selectHousehold', h);
|
this.$store.dispatch('selectHousehold', h);
|
||||||
this.$emit('readyToGo');
|
this.$emit('readyToGo');
|
||||||
},
|
},
|
||||||
|
pickHouseholdFound({selected, modal}) {
|
||||||
|
selected.forEach(function(item) {
|
||||||
|
this.selectHousehold(item.result);
|
||||||
|
}, this);
|
||||||
|
this.$refs.pickHousehold.resetSearch(); // to cast child method
|
||||||
|
modal.showModal = false;
|
||||||
|
},
|
||||||
removeHouseholdAddress() {
|
removeHouseholdAddress() {
|
||||||
this.$store.commit('removeHouseholdAddress');
|
this.$store.commit('removeHouseholdAddress');
|
||||||
},
|
},
|
||||||
|
@ -6,12 +6,13 @@
|
|||||||
<div class="list-household-members flex-table">
|
<div class="list-household-members flex-table">
|
||||||
<div
|
<div
|
||||||
v-for="conc in concerned"
|
v-for="conc in concerned"
|
||||||
class="item-bloc"
|
class="item-bloc"
|
||||||
v-bind:key="conc.person.id"
|
v-bind:key="conc.person.id"
|
||||||
>
|
>
|
||||||
<div class="pick-position item-row">
|
<div class="pick-position item-row">
|
||||||
<div class="person">
|
<div class="person">
|
||||||
<h3>{{ conc.person.text }}</h3>
|
<!-- <h3>{{ conc.person.text }}</h3> -->
|
||||||
|
<h3><person-text :person="conc.person"></person-text></h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="holder">
|
<div class="holder">
|
||||||
<button
|
<button
|
||||||
@ -53,6 +54,7 @@ import {mapGetters, mapState} from "vuex";
|
|||||||
import CurrentHousehold from "./CurrentHousehold";
|
import CurrentHousehold from "./CurrentHousehold";
|
||||||
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
||||||
import PersonComment from './PersonComment';
|
import PersonComment from './PersonComment';
|
||||||
|
import PersonText from '../../_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Positioning",
|
name: "Positioning",
|
||||||
@ -60,6 +62,7 @@ export default {
|
|||||||
CurrentHousehold,
|
CurrentHousehold,
|
||||||
PersonRenderBox,
|
PersonRenderBox,
|
||||||
PersonComment,
|
PersonComment,
|
||||||
|
PersonText
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
...mapState([
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li class="add-persons">
|
<li class="add-persons">
|
||||||
<a class="btn" :class="getClassButton" :title="$t(buttonTitle)"
|
<a class="btn" :class="getClassButton" :title="$t(buttonTitle)"
|
||||||
@click="openModal"><span v-if="displayTextButton">{{ $t(buttonTitle) }}</span></a>
|
@click="openModal"><span v-if="displayTextButton">{{ $t(buttonTitle) }}</span></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<teleport to="body">
|
<teleport to="body">
|
||||||
<modal v-if="modal.showModal"
|
<modal v-if="modal.showModal"
|
||||||
:modalDialogClass="modal.modalDialogClass"
|
:modalDialogClass="modal.modalDialogClass"
|
||||||
@close="modal.showModal = false">
|
@close="modal.showModal = false">
|
||||||
@ -181,7 +181,7 @@ export default {
|
|||||||
},
|
},
|
||||||
hasPriorSuggestion() {
|
hasPriorSuggestion() {
|
||||||
return this.search.priorSuggestion.key ? true : false;
|
return this.search.priorSuggestion.key ? true : false;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openModal() {
|
openModal() {
|
||||||
|
@ -25,6 +25,11 @@
|
|||||||
v-if="item.result.type === 'user'"
|
v-if="item.result.type === 'user'"
|
||||||
v-bind:item="item">
|
v-bind:item="item">
|
||||||
</suggestion-user>
|
</suggestion-user>
|
||||||
|
|
||||||
|
<suggestion-household
|
||||||
|
v-if="item.result.type === 'household'"
|
||||||
|
v-bind:item="item">
|
||||||
|
</suggestion-household>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -34,6 +39,7 @@
|
|||||||
import SuggestionPerson from './TypePerson';
|
import SuggestionPerson from './TypePerson';
|
||||||
import SuggestionThirdParty from './TypeThirdParty';
|
import SuggestionThirdParty from './TypeThirdParty';
|
||||||
import SuggestionUser from './TypeUser';
|
import SuggestionUser from './TypeUser';
|
||||||
|
import SuggestionHousehold from './TypeHousehold';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PersonSuggestion',
|
name: 'PersonSuggestion',
|
||||||
@ -41,6 +47,7 @@ export default {
|
|||||||
SuggestionPerson,
|
SuggestionPerson,
|
||||||
SuggestionThirdParty,
|
SuggestionThirdParty,
|
||||||
SuggestionUser,
|
SuggestionUser,
|
||||||
|
SuggestionHousehold,
|
||||||
},
|
},
|
||||||
props: [
|
props: [
|
||||||
'item',
|
'item',
|
||||||
@ -70,7 +77,7 @@ export default {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
div.results {
|
div.results {
|
||||||
div.list-item {
|
div.list-item {
|
||||||
padding: 0.4em 0.8em;
|
padding: 0.4em 0.8em;
|
||||||
@ -83,11 +90,11 @@ export default {
|
|||||||
label {
|
label {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
div.container {
|
div.container:not(.household) {
|
||||||
& > input {
|
& > input {
|
||||||
margin-right: 0.8em;
|
margin-right: 0.8em;
|
||||||
}
|
}
|
||||||
span:not(.name) {
|
> span:not(.name) {
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container household">
|
||||||
|
<household-render-box :household="item.result" :isAddressMultiline="false"></household-render-box>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right_actions">
|
||||||
|
<badge-entity
|
||||||
|
:entity="item.result"
|
||||||
|
:options="{ displayLong: true }">
|
||||||
|
</badge-entity>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||||
|
import HouseholdRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SuggestionHousehold',
|
||||||
|
components: {
|
||||||
|
BadgeEntity,
|
||||||
|
HouseholdRenderBox,
|
||||||
|
},
|
||||||
|
props: ['item'],
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<span class="name">
|
<span class="name">
|
||||||
{{ item.result.text }}
|
<person-text :person="item.result"></person-text>
|
||||||
</span>
|
</span>
|
||||||
<span class="birthday" v-if="hasBirthdate">
|
<span class="birthday" v-if="hasBirthdate">
|
||||||
{{ $d(item.result.birthdate.datetime, 'short') }}
|
{{ $d(item.result.birthdate.datetime, 'short') }}
|
||||||
@ -28,12 +28,14 @@
|
|||||||
<script>
|
<script>
|
||||||
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
|
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
|
||||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||||
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SuggestionPerson',
|
name: 'SuggestionPerson',
|
||||||
components: {
|
components: {
|
||||||
OnTheFly,
|
OnTheFly,
|
||||||
BadgeEntity
|
BadgeEntity,
|
||||||
|
PersonText,
|
||||||
},
|
},
|
||||||
props: ['item'],
|
props: ['item'],
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="container tpartycontainer">
|
<div class="container tpartycontainer">
|
||||||
<div class="tparty-identification">
|
<div class="tparty-identification">
|
||||||
<span class="name">
|
<span class="name">
|
||||||
{{ item.result.text }}
|
{{ item.result.text }}
|
||||||
</span>
|
</span>
|
||||||
<span class="location">
|
<span class="location">
|
||||||
<template v-if="hasAddress">
|
<template v-if="hasAddress">
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="render === 'bloc'" class="item-bloc">
|
<div v-if="render === 'bloc'" class="item-bloc">
|
||||||
<section class="chill-entity entity-person">
|
<section class="chill-entity entity-person">
|
||||||
<div class="item-row entity-bloc">
|
<div class="item-row entity-bloc">
|
||||||
|
|
||||||
<div class="item-col">
|
<div class="item-col">
|
||||||
<div class="entity-label">
|
<div class="entity-label">
|
||||||
|
|
||||||
<div :class="'denomination h' + options.hLevel">
|
<div :class="'denomination h' + options.hLevel">
|
||||||
|
|
||||||
<a v-if="options.addLink === true" :href="getUrl">
|
<a v-if="options.addLink === true" :href="getUrl">
|
||||||
|
<!-- use person-text here to avoid code duplication ? TODO -->
|
||||||
<span class="firstname">{{ person.firstName }}</span>
|
<span class="firstname">{{ person.firstName }}</span>
|
||||||
<span class="lastname">{{ person.lastName }}</span>
|
<span class="lastname">{{ person.lastName }}</span>
|
||||||
<span v-if="person.altNames && options.addAltNames == true" class="altnames">
|
<span v-if="person.altNames && options.addAltNames == true" class="altnames">
|
||||||
@ -16,19 +17,20 @@
|
|||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<span class="firstname">{{ person.firstName }}</span>
|
<!-- use person-text here to avoid code duplication ? TODO -->
|
||||||
<span class="lastname">{{ person.lastName }}</span>
|
<span class="firstname">{{ person.firstName }}</span>
|
||||||
<span v-if="person.deathdate" class="deathdate"> (‡)</span>
|
<span class="lastname">{{ person.lastName }}</span>
|
||||||
<span v-if="person.altNames && options.addAltNames == true" class="altnames">
|
<span v-if="person.deathdate" class="deathdate"> (‡)</span>
|
||||||
<span :class="'altname altname-' + altNameKey">{{ altNameLabel }}</span>
|
<span v-if="person.altNames && options.addAltNames == true" class="altnames">
|
||||||
</span>
|
<span :class="'altname altname-' + altNameKey">{{ altNameLabel }}</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
<span v-if="options.addId == true" class="id-number" :title="'n° ' + person.id">{{ person.id }}</span>
|
<span v-if="options.addId == true" class="id-number" :title="'n° ' + person.id">{{ person.id }}</span>
|
||||||
|
|
||||||
<badge-entity v-if="options.addEntity === true"
|
<badge-entity v-if="options.addEntity === true"
|
||||||
:entity="person"
|
:entity="person"
|
||||||
:options="{ displayLong: options.entityDisplayLong }">
|
:options="{ displayLong: options.entityDisplayLong }">
|
||||||
</badge-entity>
|
</badge-entity>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -47,98 +49,96 @@
|
|||||||
{{ $t('renderbox.deathdate') + ' ' + deathdate }}
|
{{ $t('renderbox.deathdate') + ' ' + deathdate }}
|
||||||
</time>
|
</time>
|
||||||
|
|
||||||
<span v-if="options.addAge && person.birthdate" class="age">{{ getAge }} {{ $t('renderbox.years_old')}}</span>
|
<span v-if="options.addAge && person.birthdate" class="age">{{ $tc('renderbox.years_old', person.age) }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="item-col">
|
<div class="item-col">
|
||||||
<div class="float-button bottom">
|
<div class="float-button bottom">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="action">
|
<div class="action">
|
||||||
<slot name="record-actions"></slot>
|
<slot name="record-actions"></slot>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-content fa-ul">
|
<ul class="list-content fa-ul">
|
||||||
|
<li v-if="person.current_household_id">
|
||||||
|
<i class="fa fa-li fa-map-marker"></i>
|
||||||
|
<address-render-box v-if="person.current_household_address"
|
||||||
|
:address="person.current_household_address"
|
||||||
|
:isMultiline="isMultiline">
|
||||||
|
</address-render-box>
|
||||||
|
<p v-else class="chill-no-data-statement">
|
||||||
|
{{ $t('renderbox.household_without_address') }}
|
||||||
|
</p>
|
||||||
|
<a v-if="options.addHouseholdLink === true"
|
||||||
|
:href="getCurrentHouseholdUrl"
|
||||||
|
:title="$t('persons_associated.show_household_number', {id: person.current_household_id})">
|
||||||
|
<span class="badge rounded-pill bg-chill-beige">
|
||||||
|
<i class="fa fa-fw fa-home"></i><!--{{ $t('persons_associated.show_household') }}-->
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li v-else-if="options.addNoData">
|
||||||
|
<i class="fa fa-li fa-map-marker"></i>
|
||||||
|
<p class="chill-no-data-statement">
|
||||||
|
{{ $t('renderbox.no_data') }}
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li v-if="person.current_household_id">
|
<li v-if="person.mobilenumber">
|
||||||
<i class="fa fa-li fa-map-marker"></i>
|
<i class="fa fa-li fa-mobile"></i>
|
||||||
<address-render-box v-if="person.current_household_address"
|
<a :href="'tel: ' + person.mobilenumber">{{ person.mobilenumber }}</a>
|
||||||
:address="person.current_household_address"
|
</li>
|
||||||
:isMultiline="isMultiline">
|
<li v-else-if="options.addNoData">
|
||||||
</address-render-box>
|
<i class="fa fa-li fa-mobile"></i>
|
||||||
<p v-else class="chill-no-data-statement">
|
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
||||||
{{ $t('renderbox.household_without_address') }}
|
</li>
|
||||||
</p>
|
<li v-if="person.phonenumber">
|
||||||
<a v-if="options.addHouseholdLink === true"
|
<i class="fa fa-li fa-phone"></i>
|
||||||
:href="getCurrentHouseholdUrl"
|
<a :href="'tel: ' + person.phonenumber">{{ person.phonenumber }}</a>
|
||||||
:title="$t('persons_associated.show_household_number', {id: person.current_household_id})">
|
</li>
|
||||||
<span class="badge rounded-pill bg-chill-beige">
|
<li v-else-if="options.addNoData">
|
||||||
<i class="fa fa-fw fa-home"></i><!--{{ $t('persons_associated.show_household') }}-->
|
<i class="fa fa-li fa-phone"></i>
|
||||||
</span>
|
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
||||||
</a>
|
</li>
|
||||||
</li>
|
|
||||||
<li v-else-if="options.addNoData">
|
|
||||||
<i class="fa fa-li fa-map-marker"></i>
|
|
||||||
<p class="chill-no-data-statement">
|
|
||||||
{{ $t('renderbox.no_data') }}
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li v-if="person.mobilenumber">
|
<li v-if="person.centers !== undefined && person.centers.length > 0 && options.addCenter">
|
||||||
<i class="fa fa-li fa-mobile"></i>
|
<i class="fa fa-li fa-long-arrow-right"></i>
|
||||||
<a :href="'tel: ' + person.mobilenumber">{{ person.mobilenumber }}</a>
|
<template v-for="c in person.centers">{{ c.name }}</template>
|
||||||
</li>
|
</li>
|
||||||
<li v-else-if="options.addNoData">
|
<li v-else-if="options.addNoData">
|
||||||
<i class="fa fa-li fa-mobile"></i>
|
<i class="fa fa-li fa-long-arrow-right"></i>
|
||||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="person.phonenumber">
|
<slot name="custom-zone"></slot>
|
||||||
<i class="fa fa-li fa-phone"></i>
|
|
||||||
<a :href="'tel: ' + person.phonenumber">{{ person.phonenumber }}</a>
|
|
||||||
</li>
|
|
||||||
<li v-else-if="options.addNoData">
|
|
||||||
<i class="fa fa-li fa-phone"></i>
|
|
||||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li v-if="person.centers !== undefined && person.centers.length > 0 && options.addCenter">
|
</ul>
|
||||||
<i class="fa fa-li fa-long-arrow-right"></i>
|
</div>
|
||||||
<template v-for="c in person.centers">{{ c.name }}</template>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
<li v-else-if="options.addNoData">
|
|
||||||
<i class="fa fa-li fa-long-arrow-right"></i>
|
|
||||||
<p class="chill-no-data-statement">{{ $t('renderbox.no_data') }}</p>
|
|
||||||
</li>
|
|
||||||
<slot name="custom-zone"></slot>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span v-if="render === 'badge'" class="chill-entity entity-person badge-person">
|
<span v-if="render === 'badge'" class="chill-entity entity-person badge-person">
|
||||||
<a v-if="options.addLink === true" :href="getUrl">
|
<a v-if="options.addLink === true" :href="getUrl">
|
||||||
<span v-if="options.isHolder" class="fa-stack fa-holder" :title="$t('renderbox.holder')">
|
<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-circle fa-stack-1x text-success"></i>
|
||||||
<i class="fa fa-stack-1x">T</i>
|
<i class="fa fa-stack-1x">T</i>
|
||||||
</span>
|
</span>
|
||||||
{{ person.text }}
|
|
||||||
<span v-if="person.deathdate" class="deathdate"> (‡)</span>
|
<person-text :person="person"></person-text>
|
||||||
</a>
|
</a>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<span v-if="options.isHolder" class="fa-stack fa-holder" :title="$t('renderbox.holder')">
|
<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-circle fa-stack-1x text-success"></i>
|
||||||
<i class="fa fa-stack-1x">T</i>
|
<i class="fa fa-stack-1x">T</i>
|
||||||
</span>
|
</span>
|
||||||
{{ person.text }}
|
<person-text :person="person"></person-text>
|
||||||
<span v-if="person.deathdate" class="deathdate"> (‡)</span>
|
|
||||||
</span>
|
</span>
|
||||||
<slot name="post-badge"></slot>
|
<slot name="post-badge"></slot>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -147,13 +147,15 @@ import {dateToISO} from 'ChillMainAssets/chill/js/date.js';
|
|||||||
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
||||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||||
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PersonRenderBox",
|
name: "PersonRenderBox",
|
||||||
components: {
|
components: {
|
||||||
AddressRenderBox,
|
AddressRenderBox,
|
||||||
Confidential,
|
Confidential,
|
||||||
BadgeEntity
|
BadgeEntity,
|
||||||
|
PersonText
|
||||||
},
|
},
|
||||||
props: ['person', 'options', 'render', 'returnPath'],
|
props: ['person', 'options', 'render', 'returnPath'],
|
||||||
computed: {
|
computed: {
|
||||||
@ -168,7 +170,7 @@ export default {
|
|||||||
return this.person.gender === 'woman' ? 'fa-venus' : this.person.gender === 'man' ? 'fa-mars' : this.person.gender === 'neuter' ? 'fa-neuter' : 'fa-genderless';
|
return this.person.gender === 'woman' ? 'fa-venus' : this.person.gender === 'man' ? 'fa-mars' : this.person.gender === 'neuter' ? 'fa-neuter' : 'fa-genderless';
|
||||||
},
|
},
|
||||||
getGenderTranslation: function() {
|
getGenderTranslation: function() {
|
||||||
return this.person.gender === 'woman' ? 'renderbox.birthday.woman' : 'renderbox.birthday.man';
|
return this.person.gender === 'woman' ? 'renderbox.birthday.woman' : 'renderbox.birthday.man';
|
||||||
},
|
},
|
||||||
getGender() {
|
getGender() {
|
||||||
return this.person.gender === 'woman' ? 'person.gender.woman' : this.person.gender === 'man' ? 'person.gender.man' : this.person.gender === 'neuter' ? 'person.gender.neuter' : 'person.gender.undefined';
|
return this.person.gender === 'woman' ? 'person.gender.woman' : this.person.gender === 'man' ? 'person.gender.man' : this.person.gender === 'neuter' ? 'person.gender.neuter' : 'person.gender.undefined';
|
||||||
@ -200,24 +202,6 @@ export default {
|
|||||||
getUrl: function() {
|
getUrl: function() {
|
||||||
return `/fr/person/${this.person.id}/general`;
|
return `/fr/person/${this.person.id}/general`;
|
||||||
},
|
},
|
||||||
getAge: function() {
|
|
||||||
// TODO only one abstract function
|
|
||||||
if(this.person.birthdate && !this.person.deathdate){
|
|
||||||
const birthday = new Date(this.person.birthdate.datetime)
|
|
||||||
const now = new Date()
|
|
||||||
return (now.getFullYear() - birthday.getFullYear())
|
|
||||||
} else if(this.person.birthdate && this.person.deathdate){
|
|
||||||
const birthday = new Date(this.person.birthdate.datetime)
|
|
||||||
const deathdate = new Date(this.person.deathdate.datetime)
|
|
||||||
return (deathdate.getFullYear() - birthday.getFullYear())
|
|
||||||
} else if(!this.person.birthdate && this.person.deathdate.datetime) {
|
|
||||||
// todo: change this
|
|
||||||
return "Age unknown"
|
|
||||||
} else {
|
|
||||||
// todo: change this
|
|
||||||
return "Age unknown"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getCurrentHouseholdUrl: function() {
|
getCurrentHouseholdUrl: function() {
|
||||||
let returnPath = this.returnPath ? `?returnPath=${this.returnPath}` : ``;
|
let returnPath = this.returnPath ? `?returnPath=${this.returnPath}` : ``;
|
||||||
return `/fr/person/household/${this.person.current_household_id}/summary${returnPath}`
|
return `/fr/person/household/${this.person.current_household_id}/summary${returnPath}`
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<span v-if="isCut">{{ cutText }}</span>
|
||||||
|
<span v-else class="person-text">
|
||||||
|
<span class="firstname">{{ person.firstName }}</span>
|
||||||
|
<span class="lastname">{{ person.lastName }}</span>
|
||||||
|
<span v-if="person.altNames && person.altNames.length > 0" class="altnames">
|
||||||
|
<span :class="'altname altname-' + altNameKey"> ({{ altNameLabel }})</span>
|
||||||
|
</span>
|
||||||
|
<span class="age" v-if="this.addAge && person.birthdate !== null && person.deathdate === null">{{ $tc('renderbox.years_old', person.age) }}</span>
|
||||||
|
<span v-else-if="this.addAge && person.deathdate !== null"> (‡)</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "PersonText",
|
||||||
|
props: {
|
||||||
|
person: {
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
isCut: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
addAge: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
altNameLabel: function() {
|
||||||
|
for(let i = 0; i < this.person.altNames.length; i++){
|
||||||
|
return this.person.altNames[i].label
|
||||||
|
}
|
||||||
|
},
|
||||||
|
altNameKey: function() {
|
||||||
|
for(let i = 0; i < this.person.altNames.length; i++){
|
||||||
|
return this.person.altNames[i].key
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cutText: function() {
|
||||||
|
let more = (this.person.text.length > 15) ?'…' : '';
|
||||||
|
return this.person.text.slice(0,15) + more;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -31,7 +31,7 @@
|
|||||||
<li class="associated-persons">
|
<li class="associated-persons">
|
||||||
<span class="item-key">{{ 'Participants'|trans ~ ' : ' }}</span>
|
<span class="item-key">{{ 'Participants'|trans ~ ' : ' }}</span>
|
||||||
{% for p in w.persons %}
|
{% for p in w.persons %}
|
||||||
<span class="badge-person">{{ p|chill_entity_render_box }}</span>
|
<span class="badge-person">{{ p|chill_entity_render_box({'addAgeBadge': true}) }}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
* addCenter bool
|
* addCenter bool
|
||||||
* hLevel integer
|
* hLevel integer
|
||||||
* addDeath bool
|
* addDeath bool
|
||||||
|
* addAgeBadge bool
|
||||||
* address_multiline bool
|
* address_multiline bool
|
||||||
* customButtons [
|
* customButtons [
|
||||||
'before' Twig\Markup, (injected with macro)
|
'before' Twig\Markup, (injected with macro)
|
||||||
@ -40,6 +41,11 @@
|
|||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
</span>
|
</span>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
{%- if options['addAgeBadge'] -%}
|
||||||
|
{% if person.age is not null and person.deathDate is null %}
|
||||||
|
<span>({{- 'years_old'|trans({ 'age': person.age }) -}})</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% endmacro raw %}
|
{% endmacro raw %}
|
||||||
|
|
||||||
{% macro label(person, options) %}
|
{% macro label(person, options) %}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
'render': 'label',
|
'render': 'label',
|
||||||
'addLink': true,
|
'addLink': true,
|
||||||
'addInfo': true,
|
'addInfo': true,
|
||||||
|
'addAgeBadge': true,
|
||||||
'customArea': {
|
'customArea': {
|
||||||
'afterLabel': _self.addHolder(member.holder)
|
'afterLabel': _self.addHolder(member.holder)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Search;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Search\SearchApiInterface;
|
||||||
|
use Chill\MainBundle\Search\SearchApiQuery;
|
||||||
|
use Chill\MainBundle\Search\Utils\ExtractDateFromPattern;
|
||||||
|
use Chill\MainBundle\Search\Utils\ExtractPhonenumberFromPattern;
|
||||||
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
|
use Chill\PersonBundle\Repository\Household\HouseholdRepository;
|
||||||
|
use Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
use function array_map;
|
||||||
|
use function count;
|
||||||
|
use function in_array;
|
||||||
|
|
||||||
|
class SearchHouseholdApiProvider implements SearchApiInterface
|
||||||
|
{
|
||||||
|
private AuthorizationHelperInterface $authorizationHelper;
|
||||||
|
|
||||||
|
private ExtractDateFromPattern $extractDateFromPattern;
|
||||||
|
|
||||||
|
private ExtractPhonenumberFromPattern $extractPhonenumberFromPattern;
|
||||||
|
|
||||||
|
private HouseholdRepository $householdRepository;
|
||||||
|
|
||||||
|
private PersonACLAwareRepositoryInterface $personACLAwareRepository;
|
||||||
|
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
HouseholdRepository $householdRepository,
|
||||||
|
PersonACLAwareRepositoryInterface $personACLAwareRepository,
|
||||||
|
Security $security,
|
||||||
|
AuthorizationHelperInterface $authorizationHelper,
|
||||||
|
ExtractDateFromPattern $extractDateFromPattern,
|
||||||
|
ExtractPhonenumberFromPattern $extractPhonenumberFromPattern
|
||||||
|
) {
|
||||||
|
$this->householdRepository = $householdRepository;
|
||||||
|
$this->personACLAwareRepository = $personACLAwareRepository;
|
||||||
|
$this->security = $security;
|
||||||
|
$this->authorizationHelper = $authorizationHelper;
|
||||||
|
$this->extractDateFromPattern = $extractDateFromPattern;
|
||||||
|
$this->extractPhonenumberFromPattern = $extractPhonenumberFromPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResult(string $key, array $metadata, float $pertinence)
|
||||||
|
{
|
||||||
|
return $this->householdRepository->find($metadata['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prepare(array $metadatas): void
|
||||||
|
{
|
||||||
|
$ids = array_map(static fn ($m) => $m['id'], $metadatas);
|
||||||
|
|
||||||
|
$this->householdRepository->findBy(['id' => $ids]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideQuery(string $pattern, array $parameters): SearchApiQuery
|
||||||
|
{
|
||||||
|
$datesResult = $this->extractDateFromPattern->extractDates($pattern);
|
||||||
|
$phoneResult = $this->extractPhonenumberFromPattern->extractPhonenumber($datesResult->getFilteredSubject());
|
||||||
|
$filtered = $phoneResult->getFilteredSubject();
|
||||||
|
|
||||||
|
$query = $this->personACLAwareRepository->buildAuthorizedQuery(
|
||||||
|
$filtered,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
count($datesResult->getFound()) > 0 ? $datesResult->getFound()[0] : null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
count($phoneResult->getFound()) > 0 ? $phoneResult->getFound()[0] : null
|
||||||
|
);
|
||||||
|
|
||||||
|
$query
|
||||||
|
->setDistinct(true, 'household_id')
|
||||||
|
->setFromClause(
|
||||||
|
'view_chill_person_household_address AS vcpha ' .
|
||||||
|
'JOIN chill_person_person AS person ON vcpha.person_id = person.id'
|
||||||
|
)
|
||||||
|
->setSelectKey('household')
|
||||||
|
->andWhereClause('vcpha.validTo IS NULL', [])
|
||||||
|
->setSelectJsonbMetadata("jsonb_build_object('id', vcpha.household_id)");
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsResult(string $key, array $metadatas): bool
|
||||||
|
{
|
||||||
|
return 'household' === $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsTypes(string $pattern, array $types, array $parameters): bool
|
||||||
|
{
|
||||||
|
return in_array('household', $types, true);
|
||||||
|
}
|
||||||
|
}
|
@ -179,11 +179,13 @@ class PersonJsonNormalizer implements
|
|||||||
return [
|
return [
|
||||||
'type' => 'person',
|
'type' => 'person',
|
||||||
'id' => $person->getId(),
|
'id' => $person->getId(),
|
||||||
'text' => $this->render->renderString($person),
|
'text' => $this->render->renderString($person, ['addAge' => false]),
|
||||||
|
'textAge' => $this->render->renderString($person, ['addAge' => true]),
|
||||||
'firstName' => $person->getFirstName(),
|
'firstName' => $person->getFirstName(),
|
||||||
'lastName' => $person->getLastName(),
|
'lastName' => $person->getLastName(),
|
||||||
'birthdate' => $this->normalizer->normalize($person->getBirthdate(), $format, $context),
|
'birthdate' => $this->normalizer->normalize($person->getBirthdate(), $format, $context),
|
||||||
'deathdate' => $this->normalizer->normalize($person->getDeathdate(), $format, $context),
|
'deathdate' => $this->normalizer->normalize($person->getDeathdate(), $format, $context),
|
||||||
|
'age' => $this->normalizer->normalize($person->getAge(), $format, $context),
|
||||||
'centers' => $this->normalizer->normalize($this->centerResolverManager->resolveCenters($person), $format, $context),
|
'centers' => $this->normalizer->normalize($this->centerResolverManager->resolveCenters($person), $format, $context),
|
||||||
'phonenumber' => $person->getPhonenumber(),
|
'phonenumber' => $person->getPhonenumber(),
|
||||||
'mobilenumber' => $person->getMobilenumber(),
|
'mobilenumber' => $person->getMobilenumber(),
|
||||||
|
@ -15,6 +15,7 @@ use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender;
|
|||||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Symfony\Component\Templating\EngineInterface;
|
use Symfony\Component\Templating\EngineInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
|
|
||||||
@ -27,12 +28,16 @@ class PersonRender extends AbstractChillEntityRender
|
|||||||
|
|
||||||
private EngineInterface $engine;
|
private EngineInterface $engine;
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ConfigPersonAltNamesHelper $configAltNamesHelper,
|
ConfigPersonAltNamesHelper $configAltNamesHelper,
|
||||||
EngineInterface $engine
|
EngineInterface $engine,
|
||||||
|
TranslatorInterface $translator
|
||||||
) {
|
) {
|
||||||
$this->configAltNamesHelper = $configAltNamesHelper;
|
$this->configAltNamesHelper = $configAltNamesHelper;
|
||||||
$this->engine = $engine;
|
$this->engine = $engine;
|
||||||
|
$this->translator = $translator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,6 +58,7 @@ class PersonRender extends AbstractChillEntityRender
|
|||||||
'customButtons' => $options['customButtons'] ?? [],
|
'customButtons' => $options['customButtons'] ?? [],
|
||||||
'customArea' => $options['customArea'] ?? [],
|
'customArea' => $options['customArea'] ?? [],
|
||||||
'addDeath' => $options['addDeath'] ?? true,
|
'addDeath' => $options['addDeath'] ?? true,
|
||||||
|
'addAgeBadge' => $options['addAgeBadge'] ?? false,
|
||||||
];
|
];
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -70,6 +76,13 @@ class PersonRender extends AbstractChillEntityRender
|
|||||||
*/
|
*/
|
||||||
public function renderString($person, array $options): string
|
public function renderString($person, array $options): string
|
||||||
{
|
{
|
||||||
|
$options = array_merge(['addAge' => true], $options);
|
||||||
|
|
||||||
|
if (null !== $person->getAge() && $person->getDeathDate() === null && $options['addAge']) {
|
||||||
|
return $person->getFirstName() . ' ' . $person->getLastName()
|
||||||
|
. $this->addAltNames($person, false) . ' (' . $this->translator->trans('years_old', ['age' => $person->getAge()]) . ')';
|
||||||
|
}
|
||||||
|
|
||||||
return $person->getFirstName() . ' ' . $person->getLastName()
|
return $person->getFirstName() . ' ' . $person->getLastName()
|
||||||
. $this->addAltNames($person, false);
|
. $this->addAltNames($person, false);
|
||||||
}
|
}
|
||||||
|
@ -11,3 +11,7 @@ services:
|
|||||||
Chill\PersonBundle\Search\SearchPersonApiProvider:
|
Chill\PersonBundle\Search\SearchPersonApiProvider:
|
||||||
autowire: true
|
autowire: true
|
||||||
autoconfigure: true
|
autoconfigure: true
|
||||||
|
|
||||||
|
Chill\PersonBundle\Search\SearchHouseholdApiProvider:
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user