mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 14:43:49 +00:00
Merge branch 'master' into HEAD
This commit is contained in:
@@ -17,20 +17,21 @@ class LoadCivility extends Fixture implements FixtureGroupInterface
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$civilities = [
|
||||
['name' => ['fr' => "Monsieur" ]],
|
||||
['name' => ['fr' => "Madame" ]],
|
||||
['name' => ['fr' => "Docteur" ]],
|
||||
['name' => ['fr' => "Professeur" ]],
|
||||
['name' => ['fr' => "Madame la Directrice" ]],
|
||||
['name' => ['fr' => "Monsieur le Directeur" ]],
|
||||
['name' => ['fr' => "Monsieur" ], 'abbrev' => ['fr' => 'M.']],
|
||||
['name' => ['fr' => "Madame" ], 'abbrev' => ['fr' => 'Mme']],
|
||||
['name' => ['fr' => "Docteur" ], 'abbrev' => ['fr' => 'Dr']],
|
||||
['name' => ['fr' => "Professeur" ], 'abbrev' => ['fr' => 'Pr']],
|
||||
['name' => ['fr' => "Madame la Directrice" ], 'abbrev' => ['fr' => 'Mme']],
|
||||
['name' => ['fr' => "Monsieur le Directeur" ], 'abbrev' => ['fr' => 'M.']],
|
||||
['name' => ['fr' => "Madame la Maire" ]],
|
||||
['name' => ['fr' => "Monsieur le Maire" ]],
|
||||
['name' => ['fr' => "Maître" ]],
|
||||
['name' => ['fr' => "Maître" ], 'abbrev' => ['fr' => 'Me']],
|
||||
];
|
||||
|
||||
foreach ( $civilities as $val) {
|
||||
$civility = (new Civility())
|
||||
->setName($val['name'])
|
||||
->setAbbreviation($val['abbrev'] ?? [])
|
||||
->setActive(true);
|
||||
$manager->persist($civility);
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ class Address
|
||||
* @ORM\Id
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $id;
|
||||
|
||||
@@ -31,7 +31,7 @@ class Address
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=255)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $street = '';
|
||||
|
||||
@@ -39,7 +39,7 @@ class Address
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=255)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $streetNumber = '';
|
||||
|
||||
@@ -47,7 +47,7 @@ class Address
|
||||
* @var PostalCode
|
||||
*
|
||||
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode")
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $postcode;
|
||||
|
||||
@@ -55,7 +55,7 @@ class Address
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $floor;
|
||||
|
||||
@@ -63,7 +63,7 @@ class Address
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $corridor;
|
||||
|
||||
@@ -71,7 +71,7 @@ class Address
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $steps;
|
||||
|
||||
@@ -79,7 +79,7 @@ class Address
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $buildingName;
|
||||
|
||||
@@ -87,7 +87,7 @@ class Address
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $flat;
|
||||
|
||||
@@ -95,7 +95,7 @@ class Address
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $distribution;
|
||||
|
||||
@@ -103,7 +103,7 @@ class Address
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $extra;
|
||||
|
||||
@@ -114,7 +114,7 @@ class Address
|
||||
* @var \DateTime
|
||||
*
|
||||
* @ORM\Column(type="date")
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private \DateTime $validFrom;
|
||||
|
||||
@@ -125,13 +125,13 @@ class Address
|
||||
* @var \DateTime|null
|
||||
*
|
||||
* @ORM\Column(type="date", nullable=true)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private ?\DateTime $validTo = null;
|
||||
|
||||
/**
|
||||
* True if the address is a "no address", aka homeless person, ...
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
* @ORM\Column(type="boolean")
|
||||
*
|
||||
* @var bool
|
||||
@@ -144,7 +144,7 @@ class Address
|
||||
* @var Point|null
|
||||
*
|
||||
* @ORM\Column(type="point", nullable=true)
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $point;
|
||||
|
||||
@@ -154,7 +154,7 @@ class Address
|
||||
* @var ThirdParty|null
|
||||
*
|
||||
* @ORM\ManyToOne(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty")
|
||||
* @groups({"write"})
|
||||
* @Groups({"write"})
|
||||
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
|
||||
*/
|
||||
private $linkedToThirdParty;
|
||||
@@ -166,6 +166,12 @@ class Address
|
||||
*/
|
||||
private $customs = [];
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=AddressReference::class)
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private ?AddressReference $addressReference = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->validFrom = new \DateTime();
|
||||
@@ -376,6 +382,7 @@ class Address
|
||||
public static function createFromAddress(Address $original) : Address
|
||||
{
|
||||
return (new Address())
|
||||
->setAddressReference($original->getAddressReference())
|
||||
->setBuildingName($original->getBuildingName())
|
||||
->setCorridor($original->getCorridor())
|
||||
->setCustoms($original->getCustoms())
|
||||
@@ -402,6 +409,7 @@ class Address
|
||||
->setPostcode($original->getPostcode())
|
||||
->setStreet($original->getStreet())
|
||||
->setStreetNumber($original->getStreetNumber())
|
||||
->setAddressReference($original)
|
||||
;
|
||||
}
|
||||
|
||||
@@ -549,5 +557,22 @@ class Address
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AddressReference|null
|
||||
*/
|
||||
public function getAddressReference(): ?AddressReference
|
||||
{
|
||||
return $this->addressReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AddressReference|null $addressReference
|
||||
* @return Address
|
||||
*/
|
||||
public function setAddressReference(?AddressReference $addressReference = null): Address
|
||||
{
|
||||
$this->addressReference = $addressReference;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Form\Type\DataTransformer;
|
||||
|
||||
use Chill\MainBundle\Repository\AddressRepository;
|
||||
use Symfony\Component\Form\DataTransformerInterface;
|
||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||
|
||||
final class AddressToIdDataTransformer implements DataTransformerInterface
|
||||
{
|
||||
private AddressRepository $addressRepository;
|
||||
|
||||
public function __construct(AddressRepository $addressRepository)
|
||||
{
|
||||
$this->addressRepository = $addressRepository;
|
||||
}
|
||||
|
||||
public function reverseTransform($value)
|
||||
{
|
||||
if (NULL === $value || '' === $value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$address = $this->addressRepository->find($value);
|
||||
|
||||
if (NULL === $address) {
|
||||
$failure = new TransformationFailedException(sprintf("Address with id %s does not exists", $value));
|
||||
$failure
|
||||
->setInvalidMessage("The given {{ value }} is not a valid address id", [ '{{ value }}' => $value]);
|
||||
|
||||
throw $failure;
|
||||
}
|
||||
|
||||
return $address;
|
||||
}
|
||||
|
||||
public function transform($value)
|
||||
{
|
||||
if (NULL === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $value->getId();
|
||||
}
|
||||
}
|
@@ -32,7 +32,7 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType
|
||||
foreach ($this->requestStack->getCurrentRequest()->query->getIterator() as $key => $value) {
|
||||
switch($key) {
|
||||
case 'q':
|
||||
continue;
|
||||
break;
|
||||
case 'page':
|
||||
$builder->add($key, HiddenType::class, [
|
||||
'data' => 1
|
||||
|
79
src/Bundle/ChillMainBundle/Form/Type/PickAddressType.php
Normal file
79
src/Bundle/ChillMainBundle/Form/Type/PickAddressType.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Form\Type;
|
||||
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\MainBundle\Form\Type\DataTransformer\AddressToIdDataTransformer;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* Form type for picking an address.
|
||||
*
|
||||
* In the UI, this resolve to a vuejs component which will insert the created address id into the
|
||||
* hidden's value. It will also allow to edit existing addresses without changing the id.
|
||||
*
|
||||
* In every page where this component is shown, you must include the required module:
|
||||
*
|
||||
* ```twig
|
||||
* {% block js %}
|
||||
* {{ encore_entry_script_tags('mod_input_address') }}
|
||||
* {% endblock %}
|
||||
*
|
||||
* {% block css %}
|
||||
* {{ encore_entry_link_tags('mod_input_address') }}
|
||||
* {% endblock %}
|
||||
* ```
|
||||
*/
|
||||
final class PickAddressType extends AbstractType
|
||||
{
|
||||
private AddressToIdDataTransformer $addressToIdDataTransformer;
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(
|
||||
AddressToIdDataTransformer $addressToIdDataTransformer,
|
||||
TranslatorInterface $translator
|
||||
) {
|
||||
$this->addressToIdDataTransformer = $addressToIdDataTransformer;
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder->addModelTransformer($this->addressToIdDataTransformer);
|
||||
}
|
||||
|
||||
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||
{
|
||||
$view->vars['uniqid'] = $view->vars['attr']['data-input-address'] =\uniqid('input_address_');
|
||||
$view->vars['attr']['data-use-valid-from'] = (int) $options['use_valid_from'];
|
||||
$view->vars['attr']['data-use-valid-to'] = (int) $options['use_valid_to'];
|
||||
$view->vars['attr']['data-button-text-create'] = $this->translator->trans($options['button_text_create']);
|
||||
$view->vars['attr']['data-button-text-update'] = $this->translator->trans($options['button_text_update']);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'class' => Address::class,
|
||||
'use_valid_to' => false,
|
||||
'use_valid_from' => false,
|
||||
'button_text_create' => 'Create an address',
|
||||
'button_text_update' => 'Update address',
|
||||
|
||||
// reset default from hidden type
|
||||
'required' => true,
|
||||
'error_bubbling' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
{
|
||||
return HiddenType::class;
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
|
||||
const _fetchAction = (page, uri, params) => {
|
||||
const item_per_page = 50;
|
||||
if (params === undefined) {
|
||||
params = {};
|
||||
}
|
||||
let url = uri + '?' + new URLSearchParams({ item_per_page, page, ...params });
|
||||
|
||||
return fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=utf-8'
|
||||
},
|
||||
}).then(response => {
|
||||
if (response.ok) { return response.json(); }
|
||||
throw Error({ m: response.statusText });
|
||||
});
|
||||
};
|
||||
|
||||
const fetchResults = async (uri, params) => {
|
||||
let promises = [],
|
||||
page = 1;
|
||||
let firstData = await _fetchAction(page, uri, params);
|
||||
|
||||
promises.push(Promise.resolve(firstData.results));
|
||||
|
||||
if (firstData.pagination.more) {
|
||||
do {
|
||||
page = ++page;
|
||||
promises.push(_fetchAction(page, uri, params).then(r => Promise.resolve(r.results)));
|
||||
} while (page * firstData.pagination.items_per_page < firstData.count)
|
||||
}
|
||||
|
||||
return Promise.all(promises).then(values => values.flat());
|
||||
};
|
||||
|
||||
export {
|
||||
fetchResults
|
||||
};
|
@@ -1,15 +1,7 @@
|
||||
import { fetchResults } from 'ChillMainAssets/lib/api/download.js';
|
||||
|
||||
const fetchScopes = () => {
|
||||
return window.fetch('/api/1.0/main/scope.json').then(response => {
|
||||
if (response.ok) {
|
||||
return response.json();
|
||||
}
|
||||
}).then(data => {
|
||||
//console.log(data);
|
||||
return new Promise((resolve, reject) => {
|
||||
//console.log(data);
|
||||
resolve(data.results);
|
||||
});
|
||||
});
|
||||
return fetchResults('/api/1.0/main/scope.json');
|
||||
};
|
||||
|
||||
export {
|
||||
|
@@ -17,7 +17,8 @@ export default {
|
||||
components: {
|
||||
AddAddress
|
||||
},
|
||||
props: ['addAddress'],
|
||||
props: ['addAddress', 'callback'],
|
||||
emits: ['addressEdited', 'addressCreated'],
|
||||
computed: {
|
||||
context() {
|
||||
return this.addAddress.context;
|
||||
@@ -46,6 +47,7 @@ export default {
|
||||
|
||||
// address is already linked, just finish !
|
||||
this.$refs.addAddress.afterLastPaneAction({});
|
||||
this.$emit('addressEdited', payload);
|
||||
|
||||
// New created address
|
||||
} else {
|
||||
@@ -57,6 +59,8 @@ export default {
|
||||
* Post new created address to targetEntity
|
||||
*/
|
||||
postAddressTo(payload) {
|
||||
this.$emit('addressCreated', payload);
|
||||
|
||||
console.log('postAddress', payload.addressId, 'To', payload.target, payload.targetId);
|
||||
switch (payload.target) {
|
||||
case 'household':
|
||||
|
@@ -267,6 +267,9 @@ export default {
|
||||
title: { create: 'add_an_address_title', edit: 'edit_address' },
|
||||
openPanesInModal: true,
|
||||
stickyActions: false,
|
||||
// show a message when no address.
|
||||
// if set to undefined, the value will be equivalent to false if stickyActions is false, true otherwise.
|
||||
showMessageWhenNoAddress: undefined,
|
||||
useDate: {
|
||||
validFrom: false,
|
||||
validTo: false
|
||||
@@ -586,6 +589,14 @@ export default {
|
||||
'point': this.entity.selected.address.point.coordinates
|
||||
});
|
||||
}
|
||||
|
||||
// add the address reference, if any
|
||||
if (this.entity.selected.address.addressReference !== undefined) {
|
||||
newAddress = Object.assign(newAddress, {
|
||||
'addressReference': this.entity.selected.address.addressReference
|
||||
});
|
||||
}
|
||||
|
||||
if (this.validFrom) {
|
||||
console.log('add validFrom in fetch body', this.entity.selected.valid.from);
|
||||
newAddress = Object.assign(newAddress, {
|
||||
@@ -606,7 +617,7 @@ export default {
|
||||
let newPostcode = this.entity.selected.postcode;
|
||||
newPostcode = Object.assign(newPostcode, {
|
||||
'country': {'id': this.entity.selected.country.id },
|
||||
});
|
||||
});//TODO why not assign postcodeBody here = Object.assign(postcodeBody, {'origin': 3}); ?
|
||||
console.log('writeNew postcode is true! newPostcode: ', newPostcode);
|
||||
newAddress = Object.assign(newAddress, {
|
||||
'newPostcode': newPostcode
|
||||
@@ -638,9 +649,7 @@ export default {
|
||||
if ('newPostcode' in payload) {
|
||||
|
||||
let postcodeBody = payload.newPostcode;
|
||||
if (this.context.target.name === 'person') { // !!! maintain here ?
|
||||
postcodeBody = Object.assign(postcodeBody, {'origin': 3});
|
||||
}
|
||||
postcodeBody = Object.assign(postcodeBody, {'origin': 3});
|
||||
console.log('juste before post new postcode', postcodeBody);
|
||||
return postPostalCode(postcodeBody)
|
||||
.then(postalCode => {
|
||||
@@ -730,6 +739,9 @@ export default {
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Called when the event pick-address is emitted, which is, by the way,
|
||||
* called when an address suggestion is picked.
|
||||
*
|
||||
* @param address the address selected
|
||||
*/
|
||||
|
@@ -95,6 +95,9 @@ export default {
|
||||
},
|
||||
selectAddress(value) {
|
||||
this.entity.selected.address = value;
|
||||
this.entity.selected.address.addressReference = {
|
||||
id: value.id
|
||||
};
|
||||
this.entity.selected.address.street = value.street;
|
||||
this.entity.selected.address.streetNumber = value.streetNumber;
|
||||
this.entity.selected.writeNew.address = false;
|
||||
|
@@ -50,7 +50,7 @@ import VueMultiselect from 'vue-multiselect';
|
||||
export default {
|
||||
name: 'CitySelection',
|
||||
components: { VueMultiselect },
|
||||
props: ['entity', 'focusOnAddress'],
|
||||
props: ['entity', 'focusOnAddress', 'updateMapCenter'],
|
||||
emits: ['getReferenceAddresses'],
|
||||
data() {
|
||||
return {
|
||||
@@ -95,6 +95,7 @@ export default {
|
||||
return (value.code && value.name) ? `${value.code}-${value.name}` : '';
|
||||
},
|
||||
selectCity(value) {
|
||||
console.log(value)
|
||||
this.entity.selected.city = value;
|
||||
this.entity.selected.postcode.name = value.name;
|
||||
this.entity.selected.postcode.code = value.code;
|
||||
@@ -102,6 +103,7 @@ export default {
|
||||
console.log('writeNew.postcode false, in selectCity');
|
||||
this.$emit('getReferenceAddresses', value);
|
||||
this.focusOnAddress();
|
||||
this.updateMapCenter(value.center);
|
||||
},
|
||||
listenInputSearch(query) {
|
||||
//console.log('listenInputSearch', query, this.isCitySelectorOpen);
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<city-selection
|
||||
v-bind:entity="entity"
|
||||
v-bind:focusOnAddress="focusOnAddress"
|
||||
v-bind:updateMapCenter="updateMapCenter"
|
||||
@getReferenceAddresses="$emit('getReferenceAddresses', selected.city)">
|
||||
</city-selection>
|
||||
|
||||
@@ -135,7 +136,7 @@ export default {
|
||||
}
|
||||
},
|
||||
updateMapCenter(point) {
|
||||
//console.log('point', point);
|
||||
console.log('point', point);
|
||||
this.addressMap.center[0] = point.coordinates[1]; // TODO use reverse()
|
||||
this.addressMap.center[1] = point.coordinates[0];
|
||||
this.$refs.addressMap.update(); // cast child methods
|
||||
|
@@ -15,7 +15,7 @@
|
||||
<span v-if="forceRedirect">{{ $t('wait_redirection') }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="noAddressWithStickyActions" class="mt-5">
|
||||
<div v-if="showMessageWhenNoAddress" class="mt-5">
|
||||
<p class="chill-no-data-statement">
|
||||
{{ $t('not_yet_address') }}
|
||||
</p>
|
||||
@@ -50,8 +50,8 @@ export default {
|
||||
},
|
||||
props: [
|
||||
'context',
|
||||
'options',
|
||||
'defaultz',
|
||||
'options',
|
||||
'flag',
|
||||
'entity',
|
||||
'errorMsg',
|
||||
@@ -91,7 +91,11 @@ export default {
|
||||
forceRedirect() {
|
||||
return (!(this.context.backUrl === null || typeof this.context.backUrl === 'undefined'));
|
||||
},
|
||||
noAddressWithStickyActions() {
|
||||
showMessageWhenNoAddress() {
|
||||
let showMessageWhenNoAddress = this.options.showMessageWhenNoAddress === undefined ? this.defaultz.showMessageWhenNoAddress : this.options.showMessageWhenNoAddress;
|
||||
if (showMessageWhenNoAddress === true || showMessageWhenNoAddress === false) {
|
||||
return !this.context.edit && !this.address.id && showMessageWhenNoAddress;
|
||||
}
|
||||
return !this.context.edit && !this.address.id && this.options.stickyActions;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,86 @@
|
||||
import {createApp} from 'vue';
|
||||
import {_createI18n} from 'ChillMainAssets/vuejs/_js/i18n';
|
||||
import {addressMessages} from './i18n';
|
||||
import App from './App.vue';
|
||||
|
||||
const i18n = _createI18n(addressMessages);
|
||||
|
||||
let inputs = document.querySelectorAll('input[type="hidden"][data-input-address]');
|
||||
|
||||
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
|
||||
;
|
||||
|
||||
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,
|
||||
},
|
||||
size: null,
|
||||
displayText: true
|
||||
},
|
||||
|
||||
/// 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 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
|
||||
},
|
||||
|
||||
/// Don't display show renderbox Address: showPane display only a button
|
||||
onlyButton: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
associateToInput(payload) {
|
||||
el.value = payload.addressId;
|
||||
}
|
||||
}
|
||||
})
|
||||
.use(i18n)
|
||||
.component('app', App)
|
||||
.mount(container);
|
||||
});
|
@@ -166,6 +166,7 @@
|
||||
<li class="entry" data-collection-is-persisted="1">
|
||||
<div>
|
||||
{{ form_widget(entry) }}
|
||||
{{ form_errors(entry) }}
|
||||
</div>
|
||||
</li>
|
||||
{% else %}
|
||||
|
@@ -27,7 +27,7 @@ class SearchUserApiProvider implements SearchApiInterface
|
||||
->setSelectPertinence("GREATEST(SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical),
|
||||
SIMILARITY(LOWER(UNACCENT(?)), u.emailcanonical))", [ $pattern, $pattern ])
|
||||
->setFromClause("users AS u")
|
||||
->setWhereClause("SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical) > 0.15
|
||||
->setWhereClauses("SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical) > 0.15
|
||||
OR
|
||||
SIMILARITY(LOWER(UNACCENT(?)), u.emailcanonical) > 0.15
|
||||
", [ $pattern, $pattern ]);
|
||||
|
@@ -12,8 +12,8 @@ class SearchApiQuery
|
||||
private array $pertinenceParams = [];
|
||||
private ?string $fromClause = null;
|
||||
private array $fromClauseParams = [];
|
||||
private ?string $whereClause = null;
|
||||
private array $whereClauseParams = [];
|
||||
private array $whereClauses = [];
|
||||
private array $whereClausesParams = [];
|
||||
|
||||
public function setSelectKey(string $selectKey, array $params = []): self
|
||||
{
|
||||
@@ -47,16 +47,39 @@ class SearchApiQuery
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setWhereClause(string $whereClause, array $params = []): self
|
||||
/**
|
||||
* Set the where clause and replace all existing ones.
|
||||
*
|
||||
*/
|
||||
public function setWhereClauses(string $whereClause, array $params = []): self
|
||||
{
|
||||
$this->whereClause = $whereClause;
|
||||
$this->whereClauseParams = $params;
|
||||
$this->whereClauses = [$whereClause];
|
||||
$this->whereClausesParams = [$params];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a where clause.
|
||||
*
|
||||
* This will add to previous where clauses with and `AND` join
|
||||
*
|
||||
* @param string $whereClause
|
||||
* @param array $params
|
||||
* @return $this
|
||||
*/
|
||||
public function andWhereClause(string $whereClause, array $params = []): self
|
||||
{
|
||||
$this->whereClauses[] = $whereClause;
|
||||
$this->whereClausesParams[] = $params;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildQuery(): string
|
||||
{
|
||||
$where = \implode(' AND ', $this->whereClauses);
|
||||
|
||||
return \strtr("SELECT
|
||||
'{key}' AS key,
|
||||
{metadata} AS metadata,
|
||||
@@ -68,7 +91,7 @@ class SearchApiQuery
|
||||
'{metadata}' => $this->jsonbMetadata,
|
||||
'{pertinence}' => $this->pertinence,
|
||||
'{from}' => $this->fromClause,
|
||||
'{where}' => $this->whereClause,
|
||||
'{where}' => $where,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -79,7 +102,7 @@ class SearchApiQuery
|
||||
$this->jsonbMetadataParams,
|
||||
$this->pertinenceParams,
|
||||
$this->fromClauseParams,
|
||||
$this->whereClauseParams,
|
||||
\array_merge([], ...$this->whereClausesParams),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@
|
||||
namespace Chill\MainBundle\Serializer\Normalizer;
|
||||
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
@@ -33,6 +34,9 @@ class AddressNormalizer implements NormalizerAwareInterface, NormalizerInterface
|
||||
$data['extra'] = $address->getExtra();
|
||||
$data['validFrom'] = $address->getValidFrom();
|
||||
$data['validTo'] = $address->getValidTo();
|
||||
$data['addressReference'] = $this->normalizer->normalize($address->getAddressReference(), $format, [
|
||||
AbstractNormalizer::GROUPS => ['read']
|
||||
]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Search;
|
||||
|
||||
use Chill\MainBundle\Search\SearchApiQuery;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class SearchApiQueryTest extends TestCase
|
||||
{
|
||||
public function testMultipleWhereClauses()
|
||||
{
|
||||
$q = new SearchApiQuery();
|
||||
$q->setSelectJsonbMetadata('boum')
|
||||
->setSelectKey('bim')
|
||||
->setSelectPertinence('1')
|
||||
->setFromClause('badaboum')
|
||||
->andWhereClause('foo', [ 'alpha' ])
|
||||
->andWhereClause('bar', [ 'beta' ])
|
||||
;
|
||||
|
||||
$query = $q->buildQuery();
|
||||
|
||||
$this->assertStringContainsString('foo AND bar', $query);
|
||||
$this->assertEquals(['alpha', 'beta'], $q->buildParameters());
|
||||
}
|
||||
|
||||
public function testWithoutWhereClause()
|
||||
{
|
||||
$q = new SearchApiQuery();
|
||||
$q->setSelectJsonbMetadata('boum')
|
||||
->setSelectKey('bim')
|
||||
->setSelectPertinence('1')
|
||||
->setFromClause('badaboum')
|
||||
;
|
||||
|
||||
$this->assertTrue(\is_string($q->buildQuery()));
|
||||
$this->assertEquals([], $q->buildParameters());
|
||||
}
|
||||
|
||||
}
|
@@ -60,6 +60,7 @@ module.exports = function(encore, entries)
|
||||
encore.addEntry('mod_ckeditor5', __dirname + '/Resources/public/module/ckeditor5/index.js');
|
||||
encore.addEntry('mod_disablebuttons', __dirname + '/Resources/public/module/disable-buttons/index.js');
|
||||
|
||||
encore.addEntry('mod_input_address', __dirname + '/Resources/public/vuejs/Address/mod_input_address_index.js');
|
||||
// Vue entrypoints
|
||||
encore.addEntry('vue_address', __dirname + '/Resources/public/vuejs/Address/index.js');
|
||||
encore.addEntry('vue_onthefly', __dirname + '/Resources/public/vuejs/OnTheFly/index.js');
|
||||
|
@@ -1,4 +1,5 @@
|
||||
services:
|
||||
|
||||
chill.main.form.type.translatable.string:
|
||||
class: Chill\MainBundle\Form\Type\TranslatableStringFormType
|
||||
arguments:
|
||||
@@ -128,3 +129,11 @@ services:
|
||||
tags:
|
||||
- { name: form.type }
|
||||
|
||||
|
||||
Chill\MainBundle\Form\Type\PickAddressType:
|
||||
autoconfigure: true
|
||||
autowire: true
|
||||
|
||||
Chill\MainBundle\Form\DataTransform\AddressToIdDataTransformer:
|
||||
autoconfigure: true
|
||||
autowire: true
|
||||
|
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Main;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Add a link between address and address reference
|
||||
*/
|
||||
final class Version20210929192242 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add a link between address and address reference';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_main_address ADD addressReference_id INT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE chill_main_address ADD CONSTRAINT FK_165051F647069464 FOREIGN KEY (addressReference_id) REFERENCES chill_main_address_reference (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX IDX_165051F647069464 ON chill_main_address (addressReference_id)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_main_address DROP addressReference_id');
|
||||
}
|
||||
}
|
@@ -84,6 +84,8 @@ address more:
|
||||
extra: ""
|
||||
distribution: cedex
|
||||
Create a new address: Créer une nouvelle adresse
|
||||
Create an address: Créer une adresse
|
||||
Update address: Modifier l'adresse
|
||||
|
||||
#serach
|
||||
Your search is empty. Please provide search terms.: La recherche est vide. Merci de fournir des termes de recherche.
|
||||
@@ -127,7 +129,7 @@ New center: Nouveau centre
|
||||
Center: Centre
|
||||
|
||||
#admin section for permissions group
|
||||
Permissions group list: Liste des groupes de permissions
|
||||
Permissions group list: Groupes de permissions
|
||||
Create a new permissions group: Créer un nouveau groupe de permissions
|
||||
Permission group "%name%": Groupe de permissions "%name%"
|
||||
Grant those permissions: Attribue ces permissions
|
||||
@@ -144,7 +146,6 @@ The role '%role%' has been removed: Le rôle "%role%" a été enlevé de ce grou
|
||||
The role '%role%' on circle '%scope%' has been removed: Le rôle "%role%" sur le cercle "%scope%" a été enlevé de ce groupe de permission
|
||||
|
||||
#admin section for users
|
||||
user list: Liste des utilisateurs
|
||||
User edit: Modification d'un utilisateur
|
||||
User'status: Statut de l'utilisateur
|
||||
Disabled, the user is not allowed to login: Désactivé, l'utilisateur n'est pas autorisé à se connecter
|
||||
@@ -167,8 +168,12 @@ Back to the user edition: Retour au formulaire d'édition
|
||||
Password successfully updated!: Mot de passe mis à jour
|
||||
Flags: Drapeaux
|
||||
|
||||
# admin section for users jobs
|
||||
User jobs: Métiers
|
||||
|
||||
|
||||
#admin section for circles (old: scopes)
|
||||
List circles: Liste des cercles
|
||||
List circles: Cercles
|
||||
New circle: Nouveau cercle
|
||||
Circle: Cercle
|
||||
Circle edit: Modification du cercle
|
||||
@@ -279,6 +284,17 @@ crud:
|
||||
success: Les données ont été enregistrées
|
||||
view:
|
||||
link_duplicate: Dupliquer
|
||||
admin_user:
|
||||
index:
|
||||
title: Utilisateurs
|
||||
add_new: Créer
|
||||
admin_user_job:
|
||||
index:
|
||||
title: Métiers
|
||||
add_new: Créer
|
||||
title_new: Nouveau métier
|
||||
title_edit: Modifier un métier
|
||||
|
||||
No entities: Aucun élément
|
||||
|
||||
CHILL_FOO_SEE: Voir un élément
|
||||
|
Reference in New Issue
Block a user