mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'feature/form-move-household-with-checkboxes'
This commit is contained in:
commit
d8444455c0
18
CHANGELOG.md
Normal file
18
CHANGELOG.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to
|
||||
|
||||
* [Semantic Versioning](https://semver.org/spec/v2.0.0.html) for stable releases;
|
||||
* date versioning for test releases
|
||||
|
||||
## Unreleased
|
||||
|
||||
* [Household editor][UI] Update how household suggestion and addresses are picked;
|
||||
* [AddAddress] Handle address suggestion;
|
||||
|
||||
## Test release yyyy-mm-dd
|
||||
|
||||
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
|
||||
class AddressApiController extends ApiController
|
||||
{
|
||||
/**
|
||||
* Duplicate an existing address
|
||||
*
|
||||
* @Route("/api/1.0/main/address/{id}/duplicate.json", name="chill_api_main_address_duplicate",
|
||||
* methods={"POST"})
|
||||
*
|
||||
* @param Address $address
|
||||
*/
|
||||
public function duplicate(Address $address): JsonResponse
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_USER');
|
||||
$new = Address::createFromAddress($address);
|
||||
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
$em->persist($new);
|
||||
$em->flush();
|
||||
|
||||
return $this->json($new, Response::HTTP_OK, [], [
|
||||
AbstractNormalizer::GROUPS => ['read']
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
|
||||
namespace Chill\MainBundle\DependencyInjection;
|
||||
|
||||
use Chill\MainBundle\Controller\AddressApiController;
|
||||
use Chill\MainBundle\Controller\UserController;
|
||||
use Chill\MainBundle\Doctrine\DQL\STContains;
|
||||
use Chill\MainBundle\Doctrine\DQL\StrictWordSimilarityOPS;
|
||||
@ -319,6 +320,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
|
||||
'apis' => [
|
||||
[
|
||||
'class' => \Chill\MainBundle\Entity\Address::class,
|
||||
'controller' => AddressApiController::class,
|
||||
'name' => 'address',
|
||||
'base_path' => '/api/1.0/main/address',
|
||||
'base_role' => 'ROLE_USER',
|
||||
|
@ -376,10 +376,22 @@ class Address
|
||||
public static function createFromAddress(Address $original) : Address
|
||||
{
|
||||
return (new Address())
|
||||
->setBuildingName($original->getBuildingName())
|
||||
->setCorridor($original->getCorridor())
|
||||
->setCustoms($original->getCustoms())
|
||||
->setDistribution($original->getDistribution())
|
||||
->setExtra($original->getExtra())
|
||||
->setFlat($original->getFlat())
|
||||
->setFloor($original->getFloor())
|
||||
->setIsNoAddress($original->getIsNoAddress())
|
||||
->setLinkedToThirdParty($original->getLinkedToThirdParty())
|
||||
->setPoint($original->getPoint())
|
||||
->setPostcode($original->getPostcode())
|
||||
->setStreetAddress1($original->getStreetAddress1())
|
||||
->setStreetAddress2($original->getStreetAddress2())
|
||||
->setSteps($original->getSteps())
|
||||
->setStreet($original->getStreet())
|
||||
->setStreetNumber($original->getStreetNumber())
|
||||
->setValidFrom($original->getValidFrom())
|
||||
->setValidTo($original->getValidTo())
|
||||
;
|
||||
}
|
||||
|
||||
@ -506,7 +518,7 @@ class Address
|
||||
return $this->validTo;
|
||||
}
|
||||
|
||||
public function setValidTo(\DateTimeInterface $validTo): self
|
||||
public function setValidTo(?\DateTimeInterface $validTo = null): self
|
||||
{
|
||||
$this->validTo = $validTo;
|
||||
|
||||
|
@ -7,6 +7,7 @@ namespace Chill\MainBundle\Repository;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
final class AddressRepository implements ObjectRepository
|
||||
@ -47,4 +48,9 @@ final class AddressRepository implements ObjectRepository
|
||||
public function getClassName() {
|
||||
return Address::class;
|
||||
}
|
||||
|
||||
public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder
|
||||
{
|
||||
return $this->repository->createQueryBuilder($alias, $indexBy);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/**
|
||||
* Endpoint chill_api_single_country__index
|
||||
* method GET, get Country Object
|
||||
* @returns {Promise} a promise containing all Country object
|
||||
@ -14,7 +14,7 @@ const fetchCountries = () => {
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* Endpoint chill_api_single_postal_code__index
|
||||
* method GET, get Country Object
|
||||
* @returns {Promise} a promise containing all Postal Code objects filtered with country
|
||||
@ -29,7 +29,7 @@ const fetchCities = (country) => {
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* Endpoint chill_api_single_address_reference__index
|
||||
* method GET, get AddressReference Object
|
||||
* @returns {Promise} a promise containing all AddressReference objects filtered with postal code
|
||||
@ -44,7 +44,7 @@ const fetchReferenceAddresses = (postalCode) => {
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* Endpoint chill_api_single_address_reference__index
|
||||
* method GET, get AddressReference Object
|
||||
* @returns {Promise} a promise containing all AddressReference objects filtered with postal code
|
||||
@ -60,7 +60,7 @@ const fetchAddresses = () => {
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* Endpoint chill_api_single_address__entity__create
|
||||
* method POST, post Address Object
|
||||
* @returns {Promise}
|
||||
@ -81,8 +81,28 @@ const postAddress = (address) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param address
|
||||
* @returns {Promise<Response>}
|
||||
*/
|
||||
const duplicateAddress = (address) => {
|
||||
const url = `/api/1.0/main/address/${address.address_id}/duplicate.json`;
|
||||
return fetch(url, {
|
||||
'method': 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=utf-8'
|
||||
},
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
return response.json();
|
||||
}
|
||||
throw Error('Error with request resource response');
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
/**
|
||||
* Endpoint chill_api_single_address__entity__create
|
||||
* method PATCH, patch Address Instance
|
||||
*
|
||||
@ -142,6 +162,7 @@ const getAddress = (id) => {
|
||||
};
|
||||
|
||||
export {
|
||||
duplicateAddress,
|
||||
fetchCountries,
|
||||
fetchCities,
|
||||
fetchReferenceAddresses,
|
||||
|
@ -34,6 +34,7 @@
|
||||
v-bind:defaultz="this.defaultz"
|
||||
v-bind:entity="this.entity"
|
||||
v-bind:flag="this.flag"
|
||||
@pick-address="this.pickAddress"
|
||||
ref="suggestAddress">
|
||||
</suggest-pane>
|
||||
</template>
|
||||
@ -55,6 +56,7 @@
|
||||
v-bind:entity="this.entity"
|
||||
v-bind:flag="this.flag"
|
||||
v-bind:insideModal="false"
|
||||
@pick-address="this.pickAddress"
|
||||
ref="suggestAddress">
|
||||
|
||||
<template v-slot:before v-if="!bypassFirstStep">
|
||||
@ -217,7 +219,16 @@
|
||||
|
||||
<script>
|
||||
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
|
||||
import { getAddress, fetchCountries, fetchCities, fetchReferenceAddresses, patchAddress, postAddress, postPostalCode } from '../api';
|
||||
import {
|
||||
duplicateAddress,
|
||||
fetchCountries,
|
||||
fetchCities,
|
||||
fetchReferenceAddresses,
|
||||
getAddress,
|
||||
patchAddress,
|
||||
postAddress,
|
||||
postPostalCode,
|
||||
} from '../api';
|
||||
import { postAddressToPerson, postAddressToHousehold } from "ChillPersonAssets/vuejs/_api/AddAddress.js";
|
||||
import ShowPane from './ShowPane.vue';
|
||||
import SuggestPane from './SuggestPane.vue';
|
||||
@ -234,6 +245,9 @@ export default {
|
||||
EditPane,
|
||||
DatePane
|
||||
},
|
||||
emits: {
|
||||
pickAddress: null
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
flag: {
|
||||
@ -311,7 +325,10 @@ export default {
|
||||
return (this.validFrom || this.validTo) ? true : false;
|
||||
},
|
||||
hasSuggestions() {
|
||||
// TODO
|
||||
console.log(this.context.suggestions);
|
||||
if (typeof(this.context.suggestions) !== 'undefined') {
|
||||
return this.context.suggestions.length > 0;
|
||||
}
|
||||
//return addressSuggestions.length > 0
|
||||
return false;
|
||||
},
|
||||
@ -647,9 +664,12 @@ export default {
|
||||
this.flag.loading = false;
|
||||
this.flag.success = true;
|
||||
resolve({
|
||||
address,
|
||||
targetOrigin: this.context.target,
|
||||
// for "legacy" use:
|
||||
target: this.context.target.name,
|
||||
targetId: this.context.target.id,
|
||||
addressId: this.entity.address.address_id
|
||||
addressId: this.entity.address.address_id,
|
||||
}
|
||||
);
|
||||
}))
|
||||
@ -695,6 +715,9 @@ export default {
|
||||
this.flag.loading = false;
|
||||
this.flag.success = true;
|
||||
return resolve({
|
||||
address,
|
||||
targetOrigin: this.context.target,
|
||||
// for "legacy" use:
|
||||
target: this.context.target.name,
|
||||
targetId: this.context.target.id,
|
||||
addressId: this.entity.address.address_id
|
||||
@ -707,6 +730,29 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param address the address selected
|
||||
*/
|
||||
pickAddress(address) {
|
||||
console.log('pickAddress', address);
|
||||
duplicateAddress(address).then(newAddress => {
|
||||
this.entity.address = newAddress;
|
||||
this.flag.loading = false;
|
||||
this.flag.success = true;
|
||||
let payload = {
|
||||
address: newAddress,
|
||||
targetOrigin: this.context.target,
|
||||
// for "legacy" use:
|
||||
target: this.context.target.name,
|
||||
targetId: this.context.target.id,
|
||||
addressId: this.entity.address.address_id
|
||||
};
|
||||
this.addressChangedCallback(payload);
|
||||
this.closeSuggestPane();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Method just add closing pane to the callback method
|
||||
* (get out step1 show pane, submit button)
|
||||
|
@ -10,13 +10,14 @@
|
||||
<h4 class="h3">{{ $t('address_suggestions') }}</h4>
|
||||
|
||||
<div class="flex-table AddressSuggestionList">
|
||||
<div class="item-bloc">
|
||||
<div v-for="a in context.suggestions" class="item-bloc">
|
||||
<div class="float-button bottom">
|
||||
<div class="box">
|
||||
<div class="action">
|
||||
<!-- QUESTION normal que ça vienne avant l'adresse ? pourquoi pas après avoir affiché le address-render-box ? -->
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button class="btn btn-sm btn-choose">
|
||||
<button class="btn btn-sm btn-choose" @click="this.pickAddress(a)">
|
||||
{{ $t('use_this_address') }}
|
||||
</button>
|
||||
</li>
|
||||
@ -25,9 +26,7 @@
|
||||
<ul class="list-content fa-ul">
|
||||
<li>
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
<!--
|
||||
<address-render-box></address-render-box>
|
||||
-->
|
||||
<address-render-box :address="a"></address-render-box>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -68,9 +67,14 @@ export default {
|
||||
'flag',
|
||||
'entity',
|
||||
'errorMsg',
|
||||
'insideModal'
|
||||
'insideModal',
|
||||
],
|
||||
computed: {},
|
||||
methods: {}
|
||||
methods: {
|
||||
pickAddress(address) {
|
||||
console.log('pickAddress in suggest pane', address);
|
||||
this.$emit('pickAddress', address);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -17,32 +17,31 @@
|
||||
*/
|
||||
namespace Chill\MainBundle\Test;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
/**
|
||||
* Prepare a client authenticated with a user
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* Prepare a client authenticated with a user
|
||||
*/
|
||||
trait PrepareClientTrait
|
||||
{
|
||||
/**
|
||||
* Create a new client with authentication information.
|
||||
*
|
||||
*
|
||||
* @param string $username the username (default 'center a_social')
|
||||
* @param string $password the password (default 'password')
|
||||
* @return \Symfony\Component\BrowserKit\Client
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function getClientAuthenticated(
|
||||
$username = 'center a_social',
|
||||
$username = 'center a_social',
|
||||
$password = 'password'
|
||||
) {
|
||||
): KernelBrowser {
|
||||
if (!$this instanceof WebTestCase) {
|
||||
throw new \LogicException(sprintf("The current class does not "
|
||||
. "implements %s", WebTestCase::class));
|
||||
}
|
||||
|
||||
|
||||
return static::createClient(array(), array(
|
||||
'PHP_AUTH_USER' => $username,
|
||||
'PHP_AUTH_PW' => $password,
|
||||
|
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Controller;
|
||||
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\MainBundle\Repository\AddressRepository;
|
||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
|
||||
|
||||
class AddressControllerTest extends \Symfony\Bundle\FrameworkBundle\Test\WebTestCase
|
||||
{
|
||||
private KernelBrowser $client;
|
||||
|
||||
use PrepareClientTrait;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
self::bootKernel();
|
||||
$this->client = $this->getClientAuthenticated();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider generateAddressIds
|
||||
* @param int $addressId
|
||||
*/
|
||||
public function testDuplicate(int $addressId)
|
||||
{
|
||||
$this->client->request('POST', "/api/1.0/main/address/$addressId/duplicate.json");
|
||||
|
||||
$this->assertResponseIsSuccessful('test that duplicate is successful');
|
||||
}
|
||||
|
||||
public function generateAddressIds()
|
||||
{
|
||||
self::bootKernel();
|
||||
$em = self::$container->get(EntityManagerInterface::class);
|
||||
|
||||
$qb = $em->createQueryBuilder();
|
||||
$addresses = $qb->select('a')->from(Address::class, 'a')
|
||||
->setMaxResults(2)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
|
||||
foreach ($addresses as $a) {
|
||||
yield [ $a->getId() ];
|
||||
}
|
||||
}
|
||||
}
|
@ -293,6 +293,32 @@ paths:
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
|
||||
/1.0/main/address/{id}/duplicate.json:
|
||||
post:
|
||||
tags:
|
||||
- address
|
||||
summary: Duplicate an existing address
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: The address id that will be duplicated
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 1
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Address'
|
||||
404:
|
||||
description: "not found"
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
|
||||
/1.0/main/address-reference.json:
|
||||
get:
|
||||
tags:
|
||||
|
@ -229,7 +229,7 @@ class Household
|
||||
))
|
||||
->andWhere($expr->orX(
|
||||
$expr->isNull('endDate'),
|
||||
$expr->gte('endDate', $date)
|
||||
$expr->gt('endDate', $date)
|
||||
));
|
||||
|
||||
return $criteria;
|
||||
@ -306,7 +306,7 @@ class Household
|
||||
)
|
||||
->orWhere(
|
||||
$expr->andX(
|
||||
$expr->lt('endDate', $date),
|
||||
$expr->lte('endDate', $date),
|
||||
$expr->neq('endDate', null)
|
||||
)
|
||||
);
|
||||
|
@ -2,171 +2,126 @@
|
||||
|
||||
<h2 class="mt-4">{{ $t('household_members_editor.household_part') }}</h2>
|
||||
|
||||
<div v-if="hasHousehold">
|
||||
<div v-if="mode == null">
|
||||
|
||||
<div class="flex-table">
|
||||
<div class="item-bloc">
|
||||
<household-render-box :household="household" :isAddressMultiline="true"></household-render-box>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-info">{{ $t('household_members_editor.household.no_household_choose_one') }}</div>
|
||||
|
||||
<div v-if="isHouseholdNew && !hasHouseholdAddress">
|
||||
|
||||
<div v-if="hasAddressSuggestion" class="householdAddressSuggestion my-5">
|
||||
<h4 class="mb-3">
|
||||
{{ $t('household_members_editor.household.where_live_the_household') }}
|
||||
</h4>
|
||||
<div class="accordion" id="addressSuggestions">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="heading_address_suggestions">
|
||||
<button v-if="!showAddressSuggestion"
|
||||
class="accordion-button collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
aria-expanded="false"
|
||||
@click="toggleAddressSuggestion">
|
||||
{{ $tc('household_members_editor.show_household_suggestion', countAddressSuggestion) }}
|
||||
</button>
|
||||
<button v-if="showAddressSuggestion"
|
||||
class="accordion-button"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
aria-expanded="true"
|
||||
@click="toggleAddressSuggestion">
|
||||
{{ $t('household_members_editor.hide_household_suggestion') }}
|
||||
</button>
|
||||
</h2>
|
||||
<div class="accordion-collapse" id="collapse_address_suggestions"
|
||||
aria-labelledby="heading_address_suggestions" data-bs-parent="#addressSuggestions">
|
||||
<div v-if="showAddressSuggestion">
|
||||
<div class="flex-table householdAddressSuggestionList">
|
||||
<div v-for="a in filterAddressesSuggestion" class="item-bloc">
|
||||
<div class="float-button bottom">
|
||||
<div class="box">
|
||||
<div class="action">
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button class="btn btn-sm btn-choose" @click="setHouseholdAddress(a)">
|
||||
{{ $t('household_members_editor.household.household_live_to_this_address') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="list-content fa-ul">
|
||||
<li>
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
<address-render-box :address="a"></address-render-box>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-table householdSuggestionList">
|
||||
<div v-if="isModeNewAllowed" class="item-bloc">
|
||||
<div>
|
||||
<section>
|
||||
<div class="item-row">
|
||||
<div class="item-col">
|
||||
<div class="h4">
|
||||
<i class="fa fa-home"></i> {{ $t('household_members_editor.household.new_household') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button @click="setModeNew" class="btn btn-sm btn-create">{{ $t('household_members_editor.household.create_household') }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- if allow leave household -->
|
||||
<div v-if="isModeLeaveAllowed" class="item-bloc">
|
||||
<div>
|
||||
<section>
|
||||
<div class="item-row">
|
||||
<div class="item-col">
|
||||
<div class="h4">
|
||||
<span class="fa-stack fa-lg">
|
||||
<i class="fa fa-home fa-stack-1x"></i>
|
||||
<i class="fa fa-ban fa-stack-2x text-danger"></i>
|
||||
</span>
|
||||
{{ $t('household_members_editor.household.leave_without_household') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-row">
|
||||
{{ $t('household_members_editor.household.will_leave_any_household_explanation')}}
|
||||
</div>
|
||||
</section>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button @click="setModeLeave" class="btn btn-sm">
|
||||
<i class="fa fa-sign-out"></i>
|
||||
{{ $t('household_members_editor.household.leave') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-for="item in getSuggestions">
|
||||
<div class="item-bloc">
|
||||
<household-render-box :household="item.household"></household-render-box>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button class="btn btn-sm btn-choose" @click="selectHousehold(item.household)">
|
||||
{{ $t('household_members_editor.select_household') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="record_actions">
|
||||
<li >
|
||||
<add-address
|
||||
:context="addAddress.context"
|
||||
<div v-else>
|
||||
<div class="flex-table">
|
||||
<div class="item-bloc">
|
||||
<template v-if="isModeLeave">
|
||||
<section>
|
||||
<div class="item-row">
|
||||
<div class="item-col">
|
||||
<div class="h4">
|
||||
<span class="fa-stack fa-lg">
|
||||
<i class="fa fa-home fa-stack-1x"></i>
|
||||
<i class="fa fa-ban fa-stack-2x text-danger"></i>
|
||||
</span>
|
||||
{{ $t('household_members_editor.household.leave_without_household') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-row">
|
||||
{{ $t('household_members_editor.household.will_leave_any_household_explanation')}}
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<template v-else>
|
||||
<household-render-box :household="household" :isAddressMultiline="true"></household-render-box>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<add-address
|
||||
:context="getAddressContext"
|
||||
:key="addAddress.key"
|
||||
:options="addAddress.options"
|
||||
:result="addAddress.result"
|
||||
@addressChangedCallback="setHouseholdCreatedAddress"
|
||||
ref="addAddress">
|
||||
</add-address>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div v-if="isHouseholdNew && hasHouseholdAddress">
|
||||
<ul class="record_actions">
|
||||
<li >
|
||||
<button class="btn btn-misc" @click="removeHouseholdAddress">
|
||||
{{ $t('household_members_editor.household.delete_this_address') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else-if="isForceLeaveWithoutHousehold">
|
||||
{{ $t('household_members_editor.household.will_leave_any_household') }}
|
||||
</div>
|
||||
<div v-else class="alert alert-info">{{ $t('household_members_editor.household.no_household_choose_one') }}</div>
|
||||
|
||||
<ul v-if="allowChangeHousehold" class="record_actions">
|
||||
<li v-if="allowHouseholdCreate">
|
||||
<button class="btn btn-create" @click="createHousehold">
|
||||
{{ $t('household_members_editor.household.create_household') }}
|
||||
</button>
|
||||
</li>
|
||||
<li v-if="allowHouseholdSearch">
|
||||
<button class="btn btn-misc">
|
||||
<i class="fa fa-search"></i>{{ $t('household_members_editor.household.search_household') }}
|
||||
</button>
|
||||
</li>
|
||||
<li v-if="allowLeaveWithoutHousehold" >
|
||||
<button @click="forceLeaveWithoutHousehold" class="btn btn-orange">
|
||||
<i class="fa fa-sign-out"></i>{{ $t('household_members_editor.household.leave_without_household') }}
|
||||
</button>
|
||||
</li>
|
||||
<li v-if="allowRemoveHousehold">
|
||||
<button @click="removeHousehold" class="btn">
|
||||
{{ $t('household_members_editor.household.change') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div v-if="hasHouseholdSuggestion" class="householdSuggestions my-5">
|
||||
<h4 class="mb-3">
|
||||
{{ $t('household_members_editor.household_for_participants_accompanying_period') }} :
|
||||
</h4>
|
||||
<div class="accordion" id="householdSuggestions">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="heading_household_suggestions">
|
||||
<button v-if="!showHouseholdSuggestion"
|
||||
class="accordion-button collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
aria-expanded="false"
|
||||
@click="toggleHouseholdSuggestion">
|
||||
{{ $tc('household_members_editor.show_household_suggestion', countHouseholdSuggestion) }}
|
||||
</button>
|
||||
<button v-if="showHouseholdSuggestion"
|
||||
class="accordion-button"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
aria-expanded="true"
|
||||
@click="toggleHouseholdSuggestion">
|
||||
{{ $t('household_members_editor.hide_household_suggestion') }}
|
||||
</button>
|
||||
<!-- disabled bootstrap behaviour: data-bs-target="#collapse_household_suggestions" aria-controls="collapse_household_suggestions" -->
|
||||
</h2>
|
||||
<div class="accordion-collapse" id="collapse_household_suggestions"
|
||||
aria-labelledby="heading_household_suggestions" data-bs-parent="#householdSuggestions">
|
||||
<div v-if="showHouseholdSuggestion">
|
||||
<div class="flex-table householdSuggestionList">
|
||||
<div v-for="h in filterHouseholdSuggestionByAccompanyingPeriod" class="item-bloc">
|
||||
<household-render-box :household="h"></household-render-box>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button class="btn btn-sm btn-choose" @click="selectHousehold(h)">
|
||||
{{ $t('household_members_editor.select_household') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:addressChangedCallback="addressChanged"
|
||||
></add-address>
|
||||
</li>
|
||||
<li v-if="hasHouseholdAddress">
|
||||
<button class="btn btn-remove"
|
||||
@click="removeHouseholdAddress">
|
||||
{{ $t('household_members_editor.household.remove_address') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul v-if="isModeNewAllowed || isModeLeaveAllowed || getModeSuggestions.length > 0" class="record_actions">
|
||||
<li>
|
||||
<button class="btn btn-sm btn-chill-beige" @click="resetMode">
|
||||
{{ $t('household_members_editor.household.reset_mode') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -185,35 +140,32 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
addAddress: {
|
||||
context: {
|
||||
target: {
|
||||
name: 'household_create',
|
||||
id: 0
|
||||
},
|
||||
edit: false,
|
||||
addressId: null
|
||||
},
|
||||
key: 'household_new',
|
||||
options: {
|
||||
useDate: {
|
||||
validFrom: true
|
||||
validFrom: false,
|
||||
validTo: false,
|
||||
},
|
||||
hideAddress: true,
|
||||
button: {
|
||||
text: {
|
||||
create: 'household_members_editor.household.or_create_new_address',
|
||||
edit: null,
|
||||
create: 'household_members_editor.household.set_address',
|
||||
edit: 'household_members_editor.household.update_address',
|
||||
}
|
||||
},
|
||||
title: {
|
||||
create: 'household_members_editor.household.create_new_address',
|
||||
edit: null,
|
||||
edit: 'household_members_editor.household.update_address_title',
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isModeNewAllowed',
|
||||
'isModeLeaveAllowed',
|
||||
'getSuggestions',
|
||||
'hasHousehold',
|
||||
'isHouseholdNew',
|
||||
'hasHouseholdSuggestion',
|
||||
@ -223,68 +175,38 @@ export default {
|
||||
'countAddressSuggestion',
|
||||
'filterAddressesSuggestion',
|
||||
'hasHouseholdAddress',
|
||||
'isModeLeave',
|
||||
'getAddressContext',
|
||||
]),
|
||||
...mapState([
|
||||
'showHouseholdSuggestion',
|
||||
'showAddressSuggestion'
|
||||
'showAddressSuggestion',
|
||||
'mode',
|
||||
]),
|
||||
household() {
|
||||
return this.$store.state.household;
|
||||
},
|
||||
allowHouseholdCreate() {
|
||||
return this.$store.state.allowHouseholdCreate && !this.$store.getters.hasHousehold;
|
||||
},
|
||||
allowHouseholdSearch() {
|
||||
return false;
|
||||
return this.$store.state.allowHouseholdSearch && !this.$store.getters.hasHousehold;
|
||||
},
|
||||
allowLeaveWithoutHousehold() {
|
||||
return this.$store.state.allowLeaveWithoutHousehold && !this.$store.getters.hasHousehold;
|
||||
},
|
||||
allowRemoveHousehold() {
|
||||
return this.$store.getters.hasHousehold &&
|
||||
(
|
||||
this.allowHouseholdCreate || this.allowHouseholdSearch ||
|
||||
this.allowLeaveWithoutHousehold
|
||||
)
|
||||
;
|
||||
},
|
||||
allowChangeHousehold() {
|
||||
return this.allowHouseholdCreate || this.allowHouseholdSearch ||
|
||||
this.allowLeaveWithoutHousehold;
|
||||
},
|
||||
isForceLeaveWithoutHousehold() {
|
||||
return this.$store.state.forceLeaveWithoutHousehold;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
createHousehold() {
|
||||
setModeNew() {
|
||||
this.$store.dispatch('createHousehold');
|
||||
},
|
||||
forceLeaveWithoutHousehold() {
|
||||
setModeLeave() {
|
||||
this.$store.dispatch('forceLeaveWithoutHousehold');
|
||||
},
|
||||
toggleHouseholdSuggestion() {
|
||||
this.$store.commit('toggleHouseholdSuggestion');
|
||||
resetMode() {
|
||||
this.$store.commit('resetMode');
|
||||
},
|
||||
toggleAddressSuggestion() {
|
||||
this.$store.commit('toggleAddressSuggestion');
|
||||
addressChanged(payload) {
|
||||
console.log("addressChanged", payload);
|
||||
this.$store.dispatch('setHouseholdNewAddress', payload.address);
|
||||
},
|
||||
selectHousehold(h) {
|
||||
this.$store.dispatch('selectHousehold', h);
|
||||
this.toggleHouseholdSuggestion();
|
||||
},
|
||||
removeHousehold() {
|
||||
this.$store.dispatch('removeHousehold');
|
||||
},
|
||||
setHouseholdAddress(a) {
|
||||
let payload = this.$refs.addAddress.submitNewAddress();
|
||||
console.log('setHouseholdAddress', a);
|
||||
this.$store.commit('setHouseholdAddress', a);
|
||||
},
|
||||
setHouseholdCreatedAddress(payload) {
|
||||
console.log('setHouseholdAddress', payload);
|
||||
this.$store.dispatch('setHouseholdNewAddress', payload);
|
||||
},
|
||||
removeHouseholdAddress() {
|
||||
this.$store.commit('removeHouseholdAddress');
|
||||
@ -310,28 +232,4 @@ div.householdSuggestionList {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
div.householdAddressSuggestionList {
|
||||
display: flex;
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
& > li {}
|
||||
}
|
||||
.householdSuggestionList {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
& > .item {
|
||||
margin-bottom: 0.8rem;
|
||||
width: calc(50% - 1rem);
|
||||
border: 1px solid var(--chill-light-gray);
|
||||
padding: 0.5rem 0.5rem 0 0.5rem;
|
||||
ul.record_actions {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
</style>
|
||||
|
@ -7,16 +7,27 @@ const appMessages = {
|
||||
household: {
|
||||
no_household_choose_one: "Aucun ménage de destination. Choisissez un ménage. Les usagers concernés par la modification apparaitront ensuite.",
|
||||
new_household: "Nouveau ménage",
|
||||
create_household: "Créer un nouveau ménage de destination",
|
||||
create_household: "Créer",
|
||||
search_household: "Chercher un ménage",
|
||||
will_leave_any_household: "Ne rejoignent pas de ménage",
|
||||
will_leave_any_household: "Les usagers ne rejoignent pas de ménage",
|
||||
leave: "Quitter",
|
||||
will_leave_any_household_explanation: "Les usagers quitteront leur ménage actuel, et ne seront pas associés à un autre ménage. Par ailleurs, ils seront enregistrés comme étant sans adresse connue.",
|
||||
leave_without_household: "Sans nouveau ménage",
|
||||
set_address: "Indiquer une adresse",
|
||||
reset_mode: "Modifier la destination",
|
||||
remove_address: "Supprimer l'adresse",
|
||||
update_address: "Mettre à jour l'adresse",
|
||||
// remove ?
|
||||
/*
|
||||
where_live_the_household: "À quelle adresse habite ce ménage ?",
|
||||
household_live_to_this_address: "Sélectionner l'adresse",
|
||||
no_suggestions: "Aucune adresse à suggérer",
|
||||
delete_this_address: "Supprimer cette adresse",
|
||||
create_new_address: "Créer une nouvelle adresse",
|
||||
or_create_new_address: "Ou créer une nouvelle adresse",
|
||||
|
||||
*/
|
||||
// end remove ?
|
||||
},
|
||||
concerned: {
|
||||
title: "Nouveaux membres du ménage",
|
||||
@ -34,7 +45,7 @@ const appMessages = {
|
||||
is_not_holder: "N'est pas titulaire",
|
||||
remove_position: "Retirer des {position}",
|
||||
remove_concerned: "Ne plus transférer",
|
||||
household_part: "Ménage de destination",
|
||||
household_part: "Destination",
|
||||
suggestions: "Suggestions",
|
||||
hide_household_suggestion: "Masquer les suggestions",
|
||||
show_household_suggestion: 'Aucune suggestion | Afficher une suggestion | Afficher {count} suggestions',
|
||||
|
@ -29,6 +29,15 @@ const store = createStore({
|
||||
return 0;
|
||||
}),
|
||||
startDate: new Date(),
|
||||
/**
|
||||
* Indicates if the destination is:
|
||||
*
|
||||
* * "new" => a new household
|
||||
* * "existing" => an existing household
|
||||
* * "leave" => leave without household
|
||||
* * null if not set
|
||||
*/
|
||||
mode: window.household_members_editor_data.household === null ? null : "existing",
|
||||
allowHouseholdCreate: window.household_members_editor_data.allowHouseholdCreate,
|
||||
allowHouseholdSearch: window.household_members_editor_data.allowHouseholdSearch,
|
||||
allowLeaveWithoutHousehold: window.household_members_editor_data.allowLeaveWithoutHousehold,
|
||||
@ -41,11 +50,70 @@ const store = createStore({
|
||||
errors: []
|
||||
},
|
||||
getters: {
|
||||
/**
|
||||
* return true if this page allow to create a new household
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isModeNewAllowed(state) {
|
||||
return state.allowHouseholdCreate;
|
||||
},
|
||||
/**
|
||||
* return true if this page allow to "leave without household"
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isModeLeaveAllowed(state) {
|
||||
return state.allowLeaveWithoutHousehold;
|
||||
},
|
||||
/**
|
||||
* return true if the mode "leave" is selected
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isModeLeave(state) {
|
||||
return state.mode === "leave";
|
||||
},
|
||||
getSuggestions(state) {
|
||||
let suggestions = [];
|
||||
state.householdSuggestionByAccompanyingPeriod.forEach(h => {
|
||||
console.log(h);
|
||||
suggestions.push({household: h});
|
||||
});
|
||||
|
||||
return suggestions;
|
||||
},
|
||||
isHouseholdNew(state) {
|
||||
return state.mode === "new";
|
||||
/*
|
||||
if (state.household === null) {
|
||||
return false;
|
||||
}
|
||||
return !Number.isInteger(state.household.id);
|
||||
|
||||
*/
|
||||
},
|
||||
getAddressContext(state, getters) {
|
||||
if (!getters.hasHouseholdAddress) {
|
||||
return {
|
||||
edit: false,
|
||||
addressId: null,
|
||||
target: {
|
||||
name: state.household.type,
|
||||
id: state.household.id
|
||||
},
|
||||
suggestions: state.addressesSuggestion
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
edit: true,
|
||||
addressId: state.household.current_address.id,
|
||||
target: {
|
||||
name: state.household.type,
|
||||
id: state.household.id
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
hasHouseholdAddress(state) {
|
||||
if (null === state.household) {
|
||||
@ -180,6 +248,11 @@ const store = createStore({
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
resetMode(state) {
|
||||
state.mode = null;
|
||||
state.household = null;
|
||||
state.forceLeaveWithoutHousehold = false;
|
||||
},
|
||||
addConcerned(state, person) {
|
||||
let persons = state.concerned.map(conc => conc.person.id);
|
||||
if (!persons.includes(person.id)) {
|
||||
@ -222,6 +295,7 @@ const store = createStore({
|
||||
current_address: null,
|
||||
current_members_id: []
|
||||
};
|
||||
state.mode = "new";
|
||||
state.forceLeaveWithoutHousehold = false;
|
||||
},
|
||||
removeHousehold(state) {
|
||||
@ -229,6 +303,7 @@ const store = createStore({
|
||||
state.forceLeaveWithoutHousehold = false;
|
||||
},
|
||||
setHouseholdAddress(state, address) {
|
||||
console.log('setHouseholdAddress commit', address);
|
||||
if (null === state.household) {
|
||||
console.error("no household");
|
||||
throw new Error("No household");
|
||||
@ -246,10 +321,12 @@ const store = createStore({
|
||||
},
|
||||
forceLeaveWithoutHousehold(state) {
|
||||
state.household = null;
|
||||
state.mode = "leave";
|
||||
state.forceLeaveWithoutHousehold = true;
|
||||
},
|
||||
selectHousehold(state, household) {
|
||||
state.household = household;
|
||||
state.mode = "existing";
|
||||
state.forceLeaveWithoutHousehold = false;
|
||||
},
|
||||
setHouseholdSuggestionByAccompanyingPeriod(state, households) {
|
||||
@ -320,18 +397,8 @@ const store = createStore({
|
||||
commit('createHousehold');
|
||||
dispatch('computeWarnings');
|
||||
},
|
||||
setHouseholdNewAddress({ commit }, payload) {
|
||||
let url = `/api/1.0/main/address/${payload.addressId}.json`;
|
||||
window.fetch(url).then(r => {
|
||||
if (r.ok) {
|
||||
return r.json();
|
||||
}
|
||||
throw new Error("error while fetch address");
|
||||
}).then(data => {
|
||||
commit('setHouseholdAddress', data);
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
});
|
||||
setHouseholdNewAddress({ commit }, address) {
|
||||
commit('setHouseholdAddress', address);
|
||||
},
|
||||
forceLeaveWithoutHousehold({ commit, dispatch }) {
|
||||
commit('forceLeaveWithoutHousehold');
|
||||
|
Loading…
x
Reference in New Issue
Block a user