mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
merge master into branch
This commit is contained in:
commit
39ba21f308
18
CHANGELOG.md
18
CHANGELOG.md
@ -11,6 +11,12 @@ and this project adheres to
|
||||
## Unreleased
|
||||
|
||||
<!-- write down unreleased development here -->
|
||||
* [person] AccompanyingPeriodWorkEvaluation: fix circular reference when serialising (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/495)
|
||||
* [person] order accompanying period by opening date in search persons, person and household period lists (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/493)
|
||||
* [parcours] autosave of the pinned comment for draft accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/477)
|
||||
* [main] filter user job in undispatch acc period to assign (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/472)
|
||||
* [main] filter user job in undispatch acc period to assign (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/472)
|
||||
* [person] Add url in accompanying period work evaluations entity and form (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/476)
|
||||
* [person] Add document generation in admin and in person/{id}/document (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/464)
|
||||
* [activity] do not override location if already exist (when validating new activity) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/470)
|
||||
* [parcours] Toggle emergency/intensity only by referrer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/442)
|
||||
@ -28,8 +34,20 @@ and this project adheres to
|
||||
* [confidential] Fix position of toggle button so it does not cover text nor fall outside of box (no issue)
|
||||
* [parcours] Fix edit of both thirdparty and contact name (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/474)
|
||||
* [template] do not list inactive templates (for doc generator)
|
||||
* [household] bugfix if position of member is null, renderbox no longer throws an error (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/480)
|
||||
* [parcours] location cannot be removed if linked to a user (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/478)
|
||||
* [person] email added to twig personRenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/490)
|
||||
* [activity] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471)
|
||||
* [person] Add link to current household in person banner (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/484)
|
||||
* [address] person badge in address history changed to open OnTheFly with all person info (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/489)
|
||||
* [person] Change 'personne' with 'usager' and '&' with 'ET' (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/499)
|
||||
* [thirdparty] Add parameter condition to display centers or not (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/500)
|
||||
* [phonenumber] Remove placeholder in phonenumber field (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/496)
|
||||
* [person_resource] separate create page created to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/504)
|
||||
* [contact] add contact button color changed plus the pipe at the side removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/506)
|
||||
* [household] create-edit household composition placed in separate page to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/505)
|
||||
* [blur] Improved positioning of toggle icon (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/486)
|
||||
|
||||
## Test releases
|
||||
|
||||
### test release 2022-02-21
|
||||
|
@ -350,11 +350,6 @@ parameters:
|
||||
count: 6
|
||||
path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
|
||||
|
||||
-
|
||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
||||
count: 2
|
||||
path: src/Bundle/ChillPersonBundle/Entity/PersonPhone.php
|
||||
|
||||
-
|
||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
||||
count: 1
|
||||
|
@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
namespace Chill\DocStoreBundle\Workflow;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
||||
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||
@ -36,6 +37,13 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function getDeletionRoles(): array
|
||||
{
|
||||
return [
|
||||
AccompanyingCourseDocumentVoter::DELETE,
|
||||
];
|
||||
}
|
||||
|
||||
public function getEntityData(EntityWorkflow $entityWorkflow, array $options = []): array
|
||||
{
|
||||
$course = $this->getRelatedEntity($entityWorkflow)
|
||||
@ -66,6 +74,18 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler
|
||||
return $this->repository->find($entityWorkflow->getRelatedEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingCourseDocument $object
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
{
|
||||
return [
|
||||
['entityClass' => AccompanyingCourseDocument::class, 'entityId' => $object->getId()],
|
||||
];
|
||||
}
|
||||
|
||||
public function getRoleShow(EntityWorkflow $entityWorkflow): ?string
|
||||
{
|
||||
return null;
|
||||
@ -84,6 +104,11 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler
|
||||
];
|
||||
}
|
||||
|
||||
public function isObjectSupported(object $object): bool
|
||||
{
|
||||
return $object instanceof AccompanyingCourseDocument;
|
||||
}
|
||||
|
||||
public function supports(EntityWorkflow $entityWorkflow, array $options = []): bool
|
||||
{
|
||||
return $entityWorkflow->getRelatedEntityClass() === AccompanyingCourseDocument::class;
|
||||
|
@ -256,6 +256,13 @@ class ChillMainExtension extends Extension implements
|
||||
'channels' => ['chill'],
|
||||
]);
|
||||
|
||||
$container->prependExtensionConfig('security', [
|
||||
'access_decision_manager' => [
|
||||
'strategy' => 'unanimous',
|
||||
'allow_if_all_abstain' => false,
|
||||
],
|
||||
]);
|
||||
|
||||
//add crud api
|
||||
$this->prependCruds($container);
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ class UserJob
|
||||
* @var array|string[]A
|
||||
* @ORM\Column(name="label", type="json")
|
||||
* @Serializer\Groups({"read", "docgen:read"})
|
||||
* @Serializer\Context({"is-translatable": true}, groups={"docgen:read"})
|
||||
*/
|
||||
protected array $label = [];
|
||||
|
||||
|
@ -192,7 +192,7 @@ class EntityWorkflowStep
|
||||
* You should **not** rely on this method to get all users which are able to
|
||||
* apply a transition on this step. Use @see{EntityWorkflowStep::getAllDestUser} instead.
|
||||
*/
|
||||
public function getDestUser(): collection
|
||||
public function getDestUser(): Collection
|
||||
{
|
||||
return $this->destUser;
|
||||
}
|
||||
|
@ -16,9 +16,7 @@ use libphonenumber\PhoneNumberUtil;
|
||||
use Misd\PhoneNumberBundle\Form\Type\PhoneNumberType;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\Options;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use function array_key_exists;
|
||||
|
||||
class ChillPhoneNumberType extends AbstractType
|
||||
{
|
||||
@ -37,21 +35,7 @@ class ChillPhoneNumberType extends AbstractType
|
||||
$resolver
|
||||
->setDefault('default_region', $this->defaultCarrierCode)
|
||||
->setDefault('format', PhoneNumberFormat::NATIONAL)
|
||||
->setDefault('type', \libphonenumber\PhoneNumberType::FIXED_LINE_OR_MOBILE)
|
||||
->setNormalizer('attr', function (Options $options, $value) {
|
||||
if (array_key_exists('placeholder', $value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$examplePhoneNumber = $this->phoneNumberUtil->getExampleNumberForType($this->defaultCarrierCode, $options['type']);
|
||||
|
||||
return array_merge(
|
||||
$value,
|
||||
[
|
||||
'placeholder' => PhoneNumberUtil::getInstance()->format($examplePhoneNumber, $options['format']),
|
||||
]
|
||||
);
|
||||
});
|
||||
->setDefault('type', \libphonenumber\PhoneNumberType::FIXED_LINE_OR_MOBILE);
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
|
@ -27,7 +27,7 @@ interface PhoneNumberHelperInterface
|
||||
/**
|
||||
* Get type (mobile, landline, ...) for phone number.
|
||||
*/
|
||||
public function getType(string $phonenumber): string;
|
||||
public function getType(PhoneNumber $phonenumber): string;
|
||||
|
||||
/**
|
||||
* Return true if the validation is configured and available.
|
||||
|
@ -17,6 +17,7 @@ use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
use libphonenumber\NumberParseException;
|
||||
use libphonenumber\PhoneNumber;
|
||||
use libphonenumber\PhoneNumberType;
|
||||
use libphonenumber\PhoneNumberUtil;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@ -86,9 +87,19 @@ final class PhonenumberHelper implements PhoneNumberHelperInterface
|
||||
/**
|
||||
* Get type (mobile, landline, ...) for phone number.
|
||||
*/
|
||||
public function getType(string $phonenumber): string
|
||||
public function getType(PhoneNumber $phonenumber): string
|
||||
{
|
||||
return $this->performTwilioLookup($phonenumber) ?? 'unknown';
|
||||
switch ($this->phoneNumberUtil->getNumberType($phonenumber)) {
|
||||
case PhoneNumberType::MOBILE:
|
||||
return 'mobile';
|
||||
|
||||
case PhoneNumberType::FIXED_LINE:
|
||||
case PhoneNumberType::VOIP:
|
||||
return 'landline';
|
||||
|
||||
default:
|
||||
return 'landline';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,6 +55,30 @@ class EntityWorkflowRepository implements ObjectRepository
|
||||
return (int) $qb->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
public function countRelatedWorkflows(array $relateds): int
|
||||
{
|
||||
$qb = $this->repository->createQueryBuilder('w');
|
||||
|
||||
$orX = $qb->expr()->orX();
|
||||
$i = 0;
|
||||
|
||||
foreach ($relateds as $related) {
|
||||
$orX->add(
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->eq('w.relatedEntityClass', ':entity_class_' . $i),
|
||||
$qb->expr()->eq('w.relatedEntityId', ':entity_id_' . $i)
|
||||
)
|
||||
);
|
||||
$qb
|
||||
->setParameter('entity_class_' . $i, $related['entityClass'])
|
||||
->setParameter('entity_id_' . $i, $related['entityId']);
|
||||
++$i;
|
||||
}
|
||||
$qb->where($orX);
|
||||
|
||||
return $qb->select('COUNT(w)')->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
public function find($id): ?EntityWorkflow
|
||||
{
|
||||
return $this->repository->find($id);
|
||||
|
@ -25,7 +25,7 @@ $chill-theme-buttons: (
|
||||
"notify": $chill-blue,
|
||||
"search": $gray-300,
|
||||
"unlink": $chill-red,
|
||||
"tpchild": $chill-pink,
|
||||
"tpchild": $chill-green,
|
||||
);
|
||||
|
||||
@each $button, $color in $chill-theme-buttons {
|
||||
|
@ -1,17 +1,22 @@
|
||||
/**
|
||||
* Generic api method that can be adapted to any fetch request
|
||||
*/
|
||||
const makeFetch = (method, url, body) => {
|
||||
return fetch(url, {
|
||||
const makeFetch = (method, url, body, options) => {
|
||||
let opts = {
|
||||
method: method,
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=utf-8'
|
||||
},
|
||||
body: (body !== null) ? JSON.stringify(body) : null
|
||||
})
|
||||
};
|
||||
|
||||
if (typeof options !== 'undefined') {
|
||||
opts = Object.assign(opts, options);
|
||||
}
|
||||
|
||||
return fetch(url, opts)
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
console.log('200 error')
|
||||
return response.json();
|
||||
}
|
||||
|
||||
|
@ -1,37 +1,26 @@
|
||||
.confidential {
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
.toggle-far-twig {
|
||||
i {
|
||||
bottom: 0px;
|
||||
right: -30px;
|
||||
}
|
||||
margin-right: 20px
|
||||
}
|
||||
|
||||
.toggle-close-twig {
|
||||
i {
|
||||
bottom: 0px;
|
||||
right: -5px;
|
||||
}
|
||||
.toggle-container {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
cursor: pointer;
|
||||
z-index: 5;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.toggle{
|
||||
margin-left: 30px;
|
||||
margin-top: 5px;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
z-index: 5;
|
||||
right: -30px
|
||||
}
|
||||
|
||||
.toggle-far {
|
||||
bottom: 0px;
|
||||
right: 20px !important;
|
||||
}
|
||||
|
||||
.toggle-close {
|
||||
bottom: 125px;
|
||||
right: 15px !important;
|
||||
right: 4px;
|
||||
&-twig {
|
||||
position: absolute;
|
||||
right: -25px;
|
||||
bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.blur {
|
||||
|
@ -2,18 +2,19 @@ require('./blur.scss');
|
||||
|
||||
document.querySelectorAll('.confidential').forEach(function (el) {
|
||||
let i = document.createElement('i');
|
||||
const classes = ['fa', 'fa-eye', 'toggle'];
|
||||
const classes = ['fa', 'fa-eye-slash', 'toggle-twig'];
|
||||
i.classList.add(...classes);
|
||||
el.appendChild(i);
|
||||
|
||||
const toggleBlur = function(e) {
|
||||
for (let child of el.children) {
|
||||
if (!child.classList.contains('toggle')) {
|
||||
if (!child.classList.contains('toggle-twig')) {
|
||||
child.classList.toggle('blur');
|
||||
}
|
||||
}
|
||||
i.classList.toggle('fa-eye');
|
||||
i.classList.toggle('fa-eye-slash');
|
||||
i.classList.toggle('fa-eye');
|
||||
}
|
||||
i.addEventListener('click', toggleBlur);
|
||||
toggleBlur();
|
||||
});
|
||||
});
|
@ -22,6 +22,7 @@ const fetchCountries = () => {
|
||||
*/
|
||||
const fetchCities = (country) => {
|
||||
//console.log('<<< fetching cities for', country);
|
||||
// warning: do not use fetchResults (in apiMethods): we need only a **part** of the results in the db
|
||||
const url = `/api/1.0/main/postal-code.json?item_per_page=1000&country=${country.id}`;
|
||||
return fetch(url)
|
||||
.then(response => {
|
||||
|
@ -42,9 +42,6 @@
|
||||
<a class="btn btn-sm btn-show" :href="getUrl(e)">
|
||||
{{ $t('show_entity', { entity: $t('the_evaluation') }) }}
|
||||
</a>
|
||||
<a class="btn btn-sm btn-update" :href="getUrl(e.accompanyingPeriodWork)">
|
||||
{{ $t('show_entity', { entity: $t('the_action') }) }}
|
||||
</a>
|
||||
<a class="btn btn-sm btn-show" :href="getUrl(e.accompanyingPeriodWork.accompanyingPeriod)">
|
||||
{{ $t('show_entity', { entity: $t('the_course') }) }}
|
||||
</a>
|
||||
@ -102,4 +99,4 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
@ -3,8 +3,8 @@
|
||||
<div :class="{ 'blur': isBlurred }">
|
||||
<slot name="confidential-content"></slot>
|
||||
</div>
|
||||
<div>
|
||||
<i class="fa fa-eye toggle" :class="positionBtn" aria-hidden="true" @click="toggleBlur"></i>
|
||||
<div class="toggle-container">
|
||||
<i class="fa toggle" :class="toggleIcon" aria-hidden="true" @click="toggleBlur"></i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -12,28 +12,24 @@
|
||||
<script>
|
||||
export default {
|
||||
name: "Confidential",
|
||||
props: ['positionBtnFar'],
|
||||
data() {
|
||||
return {
|
||||
isBlurred: true,
|
||||
toggleIcon: 'fa-eye',
|
||||
};
|
||||
},
|
||||
methods : {
|
||||
toggleBlur() {
|
||||
console.log(this.positionBtnFar);
|
||||
this.isBlurred = !this.isBlurred;
|
||||
this.toggleIcon = this.isBlurred ? 'fa-eye' : 'fa-eye-slash';
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
positionBtn() {
|
||||
return this.positionBtnFar ? 'toggle-far' : 'toggle-close'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.confidential{
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
}
|
||||
</style>
|
||||
|
@ -59,7 +59,7 @@
|
||||
must be shown in such list
|
||||
#}
|
||||
{%- if render == 'list' -%}
|
||||
<li class="chill-entity entity-address {% if address.confidential %} confidential toggle-far-twig {% endif %}">
|
||||
<li class="chill-entity entity-address {% if address.confidential %} confidential {% endif %}">
|
||||
{% if options['with_picto'] %}
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
{% endif %}
|
||||
@ -68,7 +68,7 @@
|
||||
{%- endif -%}
|
||||
|
||||
{%- if render == 'inline' -%}
|
||||
<span class="chill-entity entity-address {% if address.confidential %} confidential toggle-far-twig {% endif %}">
|
||||
<span class="chill-entity entity-address {% if address.confidential %} confidential {% endif %}">
|
||||
{% if options['with_picto'] %}
|
||||
<i class="fa fa-fw fa-map-marker"></i>
|
||||
{% endif %}
|
||||
@ -77,7 +77,7 @@
|
||||
{%- endif -%}
|
||||
|
||||
{%- if render == 'bloc' -%}
|
||||
<div class="chill-entity entity-address {% if address.confidential %} confidential toggle-close-twig {% endif %}">
|
||||
<div class="chill-entity entity-address {% if address.confidential %} confidential {% endif %}">
|
||||
{% if options['has_no_address'] == true and address.isNoAddress == true %}
|
||||
{% if address.postCode is not empty %}
|
||||
<div class="address{% if options['multiline'] %} multiline{% endif %}{% if options['with_delimiter'] %} delimiter{% endif %}">
|
||||
|
@ -9,6 +9,12 @@
|
||||
<span class="item-key">{{ 'Le'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.previous.transitionAt|format_datetime('short', 'short') }}</b>
|
||||
</li>
|
||||
<li>
|
||||
<span class="item-key">{{ 'workflow.For'|trans ~ ' : ' }}</span>
|
||||
<b>
|
||||
{% for d in step.destUser %}{{ d|chill_entity_render_string }}{% if not loop.last %}, {% endif %}{% endfor %}
|
||||
</b>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<span class="item-key">{{ 'workflow.Created by'|trans ~ ' : ' }}</span>
|
||||
|
@ -0,0 +1,65 @@
|
||||
<?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\MainBundle\Security\Authorization;
|
||||
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
use function in_array;
|
||||
use function is_object;
|
||||
|
||||
class WorkflowEntityDeletionVoter extends Voter
|
||||
{
|
||||
private EntityWorkflowRepository $entityWorkflowRepository;
|
||||
|
||||
/**
|
||||
* @var iterable|EntityWorkflowHandlerInterface[]
|
||||
*/
|
||||
private iterable $handlers;
|
||||
|
||||
public function __construct($handlers, EntityWorkflowRepository $entityWorkflowRepository)
|
||||
{
|
||||
$this->handlers = $handlers;
|
||||
$this->entityWorkflowRepository = $entityWorkflowRepository;
|
||||
}
|
||||
|
||||
protected function supports($attribute, $subject)
|
||||
{
|
||||
if (!is_object($subject)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->handlers as $handler) {
|
||||
if ($handler->isObjectSupported($subject)
|
||||
&& in_array($attribute, $handler->getDeletionRoles($subject), true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
|
||||
{
|
||||
foreach ($this->handlers as $handler) {
|
||||
if ($handler->isObjectSupported($subject)) {
|
||||
return 0 === $this->entityWorkflowRepository->countRelatedWorkflows(
|
||||
$handler->getRelatedObjects($subject)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException('no handlers found');
|
||||
}
|
||||
}
|
@ -113,6 +113,7 @@ class AddressNormalizer implements ContextAwareNormalizerInterface, NormalizerAw
|
||||
[
|
||||
'postcode' => $helper->normalize(self::NULL_POSTCODE_COUNTRY, $format, $context),
|
||||
'country' => $helper->normalize(self::NULL_POSTCODE_COUNTRY, $format, $context),
|
||||
'lines' => [],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -16,10 +16,11 @@ use libphonenumber\PhoneNumber;
|
||||
use libphonenumber\PhoneNumberUtil;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterface
|
||||
class PhonenumberNormalizer implements ContextAwareNormalizerInterface, DenormalizerInterface
|
||||
{
|
||||
private string $defaultCarrierCode;
|
||||
|
||||
@ -40,6 +41,10 @@ class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterfac
|
||||
*/
|
||||
public function denormalize($data, $type, $format = null, array $context = [])
|
||||
{
|
||||
if ('' === trim($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->phoneNumberUtil->parse($data, $this->defaultCarrierCode);
|
||||
} catch (NumberParseException $e) {
|
||||
@ -49,6 +54,10 @@ class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterfac
|
||||
|
||||
public function normalize($object, ?string $format = null, array $context = []): string
|
||||
{
|
||||
if ($format === 'docgen' && null === $object) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->phoneNumberUtil->formatOutOfCountryCallingNumber($object, $this->defaultCarrierCode);
|
||||
}
|
||||
|
||||
@ -57,8 +66,18 @@ class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterfac
|
||||
return 'libphonenumber\PhoneNumber' === $type;
|
||||
}
|
||||
|
||||
public function supportsNormalization($data, ?string $format = null)
|
||||
public function supportsNormalization($data, ?string $format = null, array $context = []): bool
|
||||
{
|
||||
return $data instanceof PhoneNumber;
|
||||
if ($data instanceof PhoneNumber && $format === 'json') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($format === 'docgen' && (
|
||||
$data instanceof PhoneNumber || PhoneNumber::class === ($context['docgen:expects'] ?? null)
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,19 @@ use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
|
||||
interface EntityWorkflowHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @return array|string[]
|
||||
*/
|
||||
public function getDeletionRoles(): array;
|
||||
|
||||
public function getEntityData(EntityWorkflow $entityWorkflow, array $options = []): array;
|
||||
|
||||
public function getEntityTitle(EntityWorkflow $entityWorkflow, array $options = []): string;
|
||||
|
||||
public function getRelatedEntity(EntityWorkflow $entityWorkflow): ?object;
|
||||
|
||||
public function getRelatedObjects(object $object): array;
|
||||
|
||||
/**
|
||||
* Return a string representing the role required for seeing the workflow.
|
||||
*
|
||||
@ -33,6 +40,8 @@ interface EntityWorkflowHandlerInterface
|
||||
|
||||
public function getTemplateData(EntityWorkflow $entityWorkflow, array $options = []): array;
|
||||
|
||||
public function isObjectSupported(object $object): bool;
|
||||
|
||||
public function supports(EntityWorkflow $entityWorkflow, array $options = []): bool;
|
||||
|
||||
public function supportsFreeze(EntityWorkflow $entityWorkflow, array $options = []): bool;
|
||||
|
@ -75,3 +75,9 @@ services:
|
||||
$locker: '@Chill\MainBundle\Security\PasswordRecover\PasswordRecoverLocker'
|
||||
tags:
|
||||
- { name: security.voter }
|
||||
|
||||
Chill\MainBundle\Security\Authorization\WorkflowEntityDeletionVoter:
|
||||
autoconfigure: true
|
||||
autowire: true
|
||||
arguments:
|
||||
$handlers: !tagged_iterator chill_main.workflow_handler
|
||||
|
@ -413,6 +413,7 @@ workflow:
|
||||
Previous workflow without reaction help: Liste des workflows où vous avez été cité comme pouvant réagir à une étape, mais où un autre utilisateur a exécuté une action avant vous.
|
||||
Previous transitionned: Anciens workflows
|
||||
Previous workflow transitionned help: Workflows où vous avez exécuté une action.
|
||||
For: Pour
|
||||
|
||||
|
||||
Subscribe final: Recevoir une notification à l'étape finale
|
||||
|
@ -222,6 +222,10 @@ class AccompanyingPeriodController extends AbstractController
|
||||
$accompanyingPeriodsRaw = $this->accompanyingPeriodACLAwareRepository
|
||||
->findByPerson($person, AccompanyingPeriodVoter::SEE);
|
||||
|
||||
usort($accompanyingPeriodsRaw, static function ($a, $b) {
|
||||
return $b->getOpeningDate() > $a->getOpeningDate();
|
||||
});
|
||||
|
||||
// filter visible or not visible
|
||||
$accompanyingPeriods = array_filter($accompanyingPeriodsRaw, function (AccompanyingPeriod $ap) {
|
||||
return $this->isGranted(AccompanyingPeriodVoter::SEE, $ap);
|
||||
|
@ -134,7 +134,7 @@ class HouseholdCompositionController extends AbstractController
|
||||
public function index(Household $household, Request $request): Response
|
||||
{
|
||||
if (!$this->security->isGranted(HouseholdVoter::SEE, $household)) {
|
||||
throw new AccessDeniedException('not allowed to edit an household');
|
||||
throw new AccessDeniedException('not allowed to edit a household');
|
||||
}
|
||||
|
||||
$count = $this->householdCompositionRepository->countByHousehold($household);
|
||||
@ -146,6 +146,20 @@ class HouseholdCompositionController extends AbstractController
|
||||
$paginator->getCurrentPageFirstItemNumber()
|
||||
);
|
||||
|
||||
return new Response($this->engine->render(
|
||||
'@ChillPerson/HouseholdComposition/index.html.twig',
|
||||
[
|
||||
'household' => $household,
|
||||
'compositions' => $compositions,
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{_locale}/person/household/{id}/composition/new", name="chill_person_household_composition_new")
|
||||
*/
|
||||
public function newAction(Household $household, Request $request): Response
|
||||
{
|
||||
if ($this->security->isGranted(HouseholdVoter::EDIT, $household)) {
|
||||
$isEdit = $request->query->has('edit');
|
||||
|
||||
@ -195,10 +209,9 @@ class HouseholdCompositionController extends AbstractController
|
||||
}
|
||||
|
||||
return new Response($this->engine->render(
|
||||
'@ChillPerson/HouseholdComposition/index.html.twig',
|
||||
'@ChillPerson/HouseholdComposition/create.html.twig',
|
||||
[
|
||||
'household' => $household,
|
||||
'compositions' => $compositions,
|
||||
'form' => isset($form) ? $form->createView() : null,
|
||||
'isPosted' => isset($form) ? $form->isSubmitted() : false,
|
||||
'editId' => $request->query->getInt('edit', -1),
|
||||
|
@ -78,6 +78,10 @@ class HouseholdController extends AbstractController
|
||||
}
|
||||
}
|
||||
|
||||
usort($accompanyingPeriods, static function ($a, $b) {
|
||||
return $b->getOpeningDate() > $a->getOpeningDate();
|
||||
});
|
||||
|
||||
$oldMembers = $household->getNonCurrentMembers();
|
||||
$accompanyingPeriodsOld = [];
|
||||
|
||||
|
@ -133,6 +133,19 @@ final class PersonResourceController extends AbstractController
|
||||
$personResources = [];
|
||||
$personResources = $this->personResourceRepository->findBy(['personOwner' => $personOwner->getId()]);
|
||||
|
||||
return $this->render(
|
||||
'ChillPersonBundle:PersonResource:list.html.twig',
|
||||
[
|
||||
'person' => $personOwner,
|
||||
'personResources' => $personResources,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function newAction(Request $request, $person_id)
|
||||
{
|
||||
$personOwner = $this->personRepository->find($person_id);
|
||||
|
||||
$form = $this->createForm(PersonResourceType::class);
|
||||
|
||||
$form->handleRequest($request);
|
||||
@ -165,11 +178,10 @@ final class PersonResourceController extends AbstractController
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
'ChillPersonBundle:PersonResource:list.html.twig',
|
||||
'ChillPersonBundle:PersonResource:create.html.twig',
|
||||
[
|
||||
'person' => $personOwner,
|
||||
'personResources' => $personResources,
|
||||
'form' => $form->createView(),
|
||||
'person' => $personOwner,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use Chill\MainBundle\DependencyInjection\MissingBundleException;
|
||||
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
||||
use Chill\PersonBundle\Controller\HouseholdCompositionTypeApiController;
|
||||
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodCommentVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodResourceVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
@ -415,6 +416,25 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod\Comment::class,
|
||||
'name' => 'accompanying_period_comment',
|
||||
'base_path' => '/api/1.0/person/accompanying-period/comment',
|
||||
'base_role' => 'ROLE_USER',
|
||||
'actions' => [
|
||||
'_entity' => [
|
||||
'methods' => [
|
||||
Request::METHOD_GET => false,
|
||||
Request::METHOD_PATCH => true,
|
||||
Request::METHOD_HEAD => false,
|
||||
Request::METHOD_DELETE => false,
|
||||
],
|
||||
'roles' => [
|
||||
Request::METHOD_PATCH => AccompanyingPeriodCommentVoter::EDIT,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod\Resource::class,
|
||||
'name' => 'accompanying_period_resource',
|
||||
|
@ -257,9 +257,11 @@ class AccompanyingPeriod implements
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(
|
||||
* targetEntity=Comment::class
|
||||
* targetEntity=Comment::class,
|
||||
* cascade={"persist"},
|
||||
* )
|
||||
* @Groups({"read"})
|
||||
* @ORM\JoinColumn(onDelete="SET NULL")
|
||||
*/
|
||||
private ?Comment $pinnedComment = null;
|
||||
|
||||
|
@ -124,6 +124,7 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
||||
/**
|
||||
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
|
||||
* @Serializer\Groups({"read", "docgen:read"})
|
||||
* @Serializer\Groups({"write"})
|
||||
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
|
||||
*/
|
||||
private ?DateTimeImmutable $maxDate = null;
|
||||
|
@ -109,6 +109,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @ORM\OneToMany(targetEntity=AccompanyingPeriodParticipation::class,
|
||||
* mappedBy="person",
|
||||
* cascade={"persist", "remove", "merge", "detach"})
|
||||
* @ORM\OrderBy({"startDate": "DESC"})
|
||||
*/
|
||||
private $accompanyingPeriodParticipations;
|
||||
|
||||
|
@ -98,7 +98,8 @@ class PersonPhone
|
||||
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->getDescription()) && empty($this->getPhonenumber());
|
||||
return ('' === $this->getDescription() || null === $this->getDescription())
|
||||
&& null === $this->getPhonenumber();
|
||||
}
|
||||
|
||||
public function setDate(DateTime $date): void
|
||||
|
@ -62,6 +62,12 @@ class Evaluation
|
||||
*/
|
||||
private array $title = [];
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
* @Serializer\Groups({"read", "docgen:read"})
|
||||
*/
|
||||
private ?string $url = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->socialActions = new ArrayCollection();
|
||||
@ -101,6 +107,11 @@ class Evaluation
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function getUrl(): ?string
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function removeSocialAction(SocialAction $socialAction): self
|
||||
{
|
||||
if ($this->socialActions->contains($socialAction)) {
|
||||
@ -130,4 +141,11 @@ class Evaluation
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUrl(?string $url): self
|
||||
{
|
||||
$this->url = $url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\PersonPhone;
|
||||
use Chill\PersonBundle\Form\Type\GenderType;
|
||||
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
||||
use Chill\PersonBundle\Form\Type\PersonPhoneType;
|
||||
use Chill\PersonBundle\Form\Type\Select2MaritalStatusType;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
@ -158,7 +159,7 @@ class PersonType extends AbstractType
|
||||
}
|
||||
|
||||
$builder->add('otherPhoneNumbers', ChillCollectionType::class, [
|
||||
'entry_type' => ChillPhoneNumberType::class,
|
||||
'entry_type' => PersonPhoneType::class,
|
||||
'button_add_label' => 'Add new phone',
|
||||
'button_remove_label' => 'Remove phone',
|
||||
'required' => false,
|
||||
|
@ -11,11 +11,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Form\Type;
|
||||
|
||||
use Chill\MainBundle\Form\Type\ChillPhoneNumberType;
|
||||
use Chill\MainBundle\Phonenumber\PhonenumberHelper;
|
||||
use Chill\PersonBundle\Entity\PersonPhone;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TelType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
@ -36,7 +36,7 @@ class PersonPhoneType extends AbstractType
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder->add('phonenumber', TelType::class, [
|
||||
$builder->add('phonenumber', ChillPhoneNumberType::class, [
|
||||
'label' => 'Other phonenumber',
|
||||
'required' => true,
|
||||
]);
|
||||
|
@ -33,61 +33,74 @@ div.banner {
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
div.contact {
|
||||
display: flex;
|
||||
align-content: center;
|
||||
& > * {
|
||||
margin-right: 1em;
|
||||
}
|
||||
}
|
||||
.household-link {
|
||||
border: 1px solid white;
|
||||
padding: .05rem .3rem;
|
||||
border-radius: 5px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: white;
|
||||
color: $chill-person-context
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.person-view {
|
||||
figure.person-details {
|
||||
h2 {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.3em;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
dl {
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
dt {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: 600;
|
||||
}
|
||||
dd {
|
||||
margin-left: 0;
|
||||
}
|
||||
/*
|
||||
a.sc-button { background-color: $black; padding-top: 0.2em; padding-bottom: 0.2em; }
|
||||
*/
|
||||
}
|
||||
/* custom fields on the home page */
|
||||
div.custom-fields {
|
||||
figure.person-details {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
div.cf_title_box:nth-child(4n+1) h2 {
|
||||
@extend .chill-red !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+2) h2 {
|
||||
@extend .chill-green !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+3) h2 {
|
||||
@extend .chill-orange !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+4) h2 {
|
||||
@extend .chill-blue !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(2n+1) {
|
||||
width: 50%;
|
||||
margin-right: 40px;
|
||||
}
|
||||
div.cf_title_box:nth-child(2n+2) {
|
||||
width: calc(50% - 40px);
|
||||
}
|
||||
}
|
||||
}
|
||||
figure.person-details {
|
||||
h2 {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.3em;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
dl {
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
dt {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: 600;
|
||||
}
|
||||
dd {
|
||||
margin-left: 0;
|
||||
}
|
||||
/*
|
||||
a.sc-button { background-color: $black; padding-top: 0.2em; padding-bottom: 0.2em; }
|
||||
*/
|
||||
}
|
||||
/* custom fields on the home page */
|
||||
div.custom-fields {
|
||||
figure.person-details {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
div.cf_title_box:nth-child(4n+1) h2 {
|
||||
@extend .chill-red !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+2) h2 {
|
||||
@extend .chill-green !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+3) h2 {
|
||||
@extend .chill-orange !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+4) h2 {
|
||||
@extend .chill-blue !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(2n+1) {
|
||||
width: 50%;
|
||||
margin-right: 40px;
|
||||
}
|
||||
div.cf_title_box:nth-child(2n+2) {
|
||||
width: calc(50% - 40px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -19,22 +19,21 @@ import {fetchResults} from 'ChillMainAssets/lib/api/apiMethods.js';
|
||||
*/
|
||||
|
||||
document.querySelectorAll('[data-set-referrer-app]').forEach(function (el) {
|
||||
let
|
||||
periodId = Number.parseInt(el.dataset.setReferrerAccompanyingPeriodId);
|
||||
|
||||
const periodId = Number.parseInt(el.dataset.setReferrerAccompanyingPeriodId);
|
||||
const jobId = Number.parseInt(el.dataset.setReferrerJobId);
|
||||
const url = `/api/1.0/person/accompanying-course/${periodId}/referrers-suggested.json`;
|
||||
|
||||
fetchResults(url).then(suggested => {
|
||||
|
||||
const filteredSuggested = suggested.filter((s) => s.user_job ? s.user_job.id === jobId : false);
|
||||
const app = createApp({
|
||||
components: {
|
||||
SetReferrer,
|
||||
},
|
||||
template:
|
||||
'<set-referrer :suggested="suggested" :periodId="periodId" @referrerSet="onReferrerSet"></set-referrer>',
|
||||
'<set-referrer :suggested="filteredSuggested" :periodId="periodId" @referrerSet="onReferrerSet"></set-referrer>',
|
||||
data() {
|
||||
return {
|
||||
periodId, suggested, original: suggested,
|
||||
periodId, filteredSuggested, original: filteredSuggested,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -56,7 +55,7 @@ document.querySelectorAll('[data-set-referrer-app]').forEach(function (el) {
|
||||
label.textContent = ref.text;
|
||||
label.classList.remove('chill-no-data-statement');
|
||||
|
||||
this.suggested = this.original.filter(user => user.id !== ref.id);
|
||||
this.filteredSuggested = this.original.filter(user => user.id !== ref.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -14,24 +14,27 @@
|
||||
|
||||
<ckeditor
|
||||
name="content"
|
||||
v-bind:placeholder="$t('comment.content')"
|
||||
:placeholder="$t('comment.content')"
|
||||
:editor="editor"
|
||||
v-model="content"
|
||||
tag-name="textarea">
|
||||
</ckeditor>
|
||||
|
||||
<div v-if="pinnedComment" class="metadata">
|
||||
{{ $t('comment.created_by', [
|
||||
pinnedComment.creator.text,
|
||||
$d(pinnedComment.createdAt.datetime, 'long')
|
||||
]) }}
|
||||
<div class="sub-comment">
|
||||
<div v-if="pinnedComment !== null && typeof pinnedComment.creator !== 'undefined'" class="metadata">
|
||||
{{ $t('comment.created_by', [
|
||||
pinnedComment.creator.text,
|
||||
$d(pinnedComment.updatedAt.datetime, 'long')
|
||||
])
|
||||
}}
|
||||
</div>
|
||||
<div class="loading">
|
||||
<i v-if="loading" class="fa fa-circle-o-notch fa-spin" :title="$t('loading')"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button type="submit" class="btn btn-save">{{ $t('action.save') }}</button>
|
||||
</li>
|
||||
<li v-if="pinnedComment !== null">
|
||||
<a class="btn btn-delete"
|
||||
@click="removeComment">
|
||||
@ -50,6 +53,7 @@
|
||||
<script>
|
||||
import CKEditor from '@ckeditor/ckeditor5-vue';
|
||||
import ClassicEditor from "ChillMainAssets/module/ckeditor5";
|
||||
import { mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "Comment",
|
||||
@ -59,22 +63,58 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
editor: ClassicEditor,
|
||||
formdata: {
|
||||
type: "accompanying_period_comment",
|
||||
content: ''
|
||||
}
|
||||
loading: false,
|
||||
lastRecordedContent: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pinnedComment() {
|
||||
return this.$store.state.accompanyingCourse.pinnedComment;
|
||||
},
|
||||
...mapState({
|
||||
pinnedComment: state => state.accompanyingCourse.pinnedComment,
|
||||
}),
|
||||
content: {
|
||||
set(value) {
|
||||
this.formdata.content = value;
|
||||
console.log('new comment value', value);
|
||||
console.log('previous value', this.lastRecordedContent);
|
||||
this.lastRecordedContent = value;
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('performing test on ', value);
|
||||
if (this.lastRecordedContent === value) {
|
||||
this.loading = true;
|
||||
if (value !== '') {
|
||||
this.$store.dispatch('updatePinnedComment', value)
|
||||
.then(() => {
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
} else {
|
||||
this.$toast.open({message: 'An error occurred'})
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (this.$store.state.accompanyingCourse.pinnedComment !== null) {
|
||||
this.$store.dispatch('removePinnedComment', {id: this.pinnedComment.id})
|
||||
.then(() => {
|
||||
this.loading = false;
|
||||
this.lastRecoredContent = null;
|
||||
})
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
} else {
|
||||
this.$toast.open({message: 'An error occurred'})
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
},
|
||||
get() {
|
||||
return (this.pinnedComment)? this.pinnedComment.content : {};
|
||||
get() {
|
||||
return this.pinnedComment ? this.pinnedComment.content : '';
|
||||
}
|
||||
},
|
||||
errors() {
|
||||
@ -82,18 +122,11 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitform() {
|
||||
this.$store.dispatch('postFirstComment', this.formdata)
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
} else {
|
||||
this.$toast.open({message: 'An error occurred'})
|
||||
}
|
||||
});
|
||||
onContentChange() {
|
||||
let lastRecordedContent = this.formData.content;
|
||||
},
|
||||
removeComment() {
|
||||
this.$store.dispatch('postFirstComment', {})
|
||||
this.$store.dispatch('removePinnedComment', {id: this.pinnedComment.id})
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
@ -104,15 +137,18 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* TODO
|
||||
* - [x] delete button in ul record_actions, but not in form
|
||||
* - [ ] display updatedAt => pinnedComment fetch PATCH content changes MUST NOT change object id !!
|
||||
*/
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
div.ck-editor.ck-reset {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
div.sub-comment {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
div.loading {
|
||||
margin-right: 6px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -59,14 +59,6 @@
|
||||
ref="addAddress">
|
||||
</add-address>
|
||||
</li>
|
||||
<li v-if="isPersonLocation">
|
||||
<button
|
||||
class="btn btn-remove"
|
||||
@click="removeAddress"
|
||||
:title="$t('courselocation.remove_button')">
|
||||
{{ $t('action.remove') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -180,22 +172,6 @@ export default {
|
||||
}
|
||||
this.$store.commit('setAddressContext', context);
|
||||
},
|
||||
removeAddress() {
|
||||
let payload = {
|
||||
target: this.context.target.name,
|
||||
targetId: this.context.target.id,
|
||||
locationStatusTo: 'none'
|
||||
};
|
||||
//console.log('remove address');
|
||||
this.$store.dispatch('updateLocation', payload)
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
} else {
|
||||
this.$toast.open({message: 'An error occurred'})
|
||||
}
|
||||
});
|
||||
},
|
||||
displayErrors() {
|
||||
return this.$refs.addAddress.errorMsg;
|
||||
},
|
||||
|
@ -9,7 +9,7 @@
|
||||
<input type="checkbox" v-model="requestorIsAnonymous" class="me-2" />
|
||||
{{ $t('requestor.is_anonymous') }}
|
||||
</label>
|
||||
<confidential :positionBtn="false" v-if="accompanyingCourse.requestor.type === 'thirdparty'">
|
||||
<confidential v-if="accompanyingCourse.requestor.type === 'thirdparty'">
|
||||
<template v-slot:confidential-content>
|
||||
<third-party-render-box
|
||||
:thirdparty="accompanyingCourse.requestor"
|
||||
@ -33,7 +33,7 @@
|
||||
</template>
|
||||
</confidential>
|
||||
|
||||
<confidential :positionBtnFar="false" v-else-if="accompanyingCourse.requestor.type === 'person'">
|
||||
<confidential v-else-if="accompanyingCourse.requestor.type === 'person'">
|
||||
<template v-slot:confidential-content>
|
||||
<person-render-box render="bloc"
|
||||
:person="accompanyingCourse.requestor"
|
||||
@ -339,5 +339,6 @@ div.flex-table {
|
||||
|
||||
.confidential {
|
||||
display: block;
|
||||
margin-right: 0px !important;
|
||||
}
|
||||
</style>
|
||||
|
@ -170,7 +170,9 @@ export default {
|
||||
console.log('data', payload.data)
|
||||
body.name = payload.data.name;
|
||||
body.email = payload.data.email;
|
||||
body.telephone = payload.data.phonenumber;
|
||||
body.telephone = payload.data.telephone;
|
||||
body.civility = payload.data.civility;
|
||||
body.profession = payload.data.profession;
|
||||
body.address = payload.data.address ? { id: payload.data.address.address_id } : null;
|
||||
|
||||
makeFetch('PATCH', `/api/1.0/thirdparty/thirdparty/${payload.data.id}.json`, body)
|
||||
|
@ -122,7 +122,7 @@ const appMessages = {
|
||||
title: "Observations",
|
||||
label: "Ajout d'une note",
|
||||
content: "Rédigez une première note…",
|
||||
created_by: "créé par {0}, le {1}"
|
||||
created_by: "créé par {0}, mis à jour le {1}"
|
||||
},
|
||||
confirm: {
|
||||
title: "Confirmation",
|
||||
|
@ -42,7 +42,11 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
|
||||
referrersSuggested: [],
|
||||
// all the users available
|
||||
users: [],
|
||||
permissions: {}
|
||||
permissions: {},
|
||||
// controller for updating comment
|
||||
updateCommentAbortController: null,
|
||||
// waiting response for inserting first comment
|
||||
postFirstPinnedCommentResponse: null,
|
||||
},
|
||||
getters: {
|
||||
isParticipationValid(state) {
|
||||
@ -203,9 +207,35 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
|
||||
//console.log('### mutation: toggleConfidential');
|
||||
state.accompanyingCourse.confidential = value;
|
||||
},
|
||||
postFirstComment(state, comment) {
|
||||
//console.log('### mutation: postFirstComment', comment);
|
||||
state.accompanyingCourse.pinnedComment = comment;
|
||||
setPinnedComment(state, content) {
|
||||
if (null === state.accompanyingCourse.pinnedComment) {
|
||||
state.accompanyingCourse.pinnedComment = {
|
||||
id: -1,
|
||||
content,
|
||||
type: "accompanying_period_comment",
|
||||
};
|
||||
} else {
|
||||
state.accompanyingCourse.pinnedComment.content = content;
|
||||
}
|
||||
},
|
||||
setPinnedCommentDetails(state, value) {
|
||||
state.accompanyingCourse.pinnedComment.id = value.id;
|
||||
if (typeof value.creator !== 'undefined') {
|
||||
state.accompanyingCourse.pinnedComment.creator = value.creator;
|
||||
state.accompanyingCourse.pinnedComment.updatedBy = value.updatedBy;
|
||||
state.accompanyingCourse.pinnedComment.updatedAt = value.updatedAt;
|
||||
state.accompanyingCourse.pinnedComment.createdAt = value.createdAt;
|
||||
|
||||
}
|
||||
},
|
||||
removePinnedComment(state, value) {
|
||||
state.accompanyingCourse.pinnedComment = null;
|
||||
},
|
||||
setPinCommentAbortController(state, value) {
|
||||
state.updateCommentAbortController = value;
|
||||
},
|
||||
setPostFirstPinnedCommentResponse(state, value) {
|
||||
state.postFirstPinnedCommentResponse = value;
|
||||
},
|
||||
updateSocialIssues(state, value) {
|
||||
console.log('updateSocialIssues', value);
|
||||
@ -337,6 +367,87 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Add/remove pinnedComment
|
||||
*/
|
||||
removePinnedComment({ commit }, payload) {
|
||||
const body = {type: "accompanying_period_comment", id: payload.id};
|
||||
const url = `/api/1.0/person/accompanying-course/${id}/comment.json`;
|
||||
|
||||
return makeFetch('DELETE', url, body)
|
||||
.then((response) => {
|
||||
commit('removePinnedComment');
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* internal method to insert a new comment
|
||||
*
|
||||
* @param commit
|
||||
* @param dispatch
|
||||
* @param content
|
||||
* @returns {*}
|
||||
*/
|
||||
addPinnedComment({ commit, dispatch }, content) {
|
||||
const url = `/api/1.0/person/accompanying-course/${id}/comment.json`;
|
||||
|
||||
return makeFetch('POST', url, {type: "accompanying_period_comment", content})
|
||||
.then((response) => {
|
||||
commit('setPinnedCommentDetails', response);
|
||||
return dispatch('patchFirstComment', response);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
updatePinnedComment({ commit, state, dispatch }, content) {
|
||||
commit('setPinnedComment', content);
|
||||
if (state.accompanyingCourse.pinnedComment.id === -1 && state.postFirstPinnedCommentResponse === null) {
|
||||
let r = dispatch('addPinnedComment', content).then(() => {
|
||||
commit('setPostFirstPinnedCommentResponse', null);
|
||||
});
|
||||
commit('setPostFirstPinnedCommentResponse', r);
|
||||
} else {
|
||||
(state.postFirstPinnedCommentResponse === null ? Promise.resolve() : state.postFirstPinnedCommentResponse).then(() => {
|
||||
dispatch('updateExistingPinnedComment', content);
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* internal method to patch an existing comment
|
||||
*
|
||||
* @param commit
|
||||
* @param state
|
||||
* @param comment
|
||||
* @returns {*}
|
||||
*/
|
||||
updateExistingPinnedComment({ commit, state }, content) {
|
||||
const payload = {type: "accompanying_period_comment", content, id: state.accompanyingCourse.pinnedComment.id};
|
||||
const url = `/api/1.0/person/accompanying-period/comment/${payload.id}.json`;
|
||||
|
||||
if (state.updateCommentAbortController !== null) {
|
||||
state.updateCommentAbortController.abort();
|
||||
commit('setPinCommentAbortController', null);
|
||||
}
|
||||
|
||||
let controller = new AbortController();
|
||||
commit('setPinCommentAbortController', controller);
|
||||
|
||||
return makeFetch('PATCH', url, payload, { signal: controller.signal })
|
||||
.then((response) => {
|
||||
commit('setPinCommentAbortController', null);
|
||||
commit('setPinnedCommentDetails', response);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
commit('setPinCommentAbortController', null);
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Add/remove/display anonymous requestor
|
||||
*/
|
||||
@ -606,18 +717,20 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
|
||||
|
||||
return Promise.all(promises);
|
||||
},
|
||||
postFirstComment({ commit }, payload) {
|
||||
const url = `/api/1.0/person/accompanying-course/${id}.json`
|
||||
const body = { type: "accompanying_period", pinnedComment: payload }
|
||||
|
||||
patchFirstComment({ commit }, payload) {
|
||||
const url = `/api/1.0/person/accompanying-course/${id}.json`;
|
||||
const body = {
|
||||
type: "accompanying_period",
|
||||
pinnedComment: {
|
||||
type: "accompanying_period_comment",
|
||||
id: payload.id
|
||||
}
|
||||
};
|
||||
return makeFetch('PATCH', url, body)
|
||||
.then((response) => {
|
||||
commit('postFirstComment', response.pinnedComment);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
});
|
||||
},
|
||||
updateSocialIssues({ state, commit, dispatch }, { payload, body, method }) {
|
||||
const url = `/api/1.0/person/accompanying-course/${id}/socialissue.json`;
|
||||
|
@ -5,6 +5,11 @@
|
||||
<span>{{ evaluation.evaluation.title.fr }}</span>
|
||||
</div>
|
||||
|
||||
<div class="item-url mt-3 mb-4" v-if="evaluation.evaluation.url">
|
||||
<i class="fa fa-link fa-lg"></i>
|
||||
<a :href="evaluation.evaluation.url" target="_blank">{{ evaluation.evaluation.url }}</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<form-evaluation ref="FormEvaluation" :key="evaluation.key" :evaluation="evaluation"></form-evaluation>
|
||||
|
||||
@ -21,7 +26,7 @@
|
||||
></list-workflow-modal>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<li v-if="canDelete">
|
||||
<a class="btn btn-delete" @click="modal.showModal = true" :title="$t('action.delete')"></a>
|
||||
</li>
|
||||
</ul>
|
||||
@ -93,6 +98,19 @@ export default {
|
||||
pickedEvaluations() {
|
||||
return this.$store.state.evaluationsPicked;
|
||||
},
|
||||
canDelete() {
|
||||
if (this.evaluation.workflows.length > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let doc of this.evaluation.documents) {
|
||||
if (doc.workflows.length > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
removeEvaluation(e) {
|
||||
@ -128,4 +146,11 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
div.item-url {
|
||||
i {
|
||||
color: unset!important;
|
||||
margin-left: 1rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -101,7 +101,7 @@
|
||||
<li>
|
||||
<a :href="buildEditLink(d.storedObject)" class="btn btn-wopilink"></a>
|
||||
</li>
|
||||
<li>
|
||||
<li v-if="d.workflows.length === 0">
|
||||
<a class="btn btn-delete" @click="removeDocument(d)">
|
||||
</a>
|
||||
</li>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<ul class="list-suggest add-items" v-if="suggested.length > 0">
|
||||
<li v-for="r in suggested" @click="setReferrer(r)"><span>{{ r.text }}</span></li>
|
||||
<li v-for="(r, i) in suggested" @click="setReferrer(r)" :key="i"><span>{{ r.text }}</span></li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {makeFetch} from 'ChillMainAssets/lib/api/apiMethods.js';
|
||||
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods.js';
|
||||
|
||||
export default {
|
||||
name: "SetReferrer",
|
||||
|
@ -87,10 +87,14 @@ export default {
|
||||
currentMembers() {
|
||||
let members = this.household.members.filter(m => this.household.current_members_id.includes(m.id))
|
||||
.sort((a, b) => {
|
||||
if (a.position.ordering < b.position.ordering) {
|
||||
|
||||
const orderA = a.position ? a.position.ordering : 0;
|
||||
const orderB = b.position ? b.position.ordering : 0;
|
||||
|
||||
if (orderA < orderB) {
|
||||
return -1;
|
||||
}
|
||||
if (a.position.ordering > b.position.ordering) {
|
||||
if (orderA > orderB) {
|
||||
return 1;
|
||||
}
|
||||
if (a.holder && !b.holder) {
|
||||
|
@ -130,11 +130,13 @@
|
||||
href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_edit', { 'id': w.id }) }}"
|
||||
></a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-delete" title="{{ 'Delete'|trans }}"
|
||||
href="{{ path('chill_person_accompanying_period_work_delete', { 'id': w.id } ) }}"
|
||||
></a>
|
||||
</li>
|
||||
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_DELETE', w) %}
|
||||
<li>
|
||||
<a class="btn btn-delete" title="{{ 'Delete'|trans }}"
|
||||
href="{{ path('chill_person_accompanying_period_work_delete', { 'id': w.id } ) }}"
|
||||
></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -117,12 +117,15 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="item-row separator">
|
||||
<div class="item-col item-meta">
|
||||
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) %}
|
||||
{% if notif_counter.total > 0 %}
|
||||
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) %}
|
||||
{% if notif_counter.total > 0 %}
|
||||
<div class="item-col item-meta">
|
||||
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if itemMeta is defined %}
|
||||
{{ itemMeta }}
|
||||
{% endif %}
|
||||
<div class="item-col">
|
||||
{% if recordAction is defined %}
|
||||
<ul class="record_actions">
|
||||
|
@ -167,7 +167,7 @@
|
||||
<span class="chill-no-data-statement">{{ 'No data given'|trans }}</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if person.email is not null %}
|
||||
{% if person.email is not empty %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-envelope-o"></i><a href="{{ 'mailto:' ~ person.email }}">
|
||||
{{ person.email }}
|
||||
|
@ -0,0 +1,26 @@
|
||||
{% extends '@ChillPerson/Household/layout.html.twig' %}
|
||||
|
||||
{% block title 'household_composition.create'|trans %}
|
||||
|
||||
{% block block_post_menu %}
|
||||
<div class="post-menu"></div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ 'household_composition.Create'|trans }}</h1>
|
||||
|
||||
<div>
|
||||
{{ form_start(form) }}
|
||||
|
||||
{{ form_widget(form) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button type="submit" class="btn btn-create">{{ 'Save'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -15,7 +15,7 @@
|
||||
{% else %}
|
||||
<div class="flex-table">
|
||||
{% for c in compositions %}
|
||||
{% if c.id != editId %}
|
||||
{# {% if c.id != editId %} #}
|
||||
<div class="item-bloc">
|
||||
<div class="item-row">
|
||||
<div class="item-col">
|
||||
@ -42,7 +42,7 @@
|
||||
<div class="item-row">
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('chill_person_household_composition_index', {'id': c.household.id, 'edit': c.id}) }}" class="btn btn-edit"></a>
|
||||
<a href="{{ path('chill_person_household_composition_new', {'id': c.household.id, 'edit': c.id}) }}" class="btn btn-edit"></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_composition_delete', {'composition_id': c.id,
|
||||
@ -54,45 +54,17 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ form_start(form) }}
|
||||
|
||||
{{ form_widget(form) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li class="cancel" style="margin-right: auto;">
|
||||
<a class="btn btn-cancel" href="{{ path('chill_person_household_composition_index', {'id': c.household.id}) }}">{{ 'Cancel'|trans }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<button type="submit" class="btn btn-create">{{ 'Save'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(form) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="collapseForm" class="{% if not isPosted %}collapse{% endif %}">
|
||||
{{ form_start(form) }}
|
||||
|
||||
{{ form_widget(form) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button type="submit" class="btn btn-create">{{ 'Save'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
|
||||
{% if editId == -1 %}
|
||||
{% if is_granted('CHILL_PERSON_HOUSEHOLD_EDIT', household) %}
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
<button class="btn btn-primary btn-create change-icon" type="button" data-bs-toggle="collapse" data-bs-target="#collapseForm" aria-expanded="false" aria-controls="collapseForm">
|
||||
{{ 'Create'|trans }}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_composition_new', {'id': household.id,}) }}"
|
||||
class="btn btn-new"
|
||||
title="{{ 'Create'|trans }}">{{ 'Create'|trans }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -58,6 +58,13 @@
|
||||
}) }}
|
||||
</span>
|
||||
{%- endif -%}
|
||||
{% if person.getCurrentHousehold is not null %}
|
||||
<span>
|
||||
<a class="household-link" href="{{ chill_path_add_return_path('chill_person_household_summary', { 'household_id' : person.getCurrentHousehold.id } ) }}">
|
||||
<i class="fa fa-home"></i>
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -1,15 +1,25 @@
|
||||
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||
|
||||
{% set activeRouteKey = 'chill_person_resource_list' %}
|
||||
|
||||
{% block title %}{{ 'Person resources'|trans|capitalize ~ ' ' ~ person|chill_entity_render_string }}{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags('page_person_resource_showhide_input') }}
|
||||
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('page_person_resource_showhide_input') }}
|
||||
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block personcontent %}
|
||||
|
||||
<h1 style="margin-bottom: 2rem;">{{ 'Add a person resource'|trans }}</h1>
|
||||
|
||||
<div class="col-md col-xxl">
|
||||
<div id="collapseForm" class="{% if not form.vars.submitted %}collapse{% endif %}">
|
||||
<h3 style="margin-bottom: 2rem;">{{ 'Add a person resource'|trans }}</h3>
|
||||
{% include "@ChillPerson/PersonResource/form.html.twig" %}
|
||||
</div>
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
<button class="btn btn-primary btn-create change-icon" type="button" data-bs-toggle="collapse" data-bs-target="#collapseForm" aria-expanded="false" aria-controls="collapseForm">
|
||||
{{ 'Add a person resource'|trans }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -85,8 +85,14 @@
|
||||
<p class="chill-no-data-statement">{{ 'There are no available resources'|trans }}</p>
|
||||
{% endif %}
|
||||
|
||||
<h1 style="margin-bottom: 2rem;">{{ 'Add a person resource'|trans }}</h1>
|
||||
|
||||
{% include "@ChillPerson/PersonResource/create.html.twig" %}
|
||||
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_resource_new', {'person_id': person.id,}) }}"
|
||||
class="btn btn-new"
|
||||
title="{{ 'Create'|trans }}">{{ 'Create'|trans }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
@ -49,7 +49,12 @@
|
||||
<li>
|
||||
<i class="fa fa-li fa-home"></i>
|
||||
<span class="item-key">{{ "Address of"|trans}} </span>
|
||||
<span class="chill-entity entity-person badge-person">{{ a.hostPerson|chill_entity_render_box }}</span>
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: 'person', id: a.hostPerson.id },
|
||||
buttonText: a.hostPerson|chill_entity_render_string,
|
||||
isDead: a.hostPerson.deathdate is not null
|
||||
} %}
|
||||
</li>
|
||||
<li>
|
||||
{% set address_date = date(a.startDate|date("m/d/Y")) %}
|
||||
@ -62,7 +67,12 @@
|
||||
<li>
|
||||
<i class="fa fa-li fa-home"></i>
|
||||
<span class="item-key">{{ "Address of"|trans}}</span>
|
||||
<span class="chill-entity entity-person badge-thirdparty">{{ a.hostThirdParty|chill_entity_render_box }}</span>
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: 'thirdparty', id: a.hostThirdParty.id },
|
||||
buttonText: a.hostThirdParty|chill_entity_render_string,
|
||||
isDead: false,
|
||||
} %}
|
||||
</li>
|
||||
<li>
|
||||
{% if a.hostThirdParty.address is not null %}
|
||||
|
@ -24,6 +24,8 @@ class AccompanyingPeriodWorkVoter extends Voter
|
||||
{
|
||||
public const CREATE = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_CREATE';
|
||||
|
||||
public const DELETE = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_DELETE';
|
||||
|
||||
public const SEE = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_SEE';
|
||||
|
||||
public const UPDATE = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE';
|
||||
@ -60,6 +62,7 @@ class AccompanyingPeriodWorkVoter extends Voter
|
||||
|
||||
case self::CREATE:
|
||||
case self::UPDATE:
|
||||
case self::DELETE:
|
||||
return $this->security->isGranted(AccompanyingPeriodVoter::EDIT, $subject->getAccompanyingPeriod());
|
||||
|
||||
default:
|
||||
@ -86,6 +89,6 @@ class AccompanyingPeriodWorkVoter extends Voter
|
||||
|
||||
private function getRoles(): array
|
||||
{
|
||||
return [self::SEE, self::CREATE, self::UPDATE];
|
||||
return [self::SEE, self::CREATE, self::UPDATE, self::DELETE];
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Serializer\Normalizer;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||
@ -46,7 +47,10 @@ class AccompanyingPeriodWorkEvaluationNormalizer implements ContextAwareNormaliz
|
||||
{
|
||||
$initial = $this->normalizer->normalize($object, $format, array_merge(
|
||||
$context,
|
||||
[self::IGNORE_EVALUATION => spl_object_hash($object)]
|
||||
[self::IGNORE_EVALUATION => spl_object_hash($object)],
|
||||
[AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => static function ($object, $format, $context) {
|
||||
return $object->getId();
|
||||
}]
|
||||
));
|
||||
|
||||
// due to bug: https://api-platform.com/docs/core/serialization/#collection-relation
|
||||
|
@ -179,7 +179,8 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
||||
$doc = new AccompanyingPeriodWorkEvaluationDocument();
|
||||
$doc->setStoredObject($storedObject)
|
||||
->setAccompanyingPeriodWorkEvaluation($entity)
|
||||
->setTemplate($template);
|
||||
->setTemplate($template)
|
||||
->setTitle($this->translatableStringHelper->localize($template->getName()));
|
||||
$this->em->persist($doc);
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,13 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function getDeletionRoles(): array
|
||||
{
|
||||
return [
|
||||
'_',
|
||||
];
|
||||
}
|
||||
|
||||
public function getEntityData(EntityWorkflow $entityWorkflow, array $options = []): array
|
||||
{
|
||||
$doc = $this->getRelatedEntity($entityWorkflow);
|
||||
@ -63,6 +70,18 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
|
||||
return $this->repository->find($entityWorkflow->getRelatedEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingPeriodWorkEvaluationDocument $object
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
{
|
||||
return [
|
||||
['entityClass' => AccompanyingPeriodWorkEvaluationDocument::class, $object->getId()],
|
||||
];
|
||||
}
|
||||
|
||||
public function getRoleShow(EntityWorkflow $entityWorkflow): ?string
|
||||
{
|
||||
return AccompanyingPeriodWorkEvaluationDocumentVoter::SEE;
|
||||
@ -84,6 +103,11 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
|
||||
];
|
||||
}
|
||||
|
||||
public function isObjectSupported(object $object): bool
|
||||
{
|
||||
return $object instanceof AccompanyingPeriodWorkEvaluationDocument;
|
||||
}
|
||||
|
||||
public function supports(EntityWorkflow $entityWorkflow, array $options = []): bool
|
||||
{
|
||||
return $entityWorkflow->getRelatedEntityClass() === AccompanyingPeriodWorkEvaluationDocument::class;
|
||||
|
@ -15,6 +15,7 @@ use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkEvaluationVoter;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
@ -37,6 +38,11 @@ class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowH
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function getDeletionRoles(): array
|
||||
{
|
||||
return ['_'];
|
||||
}
|
||||
|
||||
public function getEntityData(EntityWorkflow $entityWorkflow, array $options = []): array
|
||||
{
|
||||
$evaluation = $this->getRelatedEntity($entityWorkflow);
|
||||
@ -61,6 +67,21 @@ class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowH
|
||||
return $this->repository->find($entityWorkflow->getRelatedEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingPeriodWorkEvaluation $object
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
{
|
||||
$relateds = [];
|
||||
$relateds[] = ['entityClass' => AccompanyingPeriodWorkEvaluation::class, 'entityId' => $object->getId()];
|
||||
|
||||
foreach ($object->getDocuments() as $doc) {
|
||||
$relateds[] = ['entityClass' => AccompanyingPeriodWorkEvaluationDocument::class, 'entityId' => $doc->getId()];
|
||||
}
|
||||
|
||||
return $relateds;
|
||||
}
|
||||
|
||||
public function getRoleShow(EntityWorkflow $entityWorkflow): ?string
|
||||
{
|
||||
return AccompanyingPeriodWorkEvaluationVoter::SEE;
|
||||
@ -79,6 +100,11 @@ class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowH
|
||||
];
|
||||
}
|
||||
|
||||
public function isObjectSupported(object $object): bool
|
||||
{
|
||||
return $object instanceof AccompanyingPeriodWorkEvaluation;
|
||||
}
|
||||
|
||||
public function supports(EntityWorkflow $entityWorkflow, array $options = []): bool
|
||||
{
|
||||
return $entityWorkflow->getRelatedEntityClass() === AccompanyingPeriodWorkEvaluation::class;
|
||||
|
@ -15,7 +15,10 @@ use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkVoter;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInterface
|
||||
@ -36,6 +39,11 @@ class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInte
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function getDeletionRoles(): array
|
||||
{
|
||||
return [AccompanyingPeriodWorkVoter::DELETE];
|
||||
}
|
||||
|
||||
public function getEntityData(EntityWorkflow $entityWorkflow, array $options = []): array
|
||||
{
|
||||
return [
|
||||
@ -58,6 +66,25 @@ class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInte
|
||||
return $this->repository->find($entityWorkflow->getRelatedEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccompanyingPeriodWork $object
|
||||
*/
|
||||
public function getRelatedObjects(object $object): array
|
||||
{
|
||||
$relateds = [];
|
||||
$relateds[] = ['entityClass' => AccompanyingPeriodWork::class, 'entityId' => $object->getId()];
|
||||
|
||||
foreach ($object->getAccompanyingPeriodWorkEvaluations() as $evaluation) {
|
||||
$relateds[] = ['entityClass' => AccompanyingPeriodWorkEvaluation::class, 'entityId' => $evaluation->getId()];
|
||||
|
||||
foreach ($evaluation->getDocuments() as $doc) {
|
||||
$relateds[] = ['entityClass' => AccompanyingPeriodWorkEvaluationDocument::class, 'entityId' => $doc->getId()];
|
||||
}
|
||||
}
|
||||
|
||||
return $relateds;
|
||||
}
|
||||
|
||||
public function getRoleShow(EntityWorkflow $entityWorkflow): ?string
|
||||
{
|
||||
return null;
|
||||
@ -76,6 +103,11 @@ class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInte
|
||||
];
|
||||
}
|
||||
|
||||
public function isObjectSupported(object $object): bool
|
||||
{
|
||||
return $object instanceof AccompanyingPeriodWork;
|
||||
}
|
||||
|
||||
public function supports(EntityWorkflow $entityWorkflow, array $options = []): bool
|
||||
{
|
||||
return $entityWorkflow->getRelatedEntityClass() === AccompanyingPeriodWork::class;
|
||||
|
@ -59,6 +59,10 @@ chill_person_resource_list:
|
||||
path: /{_locale}/person/{person_id}/resources/list
|
||||
controller: Chill\PersonBundle\Controller\PersonResourceController::listAction
|
||||
|
||||
chill_person_resource_new:
|
||||
path: /{_locale}/person/{person_id}/resources/new
|
||||
controller: Chill\PersonBundle\Controller\PersonResourceController::newAction
|
||||
|
||||
chill_person_resource_edit:
|
||||
path: /{_locale}/person/{person_id}/resources/{resource_id}/edit
|
||||
controller: Chill\PersonBundle\Controller\PersonResourceController::editAction
|
||||
|
@ -0,0 +1,37 @@
|
||||
<?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\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Add url to SocialWork Evaluation.
|
||||
*/
|
||||
final class Version20220303113855 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_social_work_evaluation DROP url');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add url to SocialWork Evaluation';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_social_work_evaluation ADD url TEXT DEFAULT NULL');
|
||||
$this->addSql("UPDATE chill_person_social_work_evaluation SET url = CASE WHEN title->>'fr' LIKE 'http%' THEN title->>'fr' ELSE null END;");
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?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\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Change constraint on pinnedComment in Accompanying period.
|
||||
*/
|
||||
final class Version20220310124318 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period DROP CONSTRAINT fk_e260a868b0804e90');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT fk_e260a868b0804e90 FOREIGN KEY (pinnedcomment_id) REFERENCES chill_person_accompanying_period_comment (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Change constraint on pinnedComment in Accompanying period';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period DROP CONSTRAINT FK_E260A868B0804E90');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT FK_E260A868B0804E90 FOREIGN KEY (pinnedComment_id) REFERENCES chill_person_accompanying_period_comment (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
}
|
||||
}
|
@ -124,8 +124,8 @@ address_country_code: Code pays
|
||||
|
||||
'Alreay existing person': 'Dossiers déjà encodés'
|
||||
'Add the person': 'Ajouter la personne'
|
||||
'Add the person and create an accompanying period': "Créer la personne & créer une période d'accompagnement"
|
||||
'Add the person and create a household': "Créer la personne & créer un ménage"
|
||||
'Add the person and create an accompanying period': "Créer l'usager ET créer une période d'accompagnement"
|
||||
'Add the person and create a household': "Créer l'usager' ET créer un ménage"
|
||||
Show person: Voir le dossier de la personne
|
||||
'Confirm the creation': 'Confirmer la création'
|
||||
'You will create this person': 'Vous allez créer le dossier suivant'
|
||||
@ -566,6 +566,7 @@ household_composition:
|
||||
Currently no composition: Aucune composition familiale renseignée.
|
||||
Add a composition: Ajouter une composition familiale
|
||||
Update composition: Modifier la composition familiale
|
||||
Create: Créér une nouvelle composition familiale
|
||||
|
||||
# docgen
|
||||
Linked evaluations: Évaluations associées
|
||||
|
@ -46,6 +46,7 @@ User: Utilisateur
|
||||
"Associated tasks": "Tâches associées"
|
||||
"My tasks": "Mes tâches"
|
||||
"Tasks for this accompanying period": "Tâches pour ce parcours d'accompagnement"
|
||||
"Tasks for {{ name }}": "Tâches pour {{ name }}"
|
||||
"No description": "Pas de description"
|
||||
"No dates specified": "Dates non spécifiées"
|
||||
"No one assignee": "Aucune personne assignée"
|
||||
|
@ -20,6 +20,7 @@ use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use Chill\ThirdPartyBundle\Repository\ThirdPartyACLAwareRepositoryInterface;
|
||||
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
|
||||
use LogicException;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
@ -31,37 +32,39 @@ use function array_merge;
|
||||
|
||||
final class ThirdPartyController extends CRUDController
|
||||
{
|
||||
/**
|
||||
* @var AuthorizationHelper
|
||||
*/
|
||||
protected $authorizationHelper;
|
||||
protected AuthorizationHelper $authorizationHelper;
|
||||
|
||||
/**
|
||||
* @var PaginatorFactory
|
||||
*/
|
||||
protected $paginatorFactory;
|
||||
protected PaginatorFactory $paginatorFactory;
|
||||
|
||||
protected RequestStack $requestStack;
|
||||
|
||||
protected ThirdPartyACLAwareRepositoryInterface $thirdPartyACLAwareRepository;
|
||||
|
||||
/**
|
||||
* @var TranslatorInterface
|
||||
*/
|
||||
protected $translator;
|
||||
protected TranslatorInterface $translator;
|
||||
|
||||
private bool $askCenter;
|
||||
|
||||
public function __construct(
|
||||
AuthorizationHelper $authorizationHelper,
|
||||
TranslatorInterface $translator,
|
||||
PaginatorFactory $paginatorFactory,
|
||||
RequestStack $requestStack,
|
||||
ThirdPartyACLAwareRepositoryInterface $thirdPartyACLAwareRepository
|
||||
ThirdPartyACLAwareRepositoryInterface $thirdPartyACLAwareRepository,
|
||||
ParameterBagInterface $parameterBag
|
||||
) {
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
$this->translator = $translator;
|
||||
$this->paginatorFactory = $paginatorFactory;
|
||||
$this->requestStack = $requestStack;
|
||||
$this->thirdPartyACLAwareRepository = $thirdPartyACLAwareRepository;
|
||||
$this->askCenter = $parameterBag->get('chill_main')['acl']['form_show_centers'];
|
||||
}
|
||||
|
||||
public function generateTemplateParameter(string $action, $entity, Request $request, array $defaultTemplateParameters = [])
|
||||
{
|
||||
$defaultTemplateParameters['askCenter'] = $this->askCenter;
|
||||
|
||||
return $defaultTemplateParameters;
|
||||
}
|
||||
|
||||
protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper
|
||||
|
@ -36,7 +36,7 @@
|
||||
<ul class="list-content fa-ul">
|
||||
<li v-if="getProfession.length > 0">
|
||||
<i class="fa fa-li fa-id-card"></i>
|
||||
<p><span v-for="p in getProfession" :key="p" class="list-item">{{ p[0].toUpperCase() + p.slice(1).toLowerCase() }}</span></p>
|
||||
<p><span v-for="p in getProfession" :key="p" class="list-item list-professions">{{ p[0].toUpperCase() + p.slice(1).toLowerCase() }}</span></p>
|
||||
</li>
|
||||
<li v-if="hasParent">
|
||||
<i class="fa fa-li fa-hand-o-right"></i>
|
||||
@ -61,9 +61,9 @@
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
<address-render-box :address="thirdparty.address" :isMultiline="isMultiline"></address-render-box>
|
||||
</li>
|
||||
<li v-if="thirdparty.phonenumber">
|
||||
<li v-if="thirdparty.telephone">
|
||||
<i class="fa fa-li fa-mobile"></i>
|
||||
<a :href="'tel: ' + thirdparty.phonenumber">{{ thirdparty.phonenumber }}</a>
|
||||
<a :href="'tel: ' + thirdparty.telephone">{{ thirdparty.telephone }}</a>
|
||||
</li>
|
||||
<li v-if="thirdparty.email">
|
||||
<i class="fa fa-li fa-envelope-o"></i>
|
||||
@ -78,9 +78,9 @@
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
<address-render-box :address="thirdparty.address" :isMultiline="isMultiline"></address-render-box>
|
||||
</li>
|
||||
<li v-if="thirdparty.phonenumber">
|
||||
<li v-if="thirdparty.telephone">
|
||||
<i class="fa fa-li fa-mobile"></i>
|
||||
<a :href="'tel: ' + thirdparty.phonenumber">{{ thirdparty.phonenumber }}</a>
|
||||
<a :href="'tel: ' + thirdparty.telephone">{{ thirdparty.telephone }}</a>
|
||||
</li>
|
||||
<li v-if="thirdparty.email">
|
||||
<i class="fa fa-li fa-envelope-o"></i>
|
||||
@ -165,7 +165,7 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.list-item {
|
||||
.list-professions {
|
||||
&::after {
|
||||
content: " | ";
|
||||
}
|
||||
|
@ -118,7 +118,7 @@
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-text" id="phonenumber"><i class="fa fa-fw fa-phone"></i></span>
|
||||
<input class="form-control form-control-lg"
|
||||
v-model="thirdparty.phonenumber"
|
||||
v-model="thirdparty.telephone"
|
||||
v-bind:placeholder="$t('thirdparty.phonenumber')"
|
||||
v-bind:aria-label="$t('thirdparty.phonenumber')"
|
||||
aria-describedby="phonenumber" />
|
||||
|
@ -13,7 +13,7 @@
|
||||
<h1>
|
||||
{{ title_ }}
|
||||
<span class="badge bg-{{ thirdParty.active ? 'success' : 'danger' }} float-end"
|
||||
title="{{ (thirdParty.active ? 'shown to users' : 'not shown to users')|trans }}">
|
||||
title="{{ (thirdParty.active ? 'shown to users' : 'not shown to users')|trans }}">
|
||||
{{ (thirdParty.active ? 'Active' : 'Inactive')|trans }}
|
||||
</span>
|
||||
</h1>
|
||||
@ -123,19 +123,20 @@
|
||||
</dd>
|
||||
{% endif %}
|
||||
|
||||
<dt>{{ 'Centers'|trans }}</dt>
|
||||
<dd>
|
||||
{% set centers = thirdParty|chill_resolve_center %}
|
||||
{% if centers is iterable %}
|
||||
{{ 'The party is visible in those centers'|trans }} :
|
||||
{{ centers|join(', ') }}
|
||||
{% elseif centers is null %}
|
||||
{{ 'The party is not visible in any center'|trans }}
|
||||
{% else %}
|
||||
{{ 'The party is visible in those centers'|trans }} : {{ centers }}
|
||||
{% endif %}
|
||||
</dd>
|
||||
|
||||
{% if askCenter %}
|
||||
<dt>{{ 'Centers'|trans }}</dt>
|
||||
<dd>
|
||||
{% set centers = thirdParty|chill_resolve_center %}
|
||||
{% if centers is iterable %}
|
||||
{{ 'The party is visible in those centers'|trans }} :
|
||||
{{ centers|join(', ') }}
|
||||
{% elseif centers is null %}
|
||||
{{ 'The party is not visible in any center'|trans }}
|
||||
{% else %}
|
||||
{{ 'The party is visible in those centers'|trans }} : {{ centers }}
|
||||
{% endif %}
|
||||
</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
{% endblock %}
|
||||
{% block content_form_actions_delete %}{% endblock %}
|
||||
|
@ -62,7 +62,7 @@ class ThirdPartyNormalizer implements NormalizerAwareInterface, NormalizerInterf
|
||||
}, $thirdParty->getTypesAndCategories()),
|
||||
'profession' => $this->normalizer->normalize($thirdParty->getProfession(), $format, $context),
|
||||
'address' => $this->normalizer->normalize($thirdParty->getAddress(), $format, ['address_rendering' => 'short']),
|
||||
'phonenumber' => $this->normalizer->normalize($thirdParty->getTelephone()),
|
||||
'telephone' => $this->normalizer->normalize($thirdParty->getTelephone()),
|
||||
'email' => $thirdParty->getEmail(),
|
||||
'isChild' => $thirdParty->isChild(),
|
||||
'parent' => $this->normalizer->normalize($thirdParty->getParent(), $format, $context),
|
||||
|
Loading…
x
Reference in New Issue
Block a user