fix conflict in CHANGELOG

This commit is contained in:
nobohan 2021-11-08 12:41:11 +01:00
commit c979de962e
21 changed files with 287 additions and 127 deletions

View File

@ -12,6 +12,9 @@ and this project adheres to
<!-- write down unreleased development here -->
* [person]: Add civility to the person
* [person]: Various improvements on the edit person form
* [person]: Set available_languages and available_countries as parameters for use in the edit person form
* [activity] Bugfix: documents can now be added to an activity.
* [tasks] improve tasks with filter order
* [tasks] refactor singleControllerTasks: limit the number of conditions from the context
@ -35,6 +38,7 @@ and this project adheres to
## Test releases
### Test release 2021-10-27
* [person]: delete double actions buttons on search person page

View File

@ -107,6 +107,9 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
$container->setParameter('chill_main.available_languages',
$config['available_languages']);
$container->setParameter('chill_main.available_countries',
$config['available_countries']);
$container->setParameter('chill_main.routing.resources',
$config['routing']['resources']);

View File

@ -51,6 +51,10 @@ class Configuration implements ConfigurationInterface
->defaultValue(array('fr'))
->prototype('scalar')->end()
->end() // end of array 'available_languages'
->arrayNode('available_countries')
->defaultValue(array('FR'))
->prototype('scalar')->end()
->end() // end of array 'available_countries'
->arrayNode('routing')
->children()
->arrayNode('resources')

View File

@ -54,7 +54,7 @@ class CommentType extends AbstractType
$data = $event->getForm()->getData();
$comment = $event->getData() ?? ['comment' => ''];
if ($data->getComment() !== $comment['comment']) {
if (null !== $data && $data->getComment() !== $comment['comment']) {
$data->setDate(new \DateTime());
$data->setUserId($this->user->getId());
$event->getForm()->setData($data);

View File

@ -28,6 +28,7 @@ use Chill\MainBundle\Form\Type\DataTransformer\ObjectToIdTransformer;
use Doctrine\Persistence\ObjectManager;
use Chill\MainBundle\Form\Type\Select2ChoiceType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
/**
* Extends choice to allow adding select2 library on widget
@ -37,31 +38,25 @@ use Chill\MainBundle\Templating\TranslatableStringHelper;
*/
class Select2CountryType extends AbstractType
{
/**
* @var RequestStack
*/
private $requestStack;
private RequestStack $requestStack;
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
private ObjectManager $em;
/**
* @var ObjectManager
*/
private $em;
protected TranslatableStringHelper $translatableStringHelper;
protected ParameterBagInterface $parameterBag;
public function __construct(
RequestStack $requestStack,
ObjectManager $em,
TranslatableStringHelper $translatableStringHelper
TranslatableStringHelper $translatableStringHelper,
ParameterBagInterface $parameterBag
)
{
$this->requestStack = $requestStack;
$this->em = $em;
$this->translatableStringHelper = $translatableStringHelper;
$this->parameterBag = $parameterBag;
}
public function getBlockPrefix()
@ -82,19 +77,29 @@ class Select2CountryType extends AbstractType
public function configureOptions(OptionsResolver $resolver)
{
$locale = $this->requestStack->getCurrentRequest()->getLocale();
$countries = $this->em->getRepository('Chill\MainBundle\Entity\Country')->findAll();
$choices = array();
$choices = [];
$preferredCountries = $this->parameterBag->get('chill_main.available_countries');
$preferredChoices = [];
foreach ($countries as $c) {
$choices[$c->getId()] = $this->translatableStringHelper->localize($c->getName());
}
foreach ($preferredCountries as $pc) {
foreach ($countries as $c) {
if ($c->getCountryCode() == $pc) {
$preferredChoices[$c->getId()] = $this->translatableStringHelper->localize($c->getName());
}
}
}
asort($choices, SORT_STRING | SORT_FLAG_CASE);
$resolver->setDefaults(array(
'class' => 'Chill\MainBundle\Entity\Country',
'choices' => array_combine(array_values($choices),array_keys($choices))
'choices' => array_combine(array_values($choices),array_keys($choices)),
'preferred_choices' => array_combine(array_values($preferredChoices), array_keys($preferredChoices))
));
}
}

View File

@ -28,37 +28,32 @@ use Chill\MainBundle\Form\Type\DataTransformer\MultipleObjectsToIdTransformer;
use Doctrine\Persistence\ObjectManager;
use Chill\MainBundle\Form\Type\Select2ChoiceType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
/**
* Extends choice to allow adding select2 library on widget for languages (multiple)
*/
class Select2LanguageType extends AbstractType
{
/**
* @var RequestStack
*/
private $requestStack;
private RequestStack $requestStack;
/**
* @var ObjectManager
*/
private $em;
private ObjectManager $em;
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
protected TranslatableStringHelper $translatableStringHelper;
protected ParameterBagInterface $parameterBag;
public function __construct(
RequestStack $requestStack,
ObjectManager $em,
TranslatableStringHelper $translatableStringHelper
TranslatableStringHelper $translatableStringHelper,
ParameterBagInterface $parameterBag
)
{
$this->requestStack = $requestStack;
$this->em = $em;
$this->translatableStringHelper = $translatableStringHelper;
$this->parameterBag = $parameterBag;
}
public function getBlockPrefix()
@ -79,19 +74,24 @@ class Select2LanguageType extends AbstractType
public function configureOptions(OptionsResolver $resolver)
{
$locale = $this->requestStack->getCurrentRequest()->getLocale();
$languages = $this->em->getRepository('Chill\MainBundle\Entity\Language')->findAll();
$choices = array();
$preferredLanguages = $this->parameterBag->get('chill_main.available_languages');
$choices = [];
$preferredChoices = [];
foreach ($languages as $l) {
$choices[$l->getId()] = $this->translatableStringHelper->localize($l->getName());
}
foreach ($preferredLanguages as $l) {
$preferredChoices[$l] = $choices[$l];
}
asort($choices, SORT_STRING | SORT_FLAG_CASE);
$resolver->setDefaults(array(
'class' => 'Chill\MainBundle\Entity\Language',
'choices' => array_combine(array_values($choices),array_keys($choices))
'choices' => array_combine(array_values($choices), array_keys($choices)),
'preferred_choices' => array_combine(array_values($preferredChoices), array_keys($preferredChoices))
));
}
}

View File

@ -1 +1,5 @@
require("./show_hide.js");
//require("./show_hide.js");
import { ShowHide } from './show_hide.js'
export { ShowHide }

View File

@ -134,4 +134,4 @@ var ShowHide = function(options) {
};
};
export {ShowHide};
export { ShowHide };

View File

@ -5,82 +5,89 @@ import App from './App.vue';
const i18n = _createI18n(addressMessages);
let inputs = document.querySelectorAll('input[type="hidden"][data-input-address]');
const addAddressInput = (inputs) => {
const isNumeric = function(v) { return !isNaN(v); };
inputs.forEach(el => {
let
addressId = el.value,
uniqid = el.dataset.inputAddress,
container = document.querySelector('div[data-input-address-container="' + uniqid + '"]'),
isEdit = addressId !== '',
addressIdInt = addressId !== '' ? parseInt(addressId) : null
;
inputs.forEach(el => {
let
addressId = el.value,
uniqid = el.dataset.inputAddress,
container = document.querySelector('div[data-input-address-container="' + uniqid + '"]'),
isEdit = addressId !== '',
addressIdInt = addressId !== '' ? parseInt(addressId) : null
;
if (container === null) {
throw Error("no container");
}
console.log('useValidFrom', el.dataset.useValidFrom === '1');
if (container === null) {
throw Error("no container");
}
console.log('useValidFrom', el.dataset.useValidFrom === '1');
const app = createApp({
template: `<app v-bind:addAddress="this.addAddress" @address-created="associateToInput"></app>`,
data() {
return {
addAddress: {
context: {
// for legacy ? can be remove ?
target: {
name: 'input-address',
id: addressIdInt,
},
edit: isEdit,
addressId: addressIdInt,
},
options: {
/// Options override default.
/// null value take default component value defined in AddAddress data()
button: {
text: {
create: el.dataset.buttonTextCreate || null,
edit: el.dataset.buttonTextUpdate || null,
const app = createApp({
template: `<app v-bind:addAddress="this.addAddress" @address-created="associateToInput"></app>`,
data() {
return {
addAddress: {
context: {
// for legacy ? can be remove ?
target: {
name: 'input-address',
id: addressIdInt,
},
size: null,
displayText: true
edit: isEdit,
addressId: addressIdInt,
},
options: {
/// Options override default.
/// null value take default component value defined in AddAddress data()
button: {
text: {
create: el.dataset.buttonTextCreate || null,
edit: el.dataset.buttonTextUpdate || null,
},
size: null,
displayText: true
},
/// Modal title text if create or edit address (trans chain, see i18n)
title: {
create: null,
edit: null,
},
/// Modal title text if create or edit address (trans chain, see i18n)
title: {
create: null,
edit: null,
},
/// Display panes in Modal for step123
openPanesInModal: true,
/// Display panes in Modal for step123
openPanesInModal: true,
/// Display actions buttons of panes in a sticky-form-button navbar
stickyActions: false,
showMessageWhenNoAddress: true,
/// Display actions buttons of panes in a sticky-form-button navbar
stickyActions: false,
showMessageWhenNoAddress: true,
/// Use Date fields
useDate: {
validFrom: el.dataset.useValidFrom === '1' || false, //boolean, default: false
validTo: el.dataset.useValidTo === '1' || false, //boolean, default: false
},
/// Use Date fields
useDate: {
validFrom: el.dataset.useValidFrom === '1' || false, //boolean, default: false
validTo: el.dataset.useValidTo === '1' || false, //boolean, default: false
},
/// Don't display show renderbox Address: showPane display only a button
onlyButton: false,
/// Don't display show renderbox Address: showPane display only a button
onlyButton: false,
}
}
}
},
methods: {
associateToInput(payload) {
el.value = payload.addressId;
}
}
},
methods: {
associateToInput(payload) {
el.value = payload.addressId;
}
}
})
.use(i18n)
.component('app', App)
.mount(container);
});
})
.use(i18n)
.component('app', App)
.mount(container);
});
};
document.addEventListener('DOMContentLoaded', (_e) =>
addAddressInput(document.querySelectorAll('input[type="hidden"][data-input-address]'))
);
window.addEventListener('collection-add-entry', (e) =>
addAddressInput(e.detail.entry.querySelectorAll('input[type="hidden"][data-input-address]'))
);

View File

@ -39,3 +39,4 @@ assetic:
chill_main:
available_languages: [fr, en]
available_countries: [FR]

View File

@ -25,6 +25,7 @@ services:
- "@request_stack"
- "@doctrine.orm.entity_manager"
- "@chill.main.helper.translatable_string"
- '@Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface'
tags:
- { name: form.type, alias: select2_chill_country }
@ -34,6 +35,7 @@ services:
- "@request_stack"
- "@doctrine.orm.entity_manager"
- "@chill.main.helper.translatable_string"
- '@Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface'
tags:
- { name: form.type, alias: select2_chill_language }

View File

@ -77,11 +77,13 @@ class Configuration implements ConfigurationInterface
->append($this->addFieldNode('nationality'))
->append($this->addFieldNode('country_of_birth'))
->append($this->addFieldNode('marital_status'))
->append($this->addFieldNode('civility'))
->append($this->addFieldNode('spoken_languages'))
->append($this->addFieldNode('address'))
->append($this->addFieldNode('accompanying_period'))
->append($this->addFieldNode('memo'))
->append($this->addFieldNode('number_of_children'))
->append($this->addFieldNode('acceptEmail'))
->arrayNode('alt_names')
->defaultValue([])
->arrayPrototype()

View File

@ -34,6 +34,7 @@ use Chill\PersonBundle\Entity\MaritalStatus;
use Chill\PersonBundle\Entity\Household\HouseholdMember;
use Chill\MainBundle\Entity\HasCenterInterface;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Civility;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\PersonBundle\Entity\Person\PersonCurrentAddress;
use DateTime;
@ -212,6 +213,15 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
*/
private $maritalStatus;
/**
* The marital status of the person
* @var Civility
*
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Civility")
* @ORM\JoinColumn(nullable=true)
*/
private $civility;
/**
* The date of the last marital status change of the person
* @var \DateTime
@ -982,6 +992,28 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
return $this->maritalStatus;
}
/**
* Set civility
*
* @param Civility $civility
* @return Person
*/
public function setCivility(Civility $civility = null)
{
$this->civility = $civility;
return $this;
}
/**
* Get civility
*
* @return Civility
*/
public function getCivility()
{
return $this->civility;
}
/**
* Set contactInfo
*

View File

@ -22,6 +22,7 @@
namespace Chill\PersonBundle\Form;
use Chill\CustomFieldsBundle\Form\Type\CustomFieldType;
use Chill\MainBundle\Entity\Civility;
use Chill\MainBundle\Form\Type\ChillCollectionType;
use Chill\MainBundle\Form\Type\ChillTextareaType;
use Chill\MainBundle\Form\Type\Select2CountryType;
@ -35,6 +36,11 @@ use Chill\PersonBundle\Form\Type\Select2MaritalStatusType;
use Symfony\Component\Form\AbstractType;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Form\Type\CommentType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TelType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
@ -62,16 +68,20 @@ class PersonType extends AbstractType
*/
protected $configAltNamesHelper;
protected TranslatableStringHelper $translatableStringHelper;
/**
*
* @param string[] $personFieldsConfiguration configuration of visibility of some fields
*/
public function __construct(
array $personFieldsConfiguration,
ConfigPersonAltNamesHelper $configAltNamesHelper
ConfigPersonAltNamesHelper $configAltNamesHelper,
TranslatableStringHelper $translatableStringHelper
) {
$this->config = $personFieldsConfiguration;
$this->configAltNamesHelper = $configAltNamesHelper;
$this->translatableStringHelper = $translatableStringHelper;
}
/**
@ -114,7 +124,19 @@ class PersonType extends AbstractType
}
if ($this->config['place_of_birth'] === 'visible') {
$builder->add('placeOfBirth', TextType::class, array('required' => false));
$builder->add('placeOfBirth', TextType::class, array(
'required' => false,
'attr' => ['style' => 'text-transform: uppercase;'],
));
$builder->get('placeOfBirth')->addModelTransformer(new CallbackTransformer(
function ($string) {
return strtoupper($string);
},
function ($string) {
return strtoupper($string);
}
));
}
if ($this->config['contact_info'] === 'visible') {
@ -150,7 +172,11 @@ class PersonType extends AbstractType
if ($this->config['email'] === 'visible') {
$builder
->add('email', EmailType::class, array('required' => false))
->add('email', EmailType::class, array('required' => false));
}
if ($this->config['acceptEmail'] === 'visible') {
$builder
->add('acceptEmail', CheckboxType::class, array('required' => false));
}
@ -173,6 +199,23 @@ class PersonType extends AbstractType
));
}
if ($this->config['civility'] === 'visible'){
$builder
->add('civility', EntityType::class, [
'label' => 'Civility',
'class' => Civility::class,
'choice_label' => function (Civility $civility): string {
return $this->translatableStringHelper->localize($civility->getName());
},
'query_builder' => function (EntityRepository $er): QueryBuilder {
return $er->createQueryBuilder('c')
->where('c.active = true');
},
'placeholder' => 'choose civility',
'required' => false
]);
}
if ($this->config['marital_status'] === 'visible'){
$builder
->add('maritalStatus', Select2MaritalStatusType::class, array(
@ -192,6 +235,7 @@ class PersonType extends AbstractType
array('attr' => array('class' => 'cf-fields'), 'group' => $options['cFGroup']))
;
}
}
/**

View File

@ -7,7 +7,6 @@ const personAcceptEmail = document.getElementById("personAcceptEmail");
const personPhoneNumber = document.getElementById("personPhoneNumber");
const personAcceptSMS = document.getElementById("personAcceptSMS");
new ShowHide({
froms: [maritalStatus],
container: [maritalStatusDate],
@ -24,21 +23,24 @@ new ShowHide({
event_name: 'change'
});
new ShowHide({
froms: [personEmail],
container: [personAcceptEmail],
test: function(froms) {
for (let f of froms.values()) {
for (let input of f.querySelectorAll('input').values()) {
if (input.value) {
return true
if (personAcceptEmail) {
new ShowHide({
froms: [personEmail],
container: [personAcceptEmail],
test: function(froms) {
for (let f of froms.values()) {
for (let input of f.querySelectorAll('input').values()) {
if (input.value) {
return true
}
}
}
}
return false;
},
event_name: 'input'
});
return false;
},
event_name: 'input'
});
}
new ShowHide({
froms: [personPhoneNumber],

View File

@ -16,3 +16,4 @@ chill_person:
country_of_birth: hidden
marital_status: hidden
spoken_languages: hidden
civility: hidden

View File

@ -37,6 +37,9 @@
<fieldset>
<legend><h2>{{ 'General information'|trans }}</h2></legend>
{%- if form.civility is defined -%}
{{ form_row(form.civility, {'label' : 'Civility'}) }}
{% endif %}
{{ form_row(form.firstName, {'label' : 'First name'}) }}
{{ form_row(form.lastName, {'label' : 'Last name'}) }}
{% if form.altNames is defined %}
@ -95,6 +98,8 @@
<div id="personEmail">
{{ form_row(form.email, {'label': 'Email'}) }}
</div>
{% endif %}
{%- if form.acceptEmail is defined -%}
<div id="personAcceptEmail">
{{ form_row(form.acceptEmail, {'label' : 'Accept emails ?'}) }}
</div>
@ -135,12 +140,11 @@
</button>
</li>
</ul>
{{ form_end(form) }}
</div>
{% endblock %}
{% block js %}
{{ encore_entry_link_tags('page_person') }}
{{ encore_entry_script_tags('page_person') }}
{% endblock %}

View File

@ -51,6 +51,15 @@ This view should receive those arguments:
<figure class="person-details">
<h2 class="chill-red">{{ 'General information'|trans }}</h2>
<dl>
{% if person.civility is not null %}
<dt>{{ 'Civility'|trans }}&nbsp;:</dt>
<dd>
{% if person.civility.name|length > 0 %}
{{ person.civility.name|first }}
{% endif %}
</dd>
{% endif %}
<dt>{{ 'First name'|trans }}&nbsp;:</dt>
<dd>{{ person.firstName }}</dd>

View File

@ -7,8 +7,9 @@ services:
Chill\PersonBundle\Form\PersonType:
arguments:
- '%chill_person.person_fields%'
- '@Chill\PersonBundle\Config\ConfigPersonAltNamesHelper'
$personFieldsConfiguration: '%chill_person.person_fields%'
$configAltNamesHelper: '@Chill\PersonBundle\Config\ConfigPersonAltNamesHelper'
$translatableStringHelper: '@Chill\MainBundle\Templating\TranslatableStringHelper'
tags:
- { name: form.type, alias: '@chill.person.form.person_creation' }

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Chill\Migrations\Person;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add Civility to Person
*/
final class Version20211108100849 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add Civility to Person';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_person_person ADD civility_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE chill_person_person ADD CONSTRAINT FK_BF210A1423D6A298 FOREIGN KEY (civility_id) REFERENCES chill_main_civility (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_BF210A1423D6A298 ON chill_person_person (civility_id)');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_person_person DROP CONSTRAINT FK_BF210A1423D6A298');
$this->addSql('DROP INDEX IDX_BF210A1423D6A298');
$this->addSql('ALTER TABLE chill_person_person DROP civility_id');
}
}

View File

@ -47,8 +47,8 @@ Phonenumber: 'Numéro de téléphone'
phonenumber: numéro de téléphone
Mobilenumber: 'Numéro de téléphone portable'
mobilenumber: numéro de téléphone portable
Accept short text message ?: Accepte les SMS?
Accept short text message: Accepte les SMS
Accept short text message ?: La personne a donné l'autorisation d'utiliser ce no de téléphone pour l'envoi de rappel par SMS
Accept short text message: La personne a donné l'autorisation d'utiliser ce no de téléphone pour l'envoi de rappel par SMS
Other phonenumber: Autre numéro de téléphone
Description: description
Add new phone: Ajouter un numéro de téléphone
@ -80,6 +80,8 @@ Married: Marié(e)
'Contact information': 'Informations de contact'
'Administrative information': Administratif
File number: Dossier n°
Civility: Civilité
choose civility: --
# dédoublonnage
Old person: Doublon