mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge remote-tracking branch 'origin/master' into issue469_budget
This commit is contained in:
commit
02409d4992
36
CHANGELOG.md
36
CHANGELOG.md
@ -11,6 +11,23 @@ and this project adheres to
|
|||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
<!-- write down unreleased development here -->
|
<!-- write down unreleased development here -->
|
||||||
|
* [ACL] fix allow to see the course, event if the scope'course does not contains the scope's user
|
||||||
|
* [search] enforce limit of results for fetching rsults by search api https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/576
|
||||||
|
* [activity] Fix delete button for document (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/554)
|
||||||
|
* [activity] Add return path the document generation (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/553)
|
||||||
|
* [person] add person ressource to person docgen normaliser (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/517)
|
||||||
|
* [person] AccompanyingCourseWorkEdit: fix deleting evaluation documents (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/546)
|
||||||
|
* [person] AccompanyingCourseWorkEdit: download existing documents (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/512)
|
||||||
|
* [person] AccompanyingCourseWorkEdit: replace document by a new one (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/511)
|
||||||
|
* [person] AccompanyingPeriodWork: add referrers to work, add doctrine event listener to add logged user to referrers collection and display a referrers list in work list (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/502)
|
||||||
|
* [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)
|
* [parcours] Toggle emergency/intensity only by referrer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/442)
|
||||||
* [docstore] Add an API entrypoint for StoredObject (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466)
|
* [docstore] Add an API entrypoint for StoredObject (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466)
|
||||||
* [person] Add the possibility of uploading existing documents to AccPeriodWorkEvaluationDocument (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466)
|
* [person] Add the possibility of uploading existing documents to AccPeriodWorkEvaluationDocument (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466)
|
||||||
@ -27,6 +44,25 @@ and this project adheres to
|
|||||||
* [confidential] Fix position of toggle button so it does not cover text nor fall outside of box (no issue)
|
* [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)
|
* [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)
|
* [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)
|
||||||
|
* [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)
|
||||||
|
* [parcours] List of parcours for a specific user so they can be reassigned in case of absence (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/509)
|
||||||
|
* [thirdparty] Thirdparty view page, english text translated (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/534)
|
||||||
|
* [social_action] Translation changed in evaluation section (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/512)
|
||||||
|
* [filiation] Possible to add person (or create onthefly) to add to filiation graph + add relation (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/519)
|
||||||
|
* [household] Within parcours listing page of household add create button (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/560)
|
||||||
|
* [person_resource] bugfix when adding thirdparty or freetext resource (no issue)
|
||||||
|
* [aside_activity] style correction + sticky-form create button (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/529)
|
||||||
|
|
||||||
## Test releases
|
## Test releases
|
||||||
|
|
||||||
|
@ -250,11 +250,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Bundle/ChillMainBundle/Entity/Address.php
|
path: src/Bundle/ChillMainBundle/Entity/Address.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
@ -350,11 +345,6 @@ parameters:
|
|||||||
count: 6
|
count: 6
|
||||||
path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
|
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\\.$#"
|
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@ -179,14 +179,15 @@ final class ActivityController extends AbstractController
|
|||||||
{
|
{
|
||||||
$view = null;
|
$view = null;
|
||||||
|
|
||||||
[$person, $accompanyingPeriod] = $this->getEntity($request);
|
|
||||||
|
|
||||||
$entity = $this->activityRepository->find($id);
|
$entity = $this->activityRepository->find($id);
|
||||||
|
|
||||||
if (null === $entity) {
|
if (null === $entity) {
|
||||||
throw $this->createNotFoundException('Unable to find Activity entity.');
|
throw $this->createNotFoundException('Unable to find Activity entity.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$accompanyingPeriod = $entity->getAccompanyingPeriod();
|
||||||
|
$person = $entity->getPerson();
|
||||||
|
|
||||||
if ($entity->getAccompanyingPeriod() instanceof AccompanyingPeriod) {
|
if ($entity->getAccompanyingPeriod() instanceof AccompanyingPeriod) {
|
||||||
$view = 'ChillActivityBundle:Activity:editAccompanyingCourse.html.twig';
|
$view = 'ChillActivityBundle:Activity:editAccompanyingCourse.html.twig';
|
||||||
$accompanyingPeriod = $entity->getAccompanyingPeriod();
|
$accompanyingPeriod = $entity->getAccompanyingPeriod();
|
||||||
@ -220,6 +221,9 @@ final class ActivityController extends AbstractController
|
|||||||
$this->entityManager->persist($entity);
|
$this->entityManager->persist($entity);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
|
||||||
|
$params['id'] = $entity->getId();
|
||||||
|
|
||||||
if ($form->has('gendocTemplateId') && null !== $form['gendocTemplateId']->getData()) {
|
if ($form->has('gendocTemplateId') && null !== $form['gendocTemplateId']->getData()) {
|
||||||
return $this->redirectToRoute(
|
return $this->redirectToRoute(
|
||||||
'chill_docgenerator_generate_from_template',
|
'chill_docgenerator_generate_from_template',
|
||||||
@ -227,15 +231,13 @@ final class ActivityController extends AbstractController
|
|||||||
'template' => $form->get('gendocTemplateId')->getData(),
|
'template' => $form->get('gendocTemplateId')->getData(),
|
||||||
'entityClassName' => Activity::class,
|
'entityClassName' => Activity::class,
|
||||||
'entityId' => $entity->getId(),
|
'entityId' => $entity->getId(),
|
||||||
|
'returnPath' => $this->generateUrl('chill_activity_activity_edit', $params),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addFlash('success', $this->get('translator')->trans('Success : activity updated!'));
|
$this->addFlash('success', $this->get('translator')->trans('Success : activity updated!'));
|
||||||
|
|
||||||
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
|
|
||||||
$params['id'] = $entity->getId();
|
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_activity_activity_show', $params);
|
return $this->redirectToRoute('chill_activity_activity_show', $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,6 +446,9 @@ final class ActivityController extends AbstractController
|
|||||||
'template' => $form->get('gendocTemplateId')->getData(),
|
'template' => $form->get('gendocTemplateId')->getData(),
|
||||||
'entityClassName' => Activity::class,
|
'entityClassName' => Activity::class,
|
||||||
'entityId' => $entity->getId(),
|
'entityId' => $entity->getId(),
|
||||||
|
'returnPath' => $this->generateUrl('chill_activity_activity_edit', [
|
||||||
|
'id' => $entity->getId(),
|
||||||
|
]),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -305,6 +305,7 @@ class ActivityType extends AbstractType
|
|||||||
'label' => $activityType->getLabel('documents'),
|
'label' => $activityType->getLabel('documents'),
|
||||||
'required' => $activityType->isRequired('documents'),
|
'required' => $activityType->isRequired('documents'),
|
||||||
'allow_add' => true,
|
'allow_add' => true,
|
||||||
|
'allow_delete' => true,
|
||||||
'button_add_label' => 'activity.Insert a document',
|
'button_add_label' => 'activity.Insert a document',
|
||||||
'button_remove_label' => 'activity.Remove a document',
|
'button_remove_label' => 'activity.Remove a document',
|
||||||
'empty_collection_explain' => 'No documents',
|
'empty_collection_explain' => 'No documents',
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
div.chill-dropzone__below-zone {
|
||||||
|
a.btn-delete {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do it in js does not work
|
||||||
|
// document.addEventListener('DOMContentLoaded', e => {
|
||||||
|
// const dropzoneBelow = document.querySelectorAll('div.chill-dropzone__below-zone');
|
||||||
|
// dropzoneBelow.forEach(
|
||||||
|
// d => {
|
||||||
|
// const a = d.querySelector('a.btn-delete');
|
||||||
|
// d.removeChild(a);
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// });
|
@ -110,10 +110,8 @@ export default function prepareLocations(store) {
|
|||||||
console.log('default loation id', window.default_location_id);
|
console.log('default loation id', window.default_location_id);
|
||||||
if (window.default_location_id) {
|
if (window.default_location_id) {
|
||||||
for (let group of store.state.availableLocations) {
|
for (let group of store.state.availableLocations) {
|
||||||
console.log(group);
|
|
||||||
let location = group.locations.find((l) => l.id === window.default_location_id);
|
let location = group.locations.find((l) => l.id === window.default_location_id);
|
||||||
console.log(location);
|
if (location !== undefined & store.state.activity.location === null) {
|
||||||
if (location !== undefined) {
|
|
||||||
store.dispatch('updateLocation', location);
|
store.dispatch('updateLocation', location);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -30,4 +30,5 @@
|
|||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
{{ encore_entry_link_tags('mod_async_upload') }}
|
{{ encore_entry_link_tags('mod_async_upload') }}
|
||||||
{{ encore_entry_link_tags('vue_activity') }}
|
{{ encore_entry_link_tags('vue_activity') }}
|
||||||
|
{{ encore_entry_link_tags('page_edit_activity') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
{% include 'ChillActivityBundle:Activity:list.html.twig' with {'context': 'person'} %}
|
{% include 'ChillActivityBundle:Activity:list.html.twig' with {'context': 'person'} %}
|
||||||
|
|
||||||
{% if is_granted('CHILL_ACTIVITY_CREATE', person) %}
|
{% if is_granted('CHILL_ACTIVITY_CREATE_PERSON', person) %}
|
||||||
<ul class="record_actions sticky-form-buttons">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ path('chill_activity_activity_new', {'person_id': person_id, 'accompanying_period_id': accompanying_course_id}) }}"
|
<a href="{{ path('chill_activity_activity_new', {'person_id': person_id, 'accompanying_period_id': accompanying_course_id}) }}"
|
||||||
|
@ -7,5 +7,7 @@ module.exports = function(encore, entries)
|
|||||||
ChillActivityAssets: __dirname + '/Resources/public'
|
ChillActivityAssets: __dirname + '/Resources/public'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
encore.addEntry('page_edit_activity', __dirname + '/Resources/public/page/edit_activity/index.scss');
|
||||||
|
|
||||||
encore.addEntry('vue_activity', __dirname + '/Resources/public/vuejs/Activity/index.js');
|
encore.addEntry('vue_activity', __dirname + '/Resources/public/vuejs/Activity/index.js');
|
||||||
};
|
};
|
||||||
|
@ -76,7 +76,7 @@ activity:
|
|||||||
Insert a document: Insérer un document
|
Insert a document: Insérer un document
|
||||||
Remove a document: Supprimer le document
|
Remove a document: Supprimer le document
|
||||||
comment: Commentaire
|
comment: Commentaire
|
||||||
No documents: Pas de documents
|
No documents: Aucun document
|
||||||
|
|
||||||
#timeline
|
#timeline
|
||||||
'%user% has done an %activity_type%': '%user% a effectué une activité de type "%activity_type%"'
|
'%user% has done an %activity_type%': '%user% a effectué une activité de type "%activity_type%"'
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-col">
|
<div class="item-col" style="justify-content: flex-end;">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<ul class="list-content fa-ul">
|
<ul class="list-content fa-ul">
|
||||||
<li>
|
<li>
|
||||||
@ -79,7 +79,7 @@
|
|||||||
|
|
||||||
{{ chill_pagination(paginator) }}
|
{{ chill_pagination(paginator) }}
|
||||||
|
|
||||||
<ul class="record_actions">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ chill_path_add_return_path('chill_crud_aside_activity_new') }}" class="btn btn-create">
|
<a href="{{ chill_path_add_return_path('chill_crud_aside_activity_new') }}" class="btn btn-create">
|
||||||
{{ 'Create'|trans }}
|
{{ 'Create'|trans }}
|
||||||
|
@ -207,21 +207,21 @@ final class DocGeneratorTemplateController extends AbstractController
|
|||||||
$context instanceof DocGeneratorContextWithPublicFormInterface
|
$context instanceof DocGeneratorContextWithPublicFormInterface
|
||||||
&& $context->hasPublicForm($template, $entity) || $isTest
|
&& $context->hasPublicForm($template, $entity) || $isTest
|
||||||
) {
|
) {
|
||||||
if ($context instanceof DocGeneratorContextWithPublicFormInterface) {
|
if ($context instanceof DocGeneratorContextWithPublicFormInterface && $context->hasPublicForm($template, $entity)) {
|
||||||
$builder = $this->createFormBuilder(
|
$builder = $this->createFormBuilder(
|
||||||
array_merge(
|
array_merge(
|
||||||
$context->getFormData($template, $entity),
|
$context->getFormData($template, $entity),
|
||||||
$isTest ? ['test_file' => null] : []
|
$isTest ? ['test_file' => null] : []
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$context->buildPublicForm($builder, $template, $entity);
|
||||||
} else {
|
} else {
|
||||||
$builder = $this->createFormBuilder(
|
$builder = $this->createFormBuilder(
|
||||||
['test_file' => null]
|
['test_file' => null]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$context->buildPublicForm($builder, $template, $entity);
|
|
||||||
|
|
||||||
if ($isTest) {
|
if ($isTest) {
|
||||||
$builder->add('test_file', FileType::class, [
|
$builder->add('test_file', FileType::class, [
|
||||||
'label' => 'Template file',
|
'label' => 'Template file',
|
||||||
|
@ -21,6 +21,8 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
|||||||
use DateTime;
|
use DateTime;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
@ -59,21 +61,37 @@ class DocumentAccompanyingCourseController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/{id}", name="accompanying_course_document_delete", methods="DELETE")
|
* @Route("/{id}/delete", name="chill_docstore_accompanying_course_document_delete")
|
||||||
*/
|
*/
|
||||||
public function delete(Request $request, AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
|
public function delete(Request $request, AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted(AccompanyingCourseDocumentVoter::DELETE, $document);
|
$this->denyAccessUnlessGranted(AccompanyingCourseDocumentVoter::DELETE, $document);
|
||||||
|
|
||||||
if ($this->isCsrfTokenValid('delete' . $document->getId(), $request->request->get('_token'))) {
|
$form = $this->createForm(FormType::class);
|
||||||
$em = $this->getDoctrine()->getManager();
|
$form->add('submit', SubmitType::class, ['label' => 'Delete']);
|
||||||
$em->remove($document);
|
|
||||||
$em->flush();
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$this->getDoctrine()->getManager()->remove($document);
|
||||||
|
$this->getDoctrine()->getManager()->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success', $this->translator->trans('The document is successfully removed'));
|
||||||
|
|
||||||
|
if ($request->query->has('returnPath')) {
|
||||||
|
return $this->redirect($request->query->get('returnPath'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->redirectToRoute(
|
return $this->redirectToRoute('accompanying_course_document_index', ['course' => $course->getId()]);
|
||||||
'accompanying_course_document_index',
|
}
|
||||||
['accompanyingCourse' => $course->getId()]
|
|
||||||
|
return $this->render(
|
||||||
|
'ChillDocStoreBundle:AccompanyingCourseDocument:delete.html.twig',
|
||||||
|
[
|
||||||
|
'document' => $document,
|
||||||
|
'delete_form' => $form->createView(),
|
||||||
|
'accompanyingCourse' => $course,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ namespace Chill\DocStoreBundle\Controller;
|
|||||||
use Chill\DocStoreBundle\Entity\PersonDocument;
|
use Chill\DocStoreBundle\Entity\PersonDocument;
|
||||||
use Chill\DocStoreBundle\Form\PersonDocumentType;
|
use Chill\DocStoreBundle\Form\PersonDocumentType;
|
||||||
use Chill\DocStoreBundle\Repository\PersonDocumentACLAwareRepositoryInterface;
|
use Chill\DocStoreBundle\Repository\PersonDocumentACLAwareRepositoryInterface;
|
||||||
|
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
@ -22,6 +23,8 @@ use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
|||||||
use DateTime;
|
use DateTime;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
@ -64,22 +67,37 @@ class DocumentPersonController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/{id}", name="person_document_delete", methods="DELETE")
|
* @Route("/{id}/delete", name="chill_docstore_person_document_delete")
|
||||||
*/
|
*/
|
||||||
public function delete(Request $request, Person $person, PersonDocument $document): Response
|
public function delete(Request $request, Person $person, PersonDocument $document): Response
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
|
$this->denyAccessUnlessGranted(PersonDocumentVoter::DELETE, $document);
|
||||||
$this->denyAccessUnlessGranted('CHILL_PERSON_DOCUMENT_DELETE', $document);
|
|
||||||
|
|
||||||
if ($this->isCsrfTokenValid('delete' . $document->getId(), $request->request->get('_token'))) {
|
$form = $this->createForm(FormType::class);
|
||||||
$em = $this->getDoctrine()->getManager();
|
$form->add('submit', SubmitType::class, ['label' => 'Delete']);
|
||||||
$em->remove($document);
|
|
||||||
$em->flush();
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$this->getDoctrine()->getManager()->remove($document);
|
||||||
|
$this->getDoctrine()->getManager()->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success', $this->translator->trans('The document is successfully removed'));
|
||||||
|
|
||||||
|
if ($request->query->has('returnPath')) {
|
||||||
|
return $this->redirect($request->query->get('returnPath'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->redirectToRoute(
|
return $this->redirectToRoute('person_document_index', ['person' => $person->getId()]);
|
||||||
'person_document_index',
|
}
|
||||||
['person' => $person->getId()]
|
|
||||||
|
return $this->render(
|
||||||
|
'ChillDocStoreBundle:PersonDocument:delete.html.twig',
|
||||||
|
[
|
||||||
|
'document' => $document,
|
||||||
|
'delete_form' => $form->createView(),
|
||||||
|
'person' => $person,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +116,6 @@ class DocumentPersonController extends AbstractController
|
|||||||
PersonDocumentType::class,
|
PersonDocumentType::class,
|
||||||
$document,
|
$document,
|
||||||
[
|
[
|
||||||
'center' => $document->getCenter(),
|
|
||||||
'role' => 'CHILL_PERSON_DOCUMENT_UPDATE',
|
'role' => 'CHILL_PERSON_DOCUMENT_UPDATE',
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
@ -199,7 +216,6 @@ class DocumentPersonController extends AbstractController
|
|||||||
$document->setDate(new DateTime('Now'));
|
$document->setDate(new DateTime('Now'));
|
||||||
|
|
||||||
$form = $this->createForm(PersonDocumentType::class, $document, [
|
$form = $this->createForm(PersonDocumentType::class, $document, [
|
||||||
'center' => $document->getCenter(),
|
|
||||||
'role' => 'CHILL_PERSON_DOCUMENT_CREATE',
|
'role' => 'CHILL_PERSON_DOCUMENT_CREATE',
|
||||||
]);
|
]);
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
@ -61,13 +61,13 @@ class StoredObject implements AsyncFileInterface, Document
|
|||||||
/**
|
/**
|
||||||
* @var int[]
|
* @var int[]
|
||||||
* @ORM\Column(type="json", name="iv")
|
* @ORM\Column(type="json", name="iv")
|
||||||
* @Serializer\Groups({"write"})
|
* @Serializer\Groups({"read", "write"})
|
||||||
*/
|
*/
|
||||||
private array $iv = [];
|
private array $iv = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json", name="key")
|
* @ORM\Column(type="json", name="key")
|
||||||
* @Serializer\Groups({"write"})
|
* @Serializer\Groups({"read", "write"})
|
||||||
*/
|
*/
|
||||||
private array $keyInfos = [];
|
private array $keyInfos = [];
|
||||||
|
|
||||||
|
@ -13,15 +13,13 @@ namespace Chill\DocStoreBundle\Form;
|
|||||||
|
|
||||||
use Chill\DocStoreBundle\Entity\Document;
|
use Chill\DocStoreBundle\Entity\Document;
|
||||||
use Chill\DocStoreBundle\Entity\PersonDocument;
|
use Chill\DocStoreBundle\Entity\PersonDocument;
|
||||||
use Chill\MainBundle\Entity\User;
|
|
||||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
use Chill\MainBundle\Form\Type\ChillTextareaType;
|
use Chill\MainBundle\Form\Type\ChillTextareaType;
|
||||||
use Chill\MainBundle\Form\Type\ScopePickerType;
|
use Chill\MainBundle\Form\Type\ScopePickerType;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher;
|
||||||
use Chill\MainBundle\Security\Resolver\ScopeResolverDispatcher;
|
use Chill\MainBundle\Security\Resolver\ScopeResolverDispatcher;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use Doctrine\Persistence\ObjectManager;
|
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
@ -31,34 +29,16 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
|||||||
|
|
||||||
class PersonDocumentType extends AbstractType
|
class PersonDocumentType extends AbstractType
|
||||||
{
|
{
|
||||||
/**
|
private CenterResolverDispatcher $centerResolverDispatcher;
|
||||||
* @var AuthorizationHelper
|
|
||||||
*/
|
|
||||||
protected $authorizationHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var ObjectManager
|
|
||||||
*/
|
|
||||||
protected $om;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var TranslatableStringHelper
|
|
||||||
*/
|
|
||||||
protected $translatableStringHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the user running this form.
|
|
||||||
*
|
|
||||||
* @var User
|
|
||||||
*/
|
|
||||||
protected $user;
|
|
||||||
|
|
||||||
private ParameterBagInterface $parameterBag;
|
private ParameterBagInterface $parameterBag;
|
||||||
|
|
||||||
private ScopeResolverDispatcher $scopeResolverDispatcher;
|
private ScopeResolverDispatcher $scopeResolverDispatcher;
|
||||||
|
|
||||||
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
TranslatableStringHelper $translatableStringHelper,
|
TranslatableStringHelperInterface $translatableStringHelper,
|
||||||
ScopeResolverDispatcher $scopeResolverDispatcher,
|
ScopeResolverDispatcher $scopeResolverDispatcher,
|
||||||
ParameterBagInterface $parameterBag
|
ParameterBagInterface $parameterBag
|
||||||
) {
|
) {
|
||||||
@ -96,7 +76,7 @@ class PersonDocumentType extends AbstractType
|
|||||||
|
|
||||||
if ($isScopeConcerned && $this->parameterBag->get('chill_main')['acl']['form_show_scopes']) {
|
if ($isScopeConcerned && $this->parameterBag->get('chill_main')['acl']['form_show_scopes']) {
|
||||||
$builder->add('scope', ScopePickerType::class, [
|
$builder->add('scope', ScopePickerType::class, [
|
||||||
'center' => $options['center'],
|
'center' => $this->centerResolverDispatcher->resolveCenter($document),
|
||||||
'role' => $options['role'],
|
'role' => $options['role'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -108,8 +88,7 @@ class PersonDocumentType extends AbstractType
|
|||||||
'data_class' => Document::class,
|
'data_class' => Document::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$resolver->setRequired(['role', 'center'])
|
$resolver->setRequired(['role'])
|
||||||
->setAllowedTypes('role', ['string'])
|
->setAllowedTypes('role', ['string']);
|
||||||
->setAllowedTypes('center', [\Chill\MainBundle\Entity\Center::class]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ var download = (button) => {
|
|||||||
button.type = mimeType;
|
button.type = mimeType;
|
||||||
button.textContent = labelReady;
|
button.textContent = labelReady;
|
||||||
if (hasFilename) {
|
if (hasFilename) {
|
||||||
|
|
||||||
button.download = filename;
|
button.download = filename;
|
||||||
if (extension !== false) {
|
if (extension !== false) {
|
||||||
button.download = button.download + '.' + extension;
|
button.download = button.download + '.' + extension;
|
||||||
@ -92,4 +93,4 @@ window.addEventListener('load', function(e) {
|
|||||||
initializeButtons(e.target);
|
initializeButtons(e.target);
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = initializeButtons;
|
export { initializeButtons, download };
|
@ -1,6 +1,6 @@
|
|||||||
var algo = 'AES-CBC';
|
var algo = 'AES-CBC';
|
||||||
import Dropzone from 'dropzone';
|
import Dropzone from 'dropzone';
|
||||||
var initializeDownload = require('./downloader.js');
|
import { initializeButtons } from './downloader.js';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -359,7 +359,7 @@ var insertDownloadButton = (zone, zoneData) => {
|
|||||||
|
|
||||||
addBelowButton(newButton, zone, zoneData);
|
addBelowButton(newButton, zone, zoneData);
|
||||||
//zone.appendChild(newButton);
|
//zone.appendChild(newButton);
|
||||||
initializeDownload(zone);
|
initializeButtons(zone);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('load', function(e) {
|
window.addEventListener('load', function(e) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<a class="btn btn-create" :title="$t(buttonTitle)" @click="openModal">
|
<a :class="btnClasses" :title="$t(buttonTitle)" @click="openModal">
|
||||||
<span>{{ $t(buttonTitle) }}</span>
|
<span>{{ $t(buttonTitle) }}</span>
|
||||||
</a>
|
</a>
|
||||||
<teleport to="body">
|
<teleport to="body">
|
||||||
@ -96,10 +96,27 @@ export default {
|
|||||||
Modal
|
Modal
|
||||||
},
|
},
|
||||||
i18n,
|
i18n,
|
||||||
props: [
|
props: {
|
||||||
'buttonTitle',
|
buttonTitle: {
|
||||||
'options'
|
type: String,
|
||||||
],
|
default: 'Ajouter un document',
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default: {
|
||||||
|
maxFiles: 1,
|
||||||
|
maxPostSize: 262144000, // 250MB
|
||||||
|
required: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
btnClasses: {
|
||||||
|
type: Object,
|
||||||
|
default: {
|
||||||
|
btn: true,
|
||||||
|
'btn-create': true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
emits: ['addDocument'],
|
emits: ['addDocument'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<a
|
||||||
|
class="btn btn-download"
|
||||||
|
:title="$t(buttonTitle)"
|
||||||
|
:data-key=JSON.stringify(storedObject.keyInfos)
|
||||||
|
:data-iv=JSON.stringify(storedObject.iv)
|
||||||
|
:data-mime-type=storedObject.type
|
||||||
|
:data-label-preparing="$t('dataLabelPreparing')"
|
||||||
|
:data-label-ready="$t('dataLabelReady')"
|
||||||
|
:data-temp-url-get-generator="url"
|
||||||
|
@click.once="downloadDocument">
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { download } from '../../module/async_upload/downloader';
|
||||||
|
|
||||||
|
const i18n = {
|
||||||
|
messages: {
|
||||||
|
fr: {
|
||||||
|
dataLabelPreparing: "Chargement...",
|
||||||
|
dataLabelReady: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AddAsyncUploadDownloader",
|
||||||
|
i18n,
|
||||||
|
props: [
|
||||||
|
'buttonTitle',
|
||||||
|
'storedObject'
|
||||||
|
],
|
||||||
|
computed: {
|
||||||
|
url() {
|
||||||
|
return `/asyncupload/temp_url/generate/GET?object_name=${this.storedObject.filename}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
downloadDocument(e) {
|
||||||
|
download(e.target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,5 +0,0 @@
|
|||||||
<form method="post" action="{{ path('accompanying_course_document_delete', {'id': document.id, 'course': course.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
|
|
||||||
<input type="hidden" name="_method" value="DELETE">
|
|
||||||
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ document.id) }}">
|
|
||||||
<button class="btn btn-delete">{{ 'Delete' | trans }}</button>
|
|
||||||
</form>
|
|
@ -0,0 +1,43 @@
|
|||||||
|
{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = '' %}
|
||||||
|
|
||||||
|
{% block title %}{{ 'Delete document ?' }}{% endblock %}
|
||||||
|
|
||||||
|
{% block docdescription %}
|
||||||
|
<dl class="chill_view_data">
|
||||||
|
<dt>{{ 'Title'|trans }}</dt>
|
||||||
|
<dd>{{ document.title }}</dd>
|
||||||
|
|
||||||
|
{% if document.scope is not null %}
|
||||||
|
<dt>{{ 'Scope' | trans }}</dt>
|
||||||
|
<dd>{{ document.scope.name | localize_translatable_string }}</dd>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<dt>{{ 'Category'|trans }}</dt>
|
||||||
|
<dd>{{ document.category.name|localize_translatable_string }}</dd>
|
||||||
|
|
||||||
|
<dt>{{ 'Description' | trans }}</dt>
|
||||||
|
<dd>
|
||||||
|
{% if document.description is empty %}
|
||||||
|
<span class="chill-no-data-statement">{{ 'Any description'|trans }}</span>
|
||||||
|
{% else %}
|
||||||
|
<blockquote class="chill-user-quote">
|
||||||
|
{{ document.description|chill_markdown_to_html }}
|
||||||
|
</blockquote>
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{{ include('@ChillMain/Util/confirmation_template.html.twig',
|
||||||
|
{
|
||||||
|
'title' : 'Delete document ?'|trans,
|
||||||
|
'display_content' : block('docdescription'),
|
||||||
|
'confirm_question' : 'Are you sure you want to remove this document ?'|trans,
|
||||||
|
'cancel_route' : 'accompanying_course_document_index',
|
||||||
|
'cancel_parameters' : {'course' : accompanyingCourse.id, 'id': document.id},
|
||||||
|
'form' : delete_form
|
||||||
|
} ) }}
|
||||||
|
{% endblock %}
|
@ -25,6 +25,11 @@
|
|||||||
{{ 'Back to the list' | trans }}
|
{{ 'Back to the list' | trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', document) %}
|
||||||
|
<li class="delete">
|
||||||
|
<a href="{{ chill_return_path_or('chill_docstore_accompanying_course_document_delete', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
<li class="edit">
|
<li class="edit">
|
||||||
<button class="btn btn-edit">{{ 'Edit'|trans }}</button>
|
<button class="btn btn-edit">{{ 'Edit'|trans }}</button>
|
||||||
</li>
|
</li>
|
||||||
|
@ -49,12 +49,9 @@
|
|||||||
{{ 'Back to the list' | trans }}
|
{{ 'Back to the list' | trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', document) %}
|
||||||
{{ m.download_button(document.object, document.title) }}
|
<li class="delete">
|
||||||
</li>
|
<a href="{{ chill_return_path_or('chill_docstore_accompanying_course_document_delete', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||||
{% if chill_document_is_editable(document.object) %}
|
|
||||||
<li>
|
|
||||||
{{ document.object|chill_document_edit_button }}
|
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
|
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
|
||||||
@ -63,6 +60,14 @@
|
|||||||
class="btn btn-edit" title="{{ 'Edit attributes' | trans }}"></a>
|
class="btn btn-edit" title="{{ 'Edit attributes' | trans }}"></a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<li>
|
||||||
|
{{ m.download_button(document.object, document.title) }}
|
||||||
|
</li>
|
||||||
|
{% if chill_document_is_editable(document.object) %}
|
||||||
|
<li>
|
||||||
|
{{ document.object|chill_document_edit_button }}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
{% set workflows_frame = chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) %}
|
{% set workflows_frame = chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) %}
|
||||||
{% if workflows_frame is not empty %}
|
{% if workflows_frame is not empty %}
|
||||||
<li>
|
<li>
|
||||||
|
@ -44,6 +44,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<ul class="item-col record_actions flex-shrink-1">
|
<ul class="item-col record_actions flex-shrink-1">
|
||||||
{% if document.course is defined %}
|
{% if document.course is defined %}
|
||||||
|
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', document) %}
|
||||||
|
<li class="delete">
|
||||||
|
<a href="{{ chill_return_path_or('chill_docstore_accompanying_course_document_delete', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ path('accompanying_course_document_edit', {'course': accompanyingCourse.id, 'id': document.id }) }}" class="btn btn-update"></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS', document) %}
|
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS', document) %}
|
||||||
<li>
|
<li>
|
||||||
{{ m.download_button(document.object, document.title) }}
|
{{ m.download_button(document.object, document.title) }}
|
||||||
@ -52,15 +62,20 @@
|
|||||||
<a href="{{ chill_path_add_return_path('accompanying_course_document_show', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-show"></a>
|
<a href="{{ chill_path_add_return_path('accompanying_course_document_show', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-show"></a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
|
|
||||||
<li>
|
|
||||||
<a href="{{ path('accompanying_course_document_edit', {'course': accompanyingCourse.id, 'id': document.id }) }}" class="btn btn-update"></a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
<li>
|
<li>
|
||||||
{{ chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) }}
|
{{ chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) }}
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
{% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %}
|
||||||
|
<li class="delete">
|
||||||
|
<a href="{{ chill_return_path_or('chill_docstore_person_document_delete', {'person': person.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document) %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ path('person_document_edit', {'person': person.id, 'id': document.id}) }}" class="btn btn-update"></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
{% if is_granted('CHILL_PERSON_DOCUMENT_SEE_DETAILS', document) %}
|
{% if is_granted('CHILL_PERSON_DOCUMENT_SEE_DETAILS', document) %}
|
||||||
<li>
|
<li>
|
||||||
{{ m.download_button(document.object, document.title) }}
|
{{ m.download_button(document.object, document.title) }}
|
||||||
@ -69,11 +84,6 @@
|
|||||||
<a href="{{ path('person_document_show', {'person': person.id, 'id': document.id}) }}" class="btn btn-show"></a>
|
<a href="{{ path('person_document_show', {'person': person.id, 'id': document.id}) }}" class="btn btn-show"></a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document) %}
|
|
||||||
<li>
|
|
||||||
<a href="{{ path('person_document_edit', {'person': person.id, 'id': document.id}) }}" class="btn btn-update"></a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = '' %}
|
||||||
|
|
||||||
|
{% block title %}{{ 'Delete document ?' }}{% endblock %}
|
||||||
|
|
||||||
|
{% block docdescription %}
|
||||||
|
<dl class="chill_view_data">
|
||||||
|
<dt>{{ 'Title'|trans }}</dt>
|
||||||
|
<dd>{{ document.title }}</dd>
|
||||||
|
|
||||||
|
{% if document.scope is not null %}
|
||||||
|
<dt>{{ 'Scope' | trans }}</dt>
|
||||||
|
<dd>{{ document.scope.name | localize_translatable_string }}</dd>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<dt>{{ 'Category'|trans }}</dt>
|
||||||
|
<dd>{{ document.category.name|localize_translatable_string }}</dd>
|
||||||
|
|
||||||
|
<dt>{{ 'Description' | trans }}</dt>
|
||||||
|
<dd>
|
||||||
|
{% if document.description is empty %}
|
||||||
|
<span class="chill-no-data-statement">{{ 'Any description'|trans }}</span>
|
||||||
|
{% else %}
|
||||||
|
<blockquote class="chill-user-quote">
|
||||||
|
{{ document.description|chill_markdown_to_html }}
|
||||||
|
</blockquote>
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block personcontent %}
|
||||||
|
{{ include('@ChillMain/Util/confirmation_template.html.twig',
|
||||||
|
{
|
||||||
|
'title' : 'Delete document ?'|trans,
|
||||||
|
'display_content' : block('docdescription'),
|
||||||
|
'confirm_question' : 'Are you sure you want to remove this document ?'|trans,
|
||||||
|
'cancel_route' : 'person_document_index',
|
||||||
|
'cancel_parameters' : {'person' : person.id, 'id': document.id},
|
||||||
|
'form' : delete_form
|
||||||
|
} ) }}
|
||||||
|
{% endblock %}
|
@ -36,20 +36,20 @@
|
|||||||
{{ form_row(form.description) }}
|
{{ form_row(form.description) }}
|
||||||
{{ form_row(form.object, { 'label': 'Document', 'existing': document.object }) }}
|
{{ form_row(form.object, { 'label': 'Document', 'existing': document.object }) }}
|
||||||
|
|
||||||
<ul class="record_actions">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
<li class="cancel">
|
<li class="cancel">
|
||||||
<a href="{{ path('person_document_index', {'person': person.id}) }}" class="btn btn-cancel">
|
<a href="{{ chill_return_path_or('person_document_index', {'person': person.id}) }}" class="btn btn-cancel">
|
||||||
{{ 'Back to the list' | trans }}
|
{{ 'Back to the list' | trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %}
|
||||||
|
<li class="delete">
|
||||||
|
<a href="{{ chill_return_path_or('chill_docstore_person_document_delete', {'person': person.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
<li class="edit">
|
<li class="edit">
|
||||||
<button class="btn btn-edit">{{ 'Edit'|trans }}</button>
|
<button class="btn btn-edit">{{ 'Edit'|trans }}</button>
|
||||||
</li>
|
</li>
|
||||||
{# {% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %}
|
|
||||||
<li class="delete">
|
|
||||||
{{ include('ChillDocStoreBundle:PersonDocument:_delete_form.html.twig') }}
|
|
||||||
</li>
|
|
||||||
{% endif %} #}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{{ form_end(form) }}
|
{{ form_end(form) }}
|
||||||
|
@ -26,7 +26,17 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
|
{{ parent() }}
|
||||||
{{ encore_entry_script_tags('mod_async_upload') }}
|
{{ encore_entry_script_tags('mod_async_upload') }}
|
||||||
|
{{ encore_entry_script_tags('mod_docgen_picktemplate') }}
|
||||||
|
{{ encore_entry_script_tags('mod_entity_workflow_pick') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
{{ parent() }}
|
||||||
|
{{ encore_entry_link_tags('mod_async_upload') }}
|
||||||
|
{{ encore_entry_link_tags('mod_docgen_picktemplate') }}
|
||||||
|
{{ encore_entry_link_tags('mod_entity_workflow_pick') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@ -46,6 +56,8 @@
|
|||||||
|
|
||||||
{{ chill_pagination(pagination) }}
|
{{ chill_pagination(pagination) }}
|
||||||
|
|
||||||
|
<div data-docgen-template-picker="data-docgen-template-picker" data-entity-class="Chill\PersonBundle\Entity\Person" data-entity-id="{{ person.id }}"></div>
|
||||||
|
|
||||||
{% if is_granted('CHILL_PERSON_DOCUMENT_CREATE', person) %}
|
{% if is_granted('CHILL_PERSON_DOCUMENT_CREATE', person) %}
|
||||||
<ul class="record_actions sticky-form-buttons">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
<li class="create">
|
<li class="create">
|
||||||
|
@ -40,9 +40,9 @@
|
|||||||
{{ form_row(form.description) }}
|
{{ form_row(form.description) }}
|
||||||
{{ form_row(form.object, { 'label': 'Document', 'existing': document.object }) }}
|
{{ form_row(form.object, { 'label': 'Document', 'existing': document.object }) }}
|
||||||
|
|
||||||
<ul class="record_actions">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
<li class="cancel">
|
<li class="cancel">
|
||||||
<a href="{{ path('person_document_index', {'person': person.id}) }}" class="btn btn-cancel">
|
<a href="{{ chill_return_path_or('person_document_index', {'person': person.id}) }}" class="btn btn-cancel">
|
||||||
{{ 'Back to the list' | trans }}
|
{{ 'Back to the list' | trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -64,13 +64,9 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
{% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %}
|
||||||
{{ m.download_button(document.object, document.title) }}
|
<li class="delete">
|
||||||
</li>
|
<a href="{{ chill_return_path_or('chill_docstore_person_document_delete', {'person': person.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||||
|
|
||||||
{% if chill_document_is_editable(document.object) %}
|
|
||||||
<li>
|
|
||||||
{{ document.object|chill_document_edit_button }}
|
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -82,5 +78,15 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<li>
|
||||||
|
{{ m.download_button(document.object, document.title) }}
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{% if chill_document_is_editable(document.object) %}
|
||||||
|
<li>
|
||||||
|
{{ document.object|chill_document_edit_button }}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{# {{ include('ChillDocStoreBundle:PersonDocument:_delete_form.html.twig') }} #}
|
{# {{ include('ChillDocStoreBundle:PersonDocument:_delete_form.html.twig') }} #}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -12,6 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\DocStoreBundle\Workflow;
|
namespace Chill\DocStoreBundle\Workflow;
|
||||||
|
|
||||||
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
||||||
|
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
||||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||||
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||||
@ -36,6 +37,13 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler
|
|||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDeletionRoles(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AccompanyingCourseDocumentVoter::DELETE,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function getEntityData(EntityWorkflow $entityWorkflow, array $options = []): array
|
public function getEntityData(EntityWorkflow $entityWorkflow, array $options = []): array
|
||||||
{
|
{
|
||||||
$course = $this->getRelatedEntity($entityWorkflow)
|
$course = $this->getRelatedEntity($entityWorkflow)
|
||||||
@ -66,6 +74,18 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler
|
|||||||
return $this->repository->find($entityWorkflow->getRelatedEntityId());
|
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
|
public function getRoleShow(EntityWorkflow $entityWorkflow): ?string
|
||||||
{
|
{
|
||||||
return null;
|
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
|
public function supports(EntityWorkflow $entityWorkflow, array $options = []): bool
|
||||||
{
|
{
|
||||||
return $entityWorkflow->getRelatedEntityClass() === AccompanyingCourseDocument::class;
|
return $entityWorkflow->getRelatedEntityClass() === AccompanyingCourseDocument::class;
|
||||||
|
@ -19,6 +19,12 @@ The document is successfully registered: Le document est enregistré
|
|||||||
The document is successfully updated: Le document est mis à jour
|
The document is successfully updated: Le document est mis à jour
|
||||||
Any description: Aucune description
|
Any description: Aucune description
|
||||||
|
|
||||||
|
# delete
|
||||||
|
Delete document ?: Supprimer le document ?
|
||||||
|
Are you sure you want to remove this document ?: Êtes-vous sûr·e de vouloir supprimer ce document ?
|
||||||
|
The document is successfully removed: Le document a été supprimé
|
||||||
|
|
||||||
|
|
||||||
# dropzone upload
|
# dropzone upload
|
||||||
File too big: Fichier trop volumineux
|
File too big: Fichier trop volumineux
|
||||||
Drop your file or click here: Cliquez ici ou faites glissez votre nouveau fichier dans cette zone
|
Drop your file or click here: Cliquez ici ou faites glissez votre nouveau fichier dans cette zone
|
||||||
|
@ -26,6 +26,7 @@ use Symfony\Component\Filesystem\Filesystem;
|
|||||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||||
|
|
||||||
use function count;
|
use function count;
|
||||||
|
use function strlen;
|
||||||
|
|
||||||
class LoadPostalCodesCommand extends Command
|
class LoadPostalCodesCommand extends Command
|
||||||
{
|
{
|
||||||
@ -118,6 +119,13 @@ class LoadPostalCodesCommand extends Command
|
|||||||
|
|
||||||
private function addPostalCode($row, OutputInterface $output)
|
private function addPostalCode($row, OutputInterface $output)
|
||||||
{
|
{
|
||||||
|
if ('FR' === $row[2] && strlen($row[0]) === 4) {
|
||||||
|
// CP in FRANCE are on 5 digit
|
||||||
|
// For CP starting with a zero, the starting zero can be remove if stored as number in a csv
|
||||||
|
// add a zero if CP from FR and on 4 digit
|
||||||
|
$row[0] = '0' . $row[0];
|
||||||
|
}
|
||||||
|
|
||||||
if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
|
if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
|
||||||
$output->writeln('handling row: ' . $row[0] . ' | ' . $row[1] . ' | ' . $row[2]);
|
$output->writeln('handling row: ' . $row[0] . ' | ' . $row[1] . ' | ' . $row[2]);
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,11 @@ class ChillMainExtension extends Extension implements
|
|||||||
$config['available_countries']
|
$config['available_countries']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
'chill_main.access_global_history',
|
||||||
|
$config['access_global_history']
|
||||||
|
);
|
||||||
|
|
||||||
$container->setParameter(
|
$container->setParameter(
|
||||||
'chill_main.routing.resources',
|
'chill_main.routing.resources',
|
||||||
$config['routing']['resources']
|
$config['routing']['resources']
|
||||||
@ -256,6 +261,13 @@ class ChillMainExtension extends Extension implements
|
|||||||
'channels' => ['chill'],
|
'channels' => ['chill'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$container->prependExtensionConfig('security', [
|
||||||
|
'access_decision_manager' => [
|
||||||
|
'strategy' => 'unanimous',
|
||||||
|
'allow_if_all_abstain' => false,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
//add crud api
|
//add crud api
|
||||||
$this->prependCruds($container);
|
$this->prependCruds($container);
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,9 @@ class Configuration implements ConfigurationInterface
|
|||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
|
->booleanNode('access_global_history')
|
||||||
|
->defaultTrue()
|
||||||
|
->end()
|
||||||
->arrayNode('redis')
|
->arrayNode('redis')
|
||||||
->children()
|
->children()
|
||||||
->scalarNode('host')
|
->scalarNode('host')
|
||||||
|
@ -61,7 +61,7 @@ class CommentEmbeddable
|
|||||||
|
|
||||||
public function isEmpty()
|
public function isEmpty()
|
||||||
{
|
{
|
||||||
return empty($this->getComment());
|
return null === $this->getComment() || '' === $this->getComment();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setComment(?string $comment)
|
public function setComment(?string $comment)
|
||||||
|
@ -40,6 +40,7 @@ class UserJob
|
|||||||
* @var array|string[]A
|
* @var array|string[]A
|
||||||
* @ORM\Column(name="label", type="json")
|
* @ORM\Column(name="label", type="json")
|
||||||
* @Serializer\Groups({"read", "docgen:read"})
|
* @Serializer\Groups({"read", "docgen:read"})
|
||||||
|
* @Serializer\Context({"is-translatable": true}, groups={"docgen:read"})
|
||||||
*/
|
*/
|
||||||
protected array $label = [];
|
protected array $label = [];
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ class EntityWorkflowStep
|
|||||||
* You should **not** rely on this method to get all users which are able to
|
* 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.
|
* apply a transition on this step. Use @see{EntityWorkflowStep::getAllDestUser} instead.
|
||||||
*/
|
*/
|
||||||
public function getDestUser(): collection
|
public function getDestUser(): Collection
|
||||||
{
|
{
|
||||||
return $this->destUser;
|
return $this->destUser;
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,7 @@ use libphonenumber\PhoneNumberUtil;
|
|||||||
use Misd\PhoneNumberBundle\Form\Type\PhoneNumberType;
|
use Misd\PhoneNumberBundle\Form\Type\PhoneNumberType;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\OptionsResolver\Options;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use function array_key_exists;
|
|
||||||
|
|
||||||
class ChillPhoneNumberType extends AbstractType
|
class ChillPhoneNumberType extends AbstractType
|
||||||
{
|
{
|
||||||
@ -37,21 +35,7 @@ class ChillPhoneNumberType extends AbstractType
|
|||||||
$resolver
|
$resolver
|
||||||
->setDefault('default_region', $this->defaultCarrierCode)
|
->setDefault('default_region', $this->defaultCarrierCode)
|
||||||
->setDefault('format', PhoneNumberFormat::NATIONAL)
|
->setDefault('format', PhoneNumberFormat::NATIONAL)
|
||||||
->setDefault('type', \libphonenumber\PhoneNumberType::FIXED_LINE_OR_MOBILE)
|
->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']),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getParent()
|
public function getParent()
|
||||||
|
@ -27,7 +27,7 @@ interface PhoneNumberHelperInterface
|
|||||||
/**
|
/**
|
||||||
* Get type (mobile, landline, ...) for phone number.
|
* 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.
|
* Return true if the validation is configured and available.
|
||||||
|
@ -17,6 +17,7 @@ use GuzzleHttp\Exception\ConnectException;
|
|||||||
use GuzzleHttp\Exception\ServerException;
|
use GuzzleHttp\Exception\ServerException;
|
||||||
use libphonenumber\NumberParseException;
|
use libphonenumber\NumberParseException;
|
||||||
use libphonenumber\PhoneNumber;
|
use libphonenumber\PhoneNumber;
|
||||||
|
use libphonenumber\PhoneNumberType;
|
||||||
use libphonenumber\PhoneNumberUtil;
|
use libphonenumber\PhoneNumberUtil;
|
||||||
use Psr\Cache\CacheItemPoolInterface;
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
@ -86,9 +87,19 @@ final class PhonenumberHelper implements PhoneNumberHelperInterface
|
|||||||
/**
|
/**
|
||||||
* Get type (mobile, landline, ...) for phone number.
|
* 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();
|
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
|
public function find($id): ?EntityWorkflow
|
||||||
{
|
{
|
||||||
return $this->repository->find($id);
|
return $this->repository->find($id);
|
||||||
|
@ -25,7 +25,7 @@ $chill-theme-buttons: (
|
|||||||
"notify": $chill-blue,
|
"notify": $chill-blue,
|
||||||
"search": $gray-300,
|
"search": $gray-300,
|
||||||
"unlink": $chill-red,
|
"unlink": $chill-red,
|
||||||
"tpchild": $chill-pink,
|
"tpchild": $chill-green,
|
||||||
);
|
);
|
||||||
|
|
||||||
@each $button, $color in $chill-theme-buttons {
|
@each $button, $color in $chill-theme-buttons {
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* Generic api method that can be adapted to any fetch request
|
* Generic api method that can be adapted to any fetch request
|
||||||
*/
|
*/
|
||||||
const makeFetch = (method, url, body) => {
|
const makeFetch = (method, url, body, options) => {
|
||||||
return fetch(url, {
|
let opts = {
|
||||||
method: method,
|
method: method,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json;charset=utf-8'
|
'Content-Type': 'application/json;charset=utf-8'
|
||||||
},
|
},
|
||||||
body: (body !== null) ? JSON.stringify(body) : null
|
body: (body !== null) ? JSON.stringify(body) : null
|
||||||
})
|
};
|
||||||
|
|
||||||
|
if (typeof options !== 'undefined') {
|
||||||
|
opts = Object.assign(opts, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch(url, opts)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
console.log('200 error')
|
|
||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,37 +1,26 @@
|
|||||||
.confidential {
|
.confidential {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
margin-right: 20px
|
||||||
.toggle-far-twig {
|
|
||||||
i {
|
|
||||||
bottom: 0px;
|
|
||||||
right: -30px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-close-twig {
|
.toggle-container {
|
||||||
i {
|
position: absolute;
|
||||||
bottom: 0px;
|
width: 100%;
|
||||||
right: -5px;
|
top: 0;
|
||||||
}
|
left: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 5;
|
||||||
|
padding-right: 1rem;
|
||||||
}
|
}
|
||||||
.toggle{
|
.toggle{
|
||||||
margin-left: 30px;
|
|
||||||
margin-top: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 5;
|
right: 4px;
|
||||||
right: -30px
|
&-twig {
|
||||||
|
position: absolute;
|
||||||
|
right: -25px;
|
||||||
|
bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-far {
|
|
||||||
bottom: 0px;
|
|
||||||
right: 20px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle-close {
|
|
||||||
bottom: 125px;
|
|
||||||
right: 15px !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.blur {
|
.blur {
|
||||||
|
@ -2,17 +2,18 @@ require('./blur.scss');
|
|||||||
|
|
||||||
document.querySelectorAll('.confidential').forEach(function (el) {
|
document.querySelectorAll('.confidential').forEach(function (el) {
|
||||||
let i = document.createElement('i');
|
let i = document.createElement('i');
|
||||||
const classes = ['fa', 'fa-eye', 'toggle'];
|
const classes = ['fa', 'fa-eye-slash', 'toggle-twig'];
|
||||||
i.classList.add(...classes);
|
i.classList.add(...classes);
|
||||||
el.appendChild(i);
|
el.appendChild(i);
|
||||||
|
|
||||||
const toggleBlur = function(e) {
|
const toggleBlur = function(e) {
|
||||||
for (let child of el.children) {
|
for (let child of el.children) {
|
||||||
if (!child.classList.contains('toggle')) {
|
if (!child.classList.contains('toggle-twig')) {
|
||||||
child.classList.toggle('blur');
|
child.classList.toggle('blur');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i.classList.toggle('fa-eye');
|
|
||||||
i.classList.toggle('fa-eye-slash');
|
i.classList.toggle('fa-eye-slash');
|
||||||
|
i.classList.toggle('fa-eye');
|
||||||
}
|
}
|
||||||
i.addEventListener('click', toggleBlur);
|
i.addEventListener('click', toggleBlur);
|
||||||
toggleBlur();
|
toggleBlur();
|
||||||
|
@ -22,6 +22,7 @@ const fetchCountries = () => {
|
|||||||
*/
|
*/
|
||||||
const fetchCities = (country) => {
|
const fetchCities = (country) => {
|
||||||
//console.log('<<< fetching cities for', 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}`;
|
const url = `/api/1.0/main/postal-code.json?item_per_page=1000&country=${country.id}`;
|
||||||
return fetch(url)
|
return fetch(url)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
@ -42,9 +42,6 @@
|
|||||||
<a class="btn btn-sm btn-show" :href="getUrl(e)">
|
<a class="btn btn-sm btn-show" :href="getUrl(e)">
|
||||||
{{ $t('show_entity', { entity: $t('the_evaluation') }) }}
|
{{ $t('show_entity', { entity: $t('the_evaluation') }) }}
|
||||||
</a>
|
</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)">
|
<a class="btn btn-sm btn-show" :href="getUrl(e.accompanyingPeriodWork.accompanyingPeriod)">
|
||||||
{{ $t('show_entity', { entity: $t('the_course') }) }}
|
{{ $t('show_entity', { entity: $t('the_course') }) }}
|
||||||
</a>
|
</a>
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
<div :class="{ 'blur': isBlurred }">
|
<div :class="{ 'blur': isBlurred }">
|
||||||
<slot name="confidential-content"></slot>
|
<slot name="confidential-content"></slot>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="toggle-container">
|
||||||
<i class="fa fa-eye toggle" :class="positionBtn" aria-hidden="true" @click="toggleBlur"></i>
|
<i class="fa toggle" :class="toggleIcon" aria-hidden="true" @click="toggleBlur"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -12,28 +12,24 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "Confidential",
|
name: "Confidential",
|
||||||
props: ['positionBtnFar'],
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isBlurred: true,
|
isBlurred: true,
|
||||||
|
toggleIcon: 'fa-eye',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods : {
|
methods : {
|
||||||
toggleBlur() {
|
toggleBlur() {
|
||||||
console.log(this.positionBtnFar);
|
console.log(this.positionBtnFar);
|
||||||
this.isBlurred = !this.isBlurred;
|
this.isBlurred = !this.isBlurred;
|
||||||
|
this.toggleIcon = this.isBlurred ? 'fa-eye' : 'fa-eye-slash';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
positionBtn() {
|
|
||||||
return this.positionBtnFar ? 'toggle-far' : 'toggle-close'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang='scss'>
|
<style scoped lang='scss'>
|
||||||
.confidential{
|
.confidential{
|
||||||
align-items: center;
|
align-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
must be shown in such list
|
must be shown in such list
|
||||||
#}
|
#}
|
||||||
{%- if render == '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'] %}
|
{% if options['with_picto'] %}
|
||||||
<i class="fa fa-li fa-map-marker"></i>
|
<i class="fa fa-li fa-map-marker"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -68,7 +68,7 @@
|
|||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
|
||||||
{%- if render == 'inline' -%}
|
{%- 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'] %}
|
{% if options['with_picto'] %}
|
||||||
<i class="fa fa-fw fa-map-marker"></i>
|
<i class="fa fa-fw fa-map-marker"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -77,7 +77,7 @@
|
|||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
|
||||||
{%- if render == 'bloc' -%}
|
{%- 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 options['has_no_address'] == true and address.isNoAddress == true %}
|
||||||
{% if address.postCode is not empty %}
|
{% if address.postCode is not empty %}
|
||||||
<div class="address{% if options['multiline'] %} multiline{% endif %}{% if options['with_delimiter'] %} delimiter{% endif %}">
|
<div class="address{% if options['multiline'] %} multiline{% endif %}{% if options['with_delimiter'] %} delimiter{% endif %}">
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{% for menu in menus %}
|
{% for menu in menus %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ menu.uri }}">
|
<a class="list-group-item list-group-item-action" href="{{ menu.uri }}">
|
||||||
{{ menu.label|upper }}
|
{{ menu.label|trans|upper }}
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,44 +1,43 @@
|
|||||||
{% extends '@ChillMain/Admin/Permission/layout_crud_permission_index.html.twig' %}
|
{% extends '@ChillMain/Admin/Permission/layout_crud_permission_index.html.twig' %}
|
||||||
|
|
||||||
{% block admin_content -%}
|
{% block admin_content -%}
|
||||||
{% embed '@ChillMain/CRUD/_index.html.twig' %}
|
|
||||||
{% block table_entities_thead_tr %}
|
<h1>{{"Users"|trans}}</h1>
|
||||||
<th>{{ 'crud.admin_user.index.is_active'|trans }}</th>
|
|
||||||
<th>{{ 'crud.admin_user.index.usernames'|trans }}</th>
|
|
||||||
<th>{{ 'crud.admin_user.index.mains'|trans }}</th>
|
|
||||||
<th> </th>
|
|
||||||
{% endblock %}
|
|
||||||
{% block table_entities_tbody %}
|
|
||||||
{% for entity in entities %}
|
{% for entity in entities %}
|
||||||
<tr data-username="{{ entity.username|e('html_attr') }}">
|
<div class="flex-table">
|
||||||
<td>
|
<div class="item-bloc">
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item-col">
|
||||||
|
{{ entity.label }}
|
||||||
{% if entity.isEnabled %}
|
{% if entity.isEnabled %}
|
||||||
<i class="fa fa-check chill-green"></i>
|
<i class="fa fa-check chill-green"></i>
|
||||||
{% else %}
|
{% else %}
|
||||||
<i class="fa fa-times chill-red"></i>
|
<i class="fa fa-times chill-red"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</div>
|
||||||
<td>
|
<div class="item-col"><i>{{ entity.email }}</i></div>
|
||||||
{{ entity.username }}
|
</div>
|
||||||
<br/>
|
<div class="item-row">
|
||||||
{{ entity.label }}
|
<div class="item-col">
|
||||||
<br/>
|
login: {{ entity.username|e('html_attr') }}
|
||||||
{{ entity.email }}
|
</div>
|
||||||
</td>
|
<div class="item-col">
|
||||||
<td>
|
|
||||||
{% if entity.userJob %}
|
{% if entity.userJob %}
|
||||||
{{ entity.userJob.label|localize_translatable_string }}
|
{{ entity.userJob.label|localize_translatable_string }}
|
||||||
<br/>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item-col">
|
||||||
{% if entity.mainScope %}
|
{% if entity.mainScope %}
|
||||||
{{ entity.mainScope.name|localize_translatable_string }}
|
{{ entity.mainScope.name|localize_translatable_string }}
|
||||||
<br/>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if entity.mainCenter %}
|
{% if entity.mainCenter %}
|
||||||
{{ entity.mainCenter.name }}
|
, {{ entity.mainCenter.name }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</div>
|
||||||
<td>
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-edit" href="{{ path('chill_crud_admin_user_edit', { 'id': entity.id }) }}"></a>
|
<a class="btn btn-edit" href="{{ path('chill_crud_admin_user_edit', { 'id': entity.id }) }}"></a>
|
||||||
@ -52,9 +51,12 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</div>
|
||||||
</tr>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endblock %}
|
|
||||||
{% endembed %}
|
{{ chill_pagination(paginator) }}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -9,6 +9,12 @@
|
|||||||
<span class="item-key">{{ 'Le'|trans ~ ' : ' }}</span>
|
<span class="item-key">{{ 'Le'|trans ~ ' : ' }}</span>
|
||||||
<b>{{ step.previous.transitionAt|format_datetime('short', 'short') }}</b>
|
<b>{{ step.previous.transitionAt|format_datetime('short', 'short') }}</b>
|
||||||
</li>
|
</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 %}
|
{% else %}
|
||||||
<li>
|
<li>
|
||||||
<span class="item-key">{{ 'workflow.Created by'|trans ~ ' : ' }}</span>
|
<span class="item-key">{{ 'workflow.Created by'|trans ~ ' : ' }}</span>
|
||||||
|
@ -14,6 +14,7 @@ namespace Chill\MainBundle\Routing\MenuBuilder;
|
|||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
@ -22,23 +23,20 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
*/
|
*/
|
||||||
class SectionMenuBuilder implements LocalMenuBuilderInterface
|
class SectionMenuBuilder implements LocalMenuBuilderInterface
|
||||||
{
|
{
|
||||||
/**
|
protected AuthorizationCheckerInterface $authorizationChecker;
|
||||||
* @var AuthorizationCheckerInterface
|
|
||||||
*/
|
|
||||||
protected $authorizationChecker;
|
|
||||||
|
|
||||||
/**
|
protected ParameterBagInterface $parameterBag;
|
||||||
* @var TranslatorInterface
|
|
||||||
*/
|
protected TranslatorInterface $translator;
|
||||||
protected $translator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SectionMenuBuilder constructor.
|
* SectionMenuBuilder constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(AuthorizationCheckerInterface $authorizationChecker, TranslatorInterface $translator)
|
public function __construct(AuthorizationCheckerInterface $authorizationChecker, TranslatorInterface $translator, ParameterBagInterface $parameterBag)
|
||||||
{
|
{
|
||||||
$this->authorizationChecker = $authorizationChecker;
|
$this->authorizationChecker = $authorizationChecker;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
|
$this->parameterBag = $parameterBag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,6 +52,7 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
'order' => 0,
|
'order' => 0,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if ($this->parameterBag->get('chill_main.access_global_history')) {
|
||||||
$menu->addChild($this->translator->trans('Global timeline'), [
|
$menu->addChild($this->translator->trans('Global timeline'), [
|
||||||
'route' => 'chill_center_timeline',
|
'route' => 'chill_center_timeline',
|
||||||
])
|
])
|
||||||
@ -62,6 +61,7 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
'order' => 10,
|
'order' => 10,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->authorizationChecker->isGranted(ChillExportVoter::EXPORT)) {
|
if ($this->authorizationChecker->isGranted(ChillExportVoter::EXPORT)) {
|
||||||
$menu->addChild($this->translator->trans('Export Menu'), [
|
$menu->addChild($this->translator->trans('Export Menu'), [
|
||||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\MainBundle\Search;
|
namespace Chill\MainBundle\Search;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Pagination\Paginator;
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
use Chill\MainBundle\Serializer\Model\Collection;
|
use Chill\MainBundle\Serializer\Model\Collection;
|
||||||
use Doctrine\DBAL\Types\Types;
|
use Doctrine\DBAL\Types\Types;
|
||||||
@ -102,9 +103,9 @@ class SearchApi
|
|||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildUnionQuery(array $queries, $types, $parameters)
|
private function buildUnionQuery(array $queries, $types, $parameters, Paginator $paginator)
|
||||||
{
|
{
|
||||||
$query = '{unions} ORDER BY pertinence DESC';
|
$query = '{unions} ORDER BY pertinence DESC LIMIT ? OFFSET ?';
|
||||||
$unions = [];
|
$unions = [];
|
||||||
$parameters = [];
|
$parameters = [];
|
||||||
|
|
||||||
@ -113,6 +114,10 @@ class SearchApi
|
|||||||
$parameters = array_merge($parameters, $q->buildParameters());
|
$parameters = array_merge($parameters, $q->buildParameters());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add pagination limit
|
||||||
|
$parameters[] = $paginator->getItemsPerPage();
|
||||||
|
$parameters[] = $paginator->getCurrentPageFirstItemNumber();
|
||||||
|
|
||||||
$union = implode(' UNION ', $unions);
|
$union = implode(' UNION ', $unions);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@ -132,9 +137,9 @@ class SearchApi
|
|||||||
return (int) $countNq->getSingleScalarResult();
|
return (int) $countNq->getSingleScalarResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function fetchRawResult($queries, $types, $parameters, $paginator): array
|
private function fetchRawResult($queries, $types, $parameters, Paginator $paginator): array
|
||||||
{
|
{
|
||||||
[$union, $parameters] = $this->buildUnionQuery($queries, $types, $parameters);
|
[$union, $parameters] = $this->buildUnionQuery($queries, $types, $parameters, $paginator);
|
||||||
$rsm = new ResultSetMappingBuilder($this->em);
|
$rsm = new ResultSetMappingBuilder($this->em);
|
||||||
$rsm->addScalarResult('key', 'key', Types::STRING)
|
$rsm->addScalarResult('key', 'key', Types::STRING)
|
||||||
->addScalarResult('metadata', 'metadata', Types::JSON)
|
->addScalarResult('metadata', 'metadata', Types::JSON)
|
||||||
|
@ -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),
|
'postcode' => $helper->normalize(self::NULL_POSTCODE_COUNTRY, $format, $context),
|
||||||
'country' => $helper->normalize(self::NULL_POSTCODE_COUNTRY, $format, $context),
|
'country' => $helper->normalize(self::NULL_POSTCODE_COUNTRY, $format, $context),
|
||||||
|
'lines' => [],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ class CommentEmbeddableDocGenNormalizer implements ContextAwareNormalizerInterfa
|
|||||||
*/
|
*/
|
||||||
public function normalize($object, ?string $format = null, array $context = []): array
|
public function normalize($object, ?string $format = null, array $context = []): array
|
||||||
{
|
{
|
||||||
if (null === $object) {
|
if (null === $object || ($object->isEmpty())) {
|
||||||
return [
|
return [
|
||||||
'comment' => '',
|
'comment' => '',
|
||||||
'isNull' => true,
|
'isNull' => true,
|
||||||
@ -52,7 +52,11 @@ class CommentEmbeddableDocGenNormalizer implements ContextAwareNormalizerInterfa
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null === $object->getUserId()) {
|
||||||
|
$user = null;
|
||||||
|
} else {
|
||||||
$user = $this->userRepository->find($object->getUserId());
|
$user = $this->userRepository->find($object->getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'comment' => $object->getComment(),
|
'comment' => $object->getComment(),
|
||||||
|
@ -16,10 +16,10 @@ use libphonenumber\PhoneNumber;
|
|||||||
use libphonenumber\PhoneNumberUtil;
|
use libphonenumber\PhoneNumberUtil;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
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;
|
private string $defaultCarrierCode;
|
||||||
|
|
||||||
@ -40,6 +40,10 @@ class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterfac
|
|||||||
*/
|
*/
|
||||||
public function denormalize($data, $type, $format = null, array $context = [])
|
public function denormalize($data, $type, $format = null, array $context = [])
|
||||||
{
|
{
|
||||||
|
if ('' === trim($data)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return $this->phoneNumberUtil->parse($data, $this->defaultCarrierCode);
|
return $this->phoneNumberUtil->parse($data, $this->defaultCarrierCode);
|
||||||
} catch (NumberParseException $e) {
|
} catch (NumberParseException $e) {
|
||||||
@ -49,6 +53,10 @@ class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterfac
|
|||||||
|
|
||||||
public function normalize($object, ?string $format = null, array $context = []): string
|
public function normalize($object, ?string $format = null, array $context = []): string
|
||||||
{
|
{
|
||||||
|
if ('docgen' === $format && null === $object) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
return $this->phoneNumberUtil->formatOutOfCountryCallingNumber($object, $this->defaultCarrierCode);
|
return $this->phoneNumberUtil->formatOutOfCountryCallingNumber($object, $this->defaultCarrierCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +65,18 @@ class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterfac
|
|||||||
return 'libphonenumber\PhoneNumber' === $type;
|
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 && 'json' === $format) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('docgen' === $format && (
|
||||||
|
$data instanceof PhoneNumber || PhoneNumber::class === ($context['docgen:expects'] ?? null)
|
||||||
|
)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,10 +100,10 @@ final class UserControllerTest extends WebTestCase
|
|||||||
$crawler = $this->client->followRedirect();
|
$crawler = $this->client->followRedirect();
|
||||||
|
|
||||||
// Check data in the show view
|
// Check data in the show view
|
||||||
$this->assertGreaterThan(
|
$this->assertStringContainsString(
|
||||||
0,
|
'Test_user',
|
||||||
$crawler->filter('td:contains("Test_user")')->count(),
|
$crawler->text(),
|
||||||
'Missing element td:contains("Test user")'
|
'page contains the name of the user'
|
||||||
);
|
);
|
||||||
|
|
||||||
//test the auth of the new client
|
//test the auth of the new client
|
||||||
@ -125,11 +125,7 @@ final class UserControllerTest extends WebTestCase
|
|||||||
$this->client->submit($form);
|
$this->client->submit($form);
|
||||||
$crawler = $this->client->followRedirect();
|
$crawler = $this->client->followRedirect();
|
||||||
// Check the element contains an attribute with value equals "Foo"
|
// Check the element contains an attribute with value equals "Foo"
|
||||||
$this->assertGreaterThan(
|
$this->assertResponseIsSuccessful();
|
||||||
0,
|
|
||||||
$crawler->filter('[data-username="' . $username . '"]')->count(),
|
|
||||||
'Missing element [data-username="Foo bar"]'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +43,7 @@ final class ValidPhonenumber extends ConstraintValidator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('' === $value) {
|
if (null === $value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,12 +15,19 @@ use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
|||||||
|
|
||||||
interface EntityWorkflowHandlerInterface
|
interface EntityWorkflowHandlerInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @return array|string[]
|
||||||
|
*/
|
||||||
|
public function getDeletionRoles(): array;
|
||||||
|
|
||||||
public function getEntityData(EntityWorkflow $entityWorkflow, array $options = []): array;
|
public function getEntityData(EntityWorkflow $entityWorkflow, array $options = []): array;
|
||||||
|
|
||||||
public function getEntityTitle(EntityWorkflow $entityWorkflow, array $options = []): string;
|
public function getEntityTitle(EntityWorkflow $entityWorkflow, array $options = []): string;
|
||||||
|
|
||||||
public function getRelatedEntity(EntityWorkflow $entityWorkflow): ?object;
|
public function getRelatedEntity(EntityWorkflow $entityWorkflow): ?object;
|
||||||
|
|
||||||
|
public function getRelatedObjects(object $object): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a string representing the role required for seeing the workflow.
|
* 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 getTemplateData(EntityWorkflow $entityWorkflow, array $options = []): array;
|
||||||
|
|
||||||
|
public function isObjectSupported(object $object): bool;
|
||||||
|
|
||||||
public function supports(EntityWorkflow $entityWorkflow, array $options = []): bool;
|
public function supports(EntityWorkflow $entityWorkflow, array $options = []): bool;
|
||||||
|
|
||||||
public function supportsFreeze(EntityWorkflow $entityWorkflow, array $options = []): bool;
|
public function supportsFreeze(EntityWorkflow $entityWorkflow, array $options = []): bool;
|
||||||
|
@ -13,9 +13,8 @@ services:
|
|||||||
- { name: 'chill.menu_builder' }
|
- { name: 'chill.menu_builder' }
|
||||||
|
|
||||||
Chill\MainBundle\Routing\MenuBuilder\SectionMenuBuilder:
|
Chill\MainBundle\Routing\MenuBuilder\SectionMenuBuilder:
|
||||||
arguments:
|
autowire: true
|
||||||
$authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface'
|
autoconfigure: true
|
||||||
$translator: '@Symfony\Contracts\Translation\TranslatorInterface'
|
|
||||||
tags:
|
tags:
|
||||||
- { name: 'chill.menu_builder' }
|
- { name: 'chill.menu_builder' }
|
||||||
|
|
||||||
|
@ -75,3 +75,9 @@ services:
|
|||||||
$locker: '@Chill\MainBundle\Security\PasswordRecover\PasswordRecoverLocker'
|
$locker: '@Chill\MainBundle\Security\PasswordRecover\PasswordRecoverLocker'
|
||||||
tags:
|
tags:
|
||||||
- { name: security.voter }
|
- { 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 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 transitionned: Anciens workflows
|
||||||
Previous workflow transitionned help: Workflows où vous avez exécuté une action.
|
Previous workflow transitionned help: Workflows où vous avez exécuté une action.
|
||||||
|
For: Pour
|
||||||
|
|
||||||
|
|
||||||
Subscribe final: Recevoir une notification à l'étape finale
|
Subscribe final: Recevoir une notification à l'étape finale
|
||||||
|
@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Controller;
|
|||||||
|
|
||||||
use Chill\ActivityBundle\Entity\Activity;
|
use Chill\ActivityBundle\Entity\Activity;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\Household\Household;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Form\AccompanyingCourseType;
|
use Chill\PersonBundle\Form\AccompanyingCourseType;
|
||||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
||||||
@ -279,6 +280,40 @@ class AccompanyingCourseController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route("/{_locale}/person/household/parcours/new", name="chill_household_accompanying_course_new")
|
||||||
|
*/
|
||||||
|
public function newHouseholdParcoursAction(Request $request): Response
|
||||||
|
{
|
||||||
|
$period = new AccompanyingPeriod();
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
|
if ($request->query->has('household_id')) {
|
||||||
|
$householdId = $request->query->get('household_id');
|
||||||
|
|
||||||
|
$household = $em->getRepository(Household::class)->find($householdId);
|
||||||
|
$members = $household->getCurrentMembers();
|
||||||
|
|
||||||
|
if (null !== $members) {
|
||||||
|
foreach ($members as $m) {
|
||||||
|
$period->addPerson($m->getPerson());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$userLocation = $this->getUser()->getCurrentLocation();
|
||||||
|
$period->setAdministrativeLocation($userLocation);
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period);
|
||||||
|
|
||||||
|
$em->persist($period);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('chill_person_accompanying_course_edit', [
|
||||||
|
'accompanying_period_id' => $period->getId(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/{_locale}/parcours/{accompanying_period_id}/open", name="chill_person_accompanying_course_reopen")
|
* @Route("/{_locale}/parcours/{accompanying_period_id}/open", name="chill_person_accompanying_course_reopen")
|
||||||
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
|
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
|
||||||
|
@ -222,6 +222,10 @@ class AccompanyingPeriodController extends AbstractController
|
|||||||
$accompanyingPeriodsRaw = $this->accompanyingPeriodACLAwareRepository
|
$accompanyingPeriodsRaw = $this->accompanyingPeriodACLAwareRepository
|
||||||
->findByPerson($person, AccompanyingPeriodVoter::SEE);
|
->findByPerson($person, AccompanyingPeriodVoter::SEE);
|
||||||
|
|
||||||
|
usort($accompanyingPeriodsRaw, static function ($a, $b) {
|
||||||
|
return $b->getOpeningDate() > $a->getOpeningDate();
|
||||||
|
});
|
||||||
|
|
||||||
// filter visible or not visible
|
// filter visible or not visible
|
||||||
$accompanyingPeriods = array_filter($accompanyingPeriodsRaw, function (AccompanyingPeriod $ap) {
|
$accompanyingPeriods = array_filter($accompanyingPeriodsRaw, function (AccompanyingPeriod $ap) {
|
||||||
return $this->isGranted(AccompanyingPeriodVoter::SEE, $ap);
|
return $this->isGranted(AccompanyingPeriodVoter::SEE, $ap);
|
||||||
|
@ -134,7 +134,7 @@ class HouseholdCompositionController extends AbstractController
|
|||||||
public function index(Household $household, Request $request): Response
|
public function index(Household $household, Request $request): Response
|
||||||
{
|
{
|
||||||
if (!$this->security->isGranted(HouseholdVoter::SEE, $household)) {
|
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);
|
$count = $this->householdCompositionRepository->countByHousehold($household);
|
||||||
@ -146,6 +146,20 @@ class HouseholdCompositionController extends AbstractController
|
|||||||
$paginator->getCurrentPageFirstItemNumber()
|
$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)) {
|
if ($this->security->isGranted(HouseholdVoter::EDIT, $household)) {
|
||||||
$isEdit = $request->query->has('edit');
|
$isEdit = $request->query->has('edit');
|
||||||
|
|
||||||
@ -195,10 +209,9 @@ class HouseholdCompositionController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new Response($this->engine->render(
|
return new Response($this->engine->render(
|
||||||
'@ChillPerson/HouseholdComposition/index.html.twig',
|
'@ChillPerson/HouseholdComposition/create.html.twig',
|
||||||
[
|
[
|
||||||
'household' => $household,
|
'household' => $household,
|
||||||
'compositions' => $compositions,
|
|
||||||
'form' => isset($form) ? $form->createView() : null,
|
'form' => isset($form) ? $form->createView() : null,
|
||||||
'isPosted' => isset($form) ? $form->isSubmitted() : false,
|
'isPosted' => isset($form) ? $form->isSubmitted() : false,
|
||||||
'editId' => $request->query->getInt('edit', -1),
|
'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();
|
$oldMembers = $household->getNonCurrentMembers();
|
||||||
$accompanyingPeriodsOld = [];
|
$accompanyingPeriodsOld = [];
|
||||||
|
|
||||||
|
@ -133,6 +133,19 @@ final class PersonResourceController extends AbstractController
|
|||||||
$personResources = [];
|
$personResources = [];
|
||||||
$personResources = $this->personResourceRepository->findBy(['personOwner' => $personOwner->getId()]);
|
$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 = $this->createForm(PersonResourceType::class);
|
||||||
|
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
@ -165,11 +178,10 @@ final class PersonResourceController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this->render(
|
return $this->render(
|
||||||
'ChillPersonBundle:PersonResource:list.html.twig',
|
'ChillPersonBundle:PersonResource:create.html.twig',
|
||||||
[
|
[
|
||||||
'person' => $personOwner,
|
|
||||||
'personResources' => $personResources,
|
|
||||||
'form' => $form->createView(),
|
'form' => $form->createView(),
|
||||||
|
'person' => $personOwner,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
|
use Chill\MainBundle\Repository\UserRepository;
|
||||||
|
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||||
|
use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
use Symfony\Component\Templating\EngineInterface;
|
||||||
|
|
||||||
|
class ReassignAccompanyingPeriodController extends AbstractController
|
||||||
|
{
|
||||||
|
private AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository;
|
||||||
|
|
||||||
|
private EngineInterface $engine;
|
||||||
|
|
||||||
|
private FormFactoryInterface $formFactory;
|
||||||
|
|
||||||
|
private PaginatorFactory $paginatorFactory;
|
||||||
|
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
|
private UserRender $userRender;
|
||||||
|
|
||||||
|
private UserRepository $userRepository;
|
||||||
|
|
||||||
|
public function __construct(AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository, UserRepository $userRepository, EngineInterface $engine, FormFactoryInterface $formFactory, PaginatorFactory $paginatorFactory, Security $security, UserRender $userRender)
|
||||||
|
{
|
||||||
|
$this->accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository;
|
||||||
|
$this->engine = $engine;
|
||||||
|
$this->formFactory = $formFactory;
|
||||||
|
$this->paginatorFactory = $paginatorFactory;
|
||||||
|
$this->security = $security;
|
||||||
|
$this->userRepository = $userRepository;
|
||||||
|
$this->userRender = $userRender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route("/{_locale}/person/accompanying-periods/reassign", name="chill_course_list_reassign")
|
||||||
|
*/
|
||||||
|
public function listAction(Request $request): Response
|
||||||
|
{
|
||||||
|
if (!$this->security->isGranted('ROLE_USER') || !$this->security->getUser() instanceof User) {
|
||||||
|
throw new AccessDeniedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = $this->buildFilterForm();
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
$total = $this->accompanyingPeriodACLAwareRepository->countByUserOpenedAccompanyingPeriod(
|
||||||
|
$form['user']->getData()
|
||||||
|
);
|
||||||
|
$paginator = $this->paginatorFactory->create($total);
|
||||||
|
$periods = $this->accompanyingPeriodACLAwareRepository
|
||||||
|
->findByUserOpenedAccompanyingPeriod(
|
||||||
|
$form['user']->getData(),
|
||||||
|
['openingDate' => 'ASC'],
|
||||||
|
$paginator->getItemsPerPage(),
|
||||||
|
$paginator->getCurrentPageFirstItemNumber()
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
$this->engine->render('@ChillPerson/AccompanyingPeriod/reassign_list.html.twig', [
|
||||||
|
'paginator' => $paginator,
|
||||||
|
'periods' => $periods,
|
||||||
|
'form' => $form->createView(),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildFilterForm(): FormInterface
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'user' => null,
|
||||||
|
];
|
||||||
|
$builder = $this->formFactory->createBuilder(FormType::class, $data, [
|
||||||
|
'method' => 'get', 'csrf_protection' => false, ]);
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->add('user', EntityType::class, [
|
||||||
|
'class' => User::class,
|
||||||
|
'choices' => $this->userRepository->findByActive(['username' => 'ASC']),
|
||||||
|
'choice_label' => function (User $u) {
|
||||||
|
return $this->userRender->renderString($u, []);
|
||||||
|
},
|
||||||
|
'multiple' => false,
|
||||||
|
'label' => 'User',
|
||||||
|
'required' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $builder->getForm();
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ namespace Chill\PersonBundle\Controller;
|
|||||||
|
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
||||||
use Chill\PersonBundle\Form\Type\ResidentialAddressType;
|
use Chill\PersonBundle\Form\ResidentialAddressType;
|
||||||
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
@ -15,6 +15,7 @@ use Chill\MainBundle\DependencyInjection\MissingBundleException;
|
|||||||
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
||||||
use Chill\PersonBundle\Controller\HouseholdCompositionTypeApiController;
|
use Chill\PersonBundle\Controller\HouseholdCompositionTypeApiController;
|
||||||
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodCommentVoter;
|
||||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodResourceVoter;
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodResourceVoter;
|
||||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
@ -58,6 +59,16 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
$config['allow_multiple_simultaneous_accompanying_periods']
|
$config['allow_multiple_simultaneous_accompanying_periods']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
'chill_person.create_person_allowed',
|
||||||
|
$config['create_person_allowed']
|
||||||
|
);
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
'chill_person.create_parcours_allowed',
|
||||||
|
$config['create_parcours_allowed']
|
||||||
|
);
|
||||||
|
|
||||||
// register all configuration in a unique parameter
|
// register all configuration in a unique parameter
|
||||||
$container->setParameter('chill_person', $config);
|
$container->setParameter('chill_person', $config);
|
||||||
|
|
||||||
@ -415,6 +426,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,
|
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod\Resource::class,
|
||||||
'name' => 'accompanying_period_resource',
|
'name' => 'accompanying_period_resource',
|
||||||
|
@ -62,6 +62,12 @@ class Configuration implements ConfigurationInterface
|
|||||||
->end() // children for 'validation', parent = validation
|
->end() // children for 'validation', parent = validation
|
||||||
->end() //validation, parent = children of root
|
->end() //validation, parent = children of root
|
||||||
->end() // children of root, parent = root
|
->end() // children of root, parent = root
|
||||||
|
->booleanNode('create_person_allowed')
|
||||||
|
->defaultTrue()
|
||||||
|
->end()
|
||||||
|
->booleanNode('create_parcours_allowed')
|
||||||
|
->defaultTrue()
|
||||||
|
->end()
|
||||||
->arrayNode('person_fields')
|
->arrayNode('person_fields')
|
||||||
->canBeDisabled()
|
->canBeDisabled()
|
||||||
->children()
|
->children()
|
||||||
|
@ -257,9 +257,11 @@ class AccompanyingPeriod implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(
|
* @ORM\ManyToOne(
|
||||||
* targetEntity=Comment::class
|
* targetEntity=Comment::class,
|
||||||
|
* cascade={"persist"},
|
||||||
* )
|
* )
|
||||||
* @Groups({"read"})
|
* @Groups({"read"})
|
||||||
|
* @ORM\JoinColumn(onDelete="SET NULL")
|
||||||
*/
|
*/
|
||||||
private ?Comment $pinnedComment = null;
|
private ?Comment $pinnedComment = null;
|
||||||
|
|
||||||
|
@ -142,6 +142,15 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
*/
|
*/
|
||||||
private Collection $persons;
|
private Collection $persons;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToMany(targetEntity=User::class)
|
||||||
|
* @ORM\JoinTable(name="chill_person_accompanying_period_work_referrer")
|
||||||
|
* @Serializer\Groups({"read", "docgen:read", "read:accompanyingPeriodWork:light"})
|
||||||
|
* @Serializer\Groups({"accompanying_period_work:edit"})
|
||||||
|
* @Serializer\Groups({"accompanying_period_work:create"})
|
||||||
|
*/
|
||||||
|
private Collection $referrers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="accompanyingPeriodWorks")
|
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="accompanyingPeriodWorks")
|
||||||
* @ORM\JoinTable(name="chill_person_accompanying_period_work_result")
|
* @ORM\JoinTable(name="chill_person_accompanying_period_work_result")
|
||||||
@ -196,6 +205,7 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
$this->thirdParties = new ArrayCollection();
|
$this->thirdParties = new ArrayCollection();
|
||||||
$this->persons = new ArrayCollection();
|
$this->persons = new ArrayCollection();
|
||||||
$this->accompanyingPeriodWorkEvaluations = new ArrayCollection();
|
$this->accompanyingPeriodWorkEvaluations = new ArrayCollection();
|
||||||
|
$this->referrers = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addAccompanyingPeriodWorkEvaluation(AccompanyingPeriodWorkEvaluation $evaluation): self
|
public function addAccompanyingPeriodWorkEvaluation(AccompanyingPeriodWorkEvaluation $evaluation): self
|
||||||
@ -227,6 +237,15 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addReferrer(User $referrer): self
|
||||||
|
{
|
||||||
|
if (!$this->referrers->contains($referrer)) {
|
||||||
|
$this->referrers[] = $referrer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function addResult(Result $result): self
|
public function addResult(Result $result): self
|
||||||
{
|
{
|
||||||
if (!$this->results->contains($result)) {
|
if (!$this->results->contains($result)) {
|
||||||
@ -308,6 +327,14 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
return $this->persons;
|
return $this->persons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection|User[]
|
||||||
|
*/
|
||||||
|
public function getReferrers(): Collection
|
||||||
|
{
|
||||||
|
return $this->referrers;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection|Result[]
|
* @return Collection|Result[]
|
||||||
*/
|
*/
|
||||||
@ -382,6 +409,13 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function removeReferrer(User $referrer): self
|
||||||
|
{
|
||||||
|
$this->referrers->removeElement($referrer);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function removeResult(Result $result): self
|
public function removeResult(Result $result): self
|
||||||
{
|
{
|
||||||
$this->results->removeElement($result);
|
$this->results->removeElement($result);
|
||||||
|
@ -124,6 +124,7 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
|||||||
/**
|
/**
|
||||||
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
|
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
|
||||||
* @Serializer\Groups({"read", "docgen:read"})
|
* @Serializer\Groups({"read", "docgen:read"})
|
||||||
|
* @Serializer\Groups({"write"})
|
||||||
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
|
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
|
||||||
*/
|
*/
|
||||||
private ?DateTimeImmutable $maxDate = null;
|
private ?DateTimeImmutable $maxDate = null;
|
||||||
|
@ -28,6 +28,7 @@ use Chill\PersonBundle\Entity\Household\Household;
|
|||||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||||
use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress;
|
use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress;
|
||||||
use Chill\PersonBundle\Entity\Person\PersonCurrentAddress;
|
use Chill\PersonBundle\Entity\Person\PersonCurrentAddress;
|
||||||
|
use Chill\PersonBundle\Entity\Person\PersonResource;
|
||||||
use Chill\PersonBundle\Validator\Constraints\Household\HouseholdMembershipSequential;
|
use Chill\PersonBundle\Validator\Constraints\Household\HouseholdMembershipSequential;
|
||||||
use Chill\PersonBundle\Validator\Constraints\Person\Birthdate;
|
use Chill\PersonBundle\Validator\Constraints\Person\Birthdate;
|
||||||
use Chill\PersonBundle\Validator\Constraints\Person\PersonHasCenter;
|
use Chill\PersonBundle\Validator\Constraints\Person\PersonHasCenter;
|
||||||
@ -111,6 +112,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
* @ORM\OneToMany(targetEntity=AccompanyingPeriodParticipation::class,
|
* @ORM\OneToMany(targetEntity=AccompanyingPeriodParticipation::class,
|
||||||
* mappedBy="person",
|
* mappedBy="person",
|
||||||
* cascade={"persist", "remove", "merge", "detach"})
|
* cascade={"persist", "remove", "merge", "detach"})
|
||||||
|
* @ORM\OrderBy({"startDate": "DESC"})
|
||||||
*/
|
*/
|
||||||
private $accompanyingPeriodParticipations;
|
private $accompanyingPeriodParticipations;
|
||||||
|
|
||||||
@ -468,6 +470,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
*/
|
*/
|
||||||
private $proxyAccompanyingPeriodOpenState = false; //TO-DELETE ?
|
private $proxyAccompanyingPeriodOpenState = false; //TO-DELETE ?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(targetEntity=PersonResource::class, mappedBy="personOwner")
|
||||||
|
*
|
||||||
|
* @var Collection|PersonResource[];
|
||||||
|
*/
|
||||||
|
private Collection $resources;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The person's spoken languages.
|
* The person's spoken languages.
|
||||||
*
|
*
|
||||||
@ -512,6 +521,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
$this->accompanyingPeriodRequested = new ArrayCollection();
|
$this->accompanyingPeriodRequested = new ArrayCollection();
|
||||||
$this->budgetResources = new ArrayCollection();
|
$this->budgetResources = new ArrayCollection();
|
||||||
$this->budgetCharges = new ArrayCollection();
|
$this->budgetCharges = new ArrayCollection();
|
||||||
|
$this->resources = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1272,7 +1282,20 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
return $this->placeOfBirth;
|
return $this->placeOfBirth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSpokenLanguages(): ?Collection
|
/**
|
||||||
|
* @return PersonResource[]|Collection
|
||||||
|
*/
|
||||||
|
public function getResources()
|
||||||
|
{
|
||||||
|
return $this->resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get spokenLanguages.
|
||||||
|
*
|
||||||
|
* @return ArrayCollection
|
||||||
|
*/
|
||||||
|
public function getSpokenLanguages()
|
||||||
{
|
{
|
||||||
return $this->spokenLanguages;
|
return $this->spokenLanguages;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
|||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
use Symfony\Component\Serializer\Annotation\Groups;
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
@ -27,7 +27,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
|||||||
/**
|
/**
|
||||||
* @ORM\Entity
|
* @ORM\Entity
|
||||||
* @ORM\Table(name="chill_person_resource")
|
* @ORM\Table(name="chill_person_resource")
|
||||||
* @DiscriminatorMap(typeProperty="type", mapping={
|
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
|
||||||
* "personResource": personResource::class
|
* "personResource": personResource::class
|
||||||
* })
|
* })
|
||||||
*/
|
*/
|
||||||
@ -39,13 +39,13 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_")
|
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_")
|
||||||
* @Groups({"read"})
|
* @Serializer\Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private CommentEmbeddable $comment;
|
private CommentEmbeddable $comment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", nullable=true)
|
* @ORM\Column(type="text", nullable=true)
|
||||||
* @Groups({"read"})
|
* @Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private ?string $freeText = null;
|
private ?string $freeText = null;
|
||||||
|
|
||||||
@ -53,25 +53,30 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
* @ORM\GeneratedValue
|
* @ORM\GeneratedValue
|
||||||
* @ORM\Column(type="integer")
|
* @ORM\Column(type="integer")
|
||||||
|
* @Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private ?int $id;
|
private ?int $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=PersonResourceKind::class, inversedBy="personResources")
|
* @ORM\ManyToOne(targetEntity=PersonResourceKind::class, inversedBy="personResources")
|
||||||
* @ORM\JoinColumn(nullable=true)
|
* @ORM\JoinColumn(nullable=true)
|
||||||
* @Groups({"read"})
|
* @Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private $kind;
|
private ?PersonResourceKind $kind = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=Person::class, inversedBy="personResources")
|
* The person which host the owner of this resource.
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity=Person::class)
|
||||||
* @ORM\JoinColumn(nullable=true)
|
* @ORM\JoinColumn(nullable=true)
|
||||||
* @Groups({"read"})
|
* @Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private ?Person $person = null;
|
private ?Person $person = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=Person::class)
|
* The person linked with this resource.
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity=Person::class, inversedBy="resources")
|
||||||
* @ORM\JoinColumn(nullable=false)
|
* @ORM\JoinColumn(nullable=false)
|
||||||
* @Groups({"read"})
|
* @Groups({"read"})
|
||||||
*/
|
*/
|
||||||
@ -80,7 +85,7 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=ThirdParty::class, inversedBy="personResources")
|
* @ORM\ManyToOne(targetEntity=ThirdParty::class, inversedBy="personResources")
|
||||||
* @ORM\JoinColumn(nullable=true)
|
* @ORM\JoinColumn(nullable=true)
|
||||||
* @Groups({"read"})
|
* @Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private ?ThirdParty $thirdParty = null;
|
private ?ThirdParty $thirdParty = null;
|
||||||
|
|
||||||
@ -122,6 +127,26 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
return $this->personOwner;
|
return $this->personOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Groups({"read", "docgen:read"})
|
||||||
|
*/
|
||||||
|
public function getResourceKind(): string
|
||||||
|
{
|
||||||
|
if ($this->getPerson() instanceof Person) {
|
||||||
|
return 'person';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getThirdParty() instanceof ThirdParty) {
|
||||||
|
return 'thirdparty';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $this->getFreeText()) {
|
||||||
|
return 'freetext';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'none';
|
||||||
|
}
|
||||||
|
|
||||||
public function getThirdParty(): ?ThirdParty
|
public function getThirdParty(): ?ThirdParty
|
||||||
{
|
{
|
||||||
return $this->thirdParty;
|
return $this->thirdParty;
|
||||||
@ -205,5 +230,10 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
$context->buildViolation('You must associate at least one entity')
|
$context->buildViolation('You must associate at least one entity')
|
||||||
->addViolation();
|
->addViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null !== $this->person && $this->person === $this->personOwner) {
|
||||||
|
$context->buildViolation('You cannot associate a resource with the same person')
|
||||||
|
->addViolation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,9 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Entity\Person;
|
namespace Chill\PersonBundle\Entity\Person;
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **About denormalization**: this operation is operated by @see{AccompanyingPeriodResourdeNormalizer}.
|
|
||||||
*
|
|
||||||
* @ORM\Entity
|
* @ORM\Entity
|
||||||
* @ORM\Table(name="chill_person_resource_kind")
|
* @ORM\Table(name="chill_person_resource_kind")
|
||||||
*/
|
*/
|
||||||
@ -25,8 +24,9 @@ class PersonResourceKind
|
|||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
* @ORM\GeneratedValue
|
* @ORM\GeneratedValue
|
||||||
* @ORM\Column(type="integer")
|
* @ORM\Column(type="integer")
|
||||||
|
* @Serializer\Groups({"docgen:read"})
|
||||||
*/
|
*/
|
||||||
private int $id;
|
private ?int $id = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
@ -35,6 +35,8 @@ class PersonResourceKind
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json", length=255)
|
* @ORM\Column(type="json", length=255)
|
||||||
|
* @Serializer\Groups({"docgen:read"})
|
||||||
|
* @Serializer\Context({"is-translatable": true}, groups={"docgen:read"})
|
||||||
*/
|
*/
|
||||||
private array $title;
|
private array $title;
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Entity;
|
|||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use libphonenumber\PhoneNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Person Phones.
|
* Person Phones.
|
||||||
@ -51,9 +52,9 @@ class PersonPhone
|
|||||||
private Person $person;
|
private Person $person;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", length=40, nullable=false)
|
* @ORM\Column(type="phone_number", nullable=false)
|
||||||
*/
|
*/
|
||||||
private string $phonenumber = '';
|
private ?PhoneNumber $phonenumber = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", length=40, nullable=true)
|
* @ORM\Column(type="text", length=40, nullable=true)
|
||||||
@ -85,7 +86,7 @@ class PersonPhone
|
|||||||
return $this->person;
|
return $this->person;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPhonenumber(): string
|
public function getPhonenumber(): ?PhoneNumber
|
||||||
{
|
{
|
||||||
return $this->phonenumber;
|
return $this->phonenumber;
|
||||||
}
|
}
|
||||||
@ -97,7 +98,8 @@ class PersonPhone
|
|||||||
|
|
||||||
public function isEmpty(): bool
|
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
|
public function setDate(DateTime $date): void
|
||||||
@ -115,7 +117,7 @@ class PersonPhone
|
|||||||
$this->person = $person;
|
$this->person = $person;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPhonenumber(string $phonenumber): void
|
public function setPhonenumber(?PhoneNumber $phonenumber): void
|
||||||
{
|
{
|
||||||
$this->phonenumber = $phonenumber;
|
$this->phonenumber = $phonenumber;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,12 @@ class Evaluation
|
|||||||
*/
|
*/
|
||||||
private array $title = [];
|
private array $title = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="text", nullable=true)
|
||||||
|
* @Serializer\Groups({"read", "docgen:read"})
|
||||||
|
*/
|
||||||
|
private ?string $url = null;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->socialActions = new ArrayCollection();
|
$this->socialActions = new ArrayCollection();
|
||||||
@ -101,6 +107,11 @@ class Evaluation
|
|||||||
return $this->title;
|
return $this->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUrl(): ?string
|
||||||
|
{
|
||||||
|
return $this->url;
|
||||||
|
}
|
||||||
|
|
||||||
public function removeSocialAction(SocialAction $socialAction): self
|
public function removeSocialAction(SocialAction $socialAction): self
|
||||||
{
|
{
|
||||||
if ($this->socialActions->contains($socialAction)) {
|
if ($this->socialActions->contains($socialAction)) {
|
||||||
@ -130,4 +141,11 @@ class Evaluation
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setUrl(?string $url): self
|
||||||
|
{
|
||||||
|
$this->url = $url;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\EventListener;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
class AccompanyingPeriodWorkEventListener
|
||||||
|
{
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
|
public function __construct(Security $security)
|
||||||
|
{
|
||||||
|
$this->security = $security;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prePersistAccompanyingPeriodWork(AccompanyingPeriodWork $work): void
|
||||||
|
{
|
||||||
|
if ($this->security->getUser() instanceof User) {
|
||||||
|
$work->addReferrer($this->security->getUser());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,7 @@ use Chill\PersonBundle\Entity\Person;
|
|||||||
use Chill\PersonBundle\Entity\PersonPhone;
|
use Chill\PersonBundle\Entity\PersonPhone;
|
||||||
use Chill\PersonBundle\Form\Type\GenderType;
|
use Chill\PersonBundle\Form\Type\GenderType;
|
||||||
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
||||||
|
use Chill\PersonBundle\Form\Type\PersonPhoneType;
|
||||||
use Chill\PersonBundle\Form\Type\Select2MaritalStatusType;
|
use Chill\PersonBundle\Form\Type\Select2MaritalStatusType;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
@ -158,7 +159,7 @@ class PersonType extends AbstractType
|
|||||||
}
|
}
|
||||||
|
|
||||||
$builder->add('otherPhoneNumbers', ChillCollectionType::class, [
|
$builder->add('otherPhoneNumbers', ChillCollectionType::class, [
|
||||||
'entry_type' => ChillPhoneNumberType::class,
|
'entry_type' => PersonPhoneType::class,
|
||||||
'button_add_label' => 'Add new phone',
|
'button_add_label' => 'Add new phone',
|
||||||
'button_remove_label' => 'Remove phone',
|
'button_remove_label' => 'Remove phone',
|
||||||
'required' => false,
|
'required' => false,
|
||||||
|
@ -9,11 +9,12 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Form\Type;
|
namespace Chill\PersonBundle\Form;
|
||||||
|
|
||||||
use Chill\MainBundle\Form\Type\CommentType;
|
use Chill\MainBundle\Form\Type\CommentType;
|
||||||
use Chill\MainBundle\Form\Type\PickAddressType;
|
use Chill\MainBundle\Form\Type\PickAddressType;
|
||||||
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||||
use Chill\ThirdPartyBundle\Form\Type\PickThirdpartyDynamicType;
|
use Chill\ThirdPartyBundle\Form\Type\PickThirdpartyDynamicType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||||
|
@ -11,11 +11,11 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Form\Type;
|
namespace Chill\PersonBundle\Form\Type;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Form\Type\ChillPhoneNumberType;
|
||||||
use Chill\MainBundle\Phonenumber\PhonenumberHelper;
|
use Chill\MainBundle\Phonenumber\PhonenumberHelper;
|
||||||
use Chill\PersonBundle\Entity\PersonPhone;
|
use Chill\PersonBundle\Entity\PersonPhone;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\Form\AbstractType;
|
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\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Form\FormEvent;
|
use Symfony\Component\Form\FormEvent;
|
||||||
@ -36,7 +36,7 @@ class PersonPhoneType extends AbstractType
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
{
|
{
|
||||||
$builder->add('phonenumber', TelType::class, [
|
$builder->add('phonenumber', ChillPhoneNumberType::class, [
|
||||||
'label' => 'Other phonenumber',
|
'label' => 'Other phonenumber',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
]);
|
]);
|
||||||
|
@ -68,12 +68,14 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->security->isGranted(AccompanyingPeriodVoter::SEE_DETAILS, $period)) {
|
if ($this->security->isGranted(AccompanyingPeriodVoter::SEE_DETAILS, $period)) {
|
||||||
|
/*
|
||||||
$menu->addChild($this->translator->trans('Accompanying Course History'), [
|
$menu->addChild($this->translator->trans('Accompanying Course History'), [
|
||||||
'route' => 'chill_person_accompanying_course_history',
|
'route' => 'chill_person_accompanying_course_history',
|
||||||
'routeParameters' => [
|
'routeParameters' => [
|
||||||
'accompanying_period_id' => $period->getId(),
|
'accompanying_period_id' => $period->getId(),
|
||||||
], ])
|
], ])
|
||||||
->setExtras(['order' => 30]);
|
->setExtras(['order' => 30]);
|
||||||
|
*/
|
||||||
|
|
||||||
$menu->addChild($this->translator->trans('Accompanying Course Comment'), [
|
$menu->addChild($this->translator->trans('Accompanying Course Comment'), [
|
||||||
'route' => 'chill_person_accompanying_period_comment_list',
|
'route' => 'chill_person_accompanying_period_comment_list',
|
||||||
|
@ -13,7 +13,9 @@ namespace Chill\PersonBundle\Menu;
|
|||||||
|
|
||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
|
use Doctrine\ORM\Query\Parameter;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
@ -22,23 +24,20 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
*/
|
*/
|
||||||
class SectionMenuBuilder implements LocalMenuBuilderInterface
|
class SectionMenuBuilder implements LocalMenuBuilderInterface
|
||||||
{
|
{
|
||||||
/**
|
protected AuthorizationCheckerInterface $authorizationChecker;
|
||||||
* @var AuthorizationCheckerInterface
|
|
||||||
*/
|
|
||||||
protected $authorizationChecker;
|
|
||||||
|
|
||||||
/**
|
protected TranslatorInterface $translator;
|
||||||
* @var TranslatorInterface
|
|
||||||
*/
|
protected ParameterBagInterface $parameterBag;
|
||||||
protected $translator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SectionMenuBuilder constructor.
|
* SectionMenuBuilder constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(AuthorizationCheckerInterface $authorizationChecker, TranslatorInterface $translator)
|
public function __construct(AuthorizationCheckerInterface $authorizationChecker, TranslatorInterface $translator, ParameterBagInterface $parameterBag)
|
||||||
{
|
{
|
||||||
$this->authorizationChecker = $authorizationChecker;
|
$this->authorizationChecker = $authorizationChecker;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
|
$this->parameterBag = $parameterBag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +45,7 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
*/
|
*/
|
||||||
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
||||||
{
|
{
|
||||||
if ($this->authorizationChecker->isGranted(PersonVoter::CREATE)) {
|
if ($this->authorizationChecker->isGranted(PersonVoter::CREATE) && $this->parameterBag->get('chill_person.create_person_allowed')) {
|
||||||
$menu->addChild($this->translator->trans('Add a person'), [
|
$menu->addChild($this->translator->trans('Add a person'), [
|
||||||
'route' => 'chill_person_new',
|
'route' => 'chill_person_new',
|
||||||
])
|
])
|
||||||
@ -56,6 +55,7 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->parameterBag->get('chill_person.create_parcours_allowed')) {
|
||||||
$menu->addChild($this->translator->trans('Create an accompanying course'), [
|
$menu->addChild($this->translator->trans('Create an accompanying course'), [
|
||||||
'route' => 'chill_person_accompanying_course_new',
|
'route' => 'chill_person_accompanying_course_new',
|
||||||
])
|
])
|
||||||
@ -65,6 +65,15 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$menu->addChild($this->translator->trans('Accompanying courses of users'), [
|
||||||
|
'route' => 'chill_course_list_reassign',
|
||||||
|
])
|
||||||
|
->setExtras([
|
||||||
|
'order' => 12,
|
||||||
|
'icons' => ['task'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public static function getMenuIds(): array
|
public static function getMenuIds(): array
|
||||||
{
|
{
|
||||||
return ['section'];
|
return ['section'];
|
||||||
|
@ -87,9 +87,12 @@ class AccompanyingPeriodWorkEvaluationRepository implements ObjectRepository
|
|||||||
->join('work.accompanyingPeriod', 'period')
|
->join('work.accompanyingPeriod', 'period')
|
||||||
->where(
|
->where(
|
||||||
$qb->expr()->andX(
|
$qb->expr()->andX(
|
||||||
$qb->expr()->eq('period.user', ':user'),
|
|
||||||
$qb->expr()->isNull('e.endDate'),
|
$qb->expr()->isNull('e.endDate'),
|
||||||
$qb->expr()->gte(':now', $qb->expr()->diff('e.maxDate', 'e.warningInterval'))
|
$qb->expr()->gte(':now', $qb->expr()->diff('e.maxDate', 'e.warningInterval')),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->eq('period.user', ':user'),
|
||||||
|
$qb->expr()->isMemberOf(':user', 'work.referrers')
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->setParameters([
|
->setParameters([
|
||||||
|
@ -159,9 +159,12 @@ final class AccompanyingPeriodWorkRepository implements ObjectRepository
|
|||||||
->join('w.accompanyingPeriod', 'period')
|
->join('w.accompanyingPeriod', 'period')
|
||||||
->where(
|
->where(
|
||||||
$qb->expr()->andX(
|
$qb->expr()->andX(
|
||||||
$qb->expr()->eq('period.user', ':user'),
|
|
||||||
$qb->expr()->gte('w.endDate', ':since'),
|
$qb->expr()->gte('w.endDate', ':since'),
|
||||||
$qb->expr()->lte('w.startDate', ':until')
|
$qb->expr()->lte('w.startDate', ':until'),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->eq('period.user', ':user'),
|
||||||
|
$qb->expr()->isMemberOf(':user', 'w.referrers')
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->setParameters([
|
->setParameters([
|
||||||
|
@ -11,12 +11,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Repository;
|
namespace Chill\PersonBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface;
|
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use DateTime;
|
||||||
|
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodACLAwareRepositoryInterface
|
final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodACLAwareRepositoryInterface
|
||||||
@ -41,6 +43,37 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC
|
|||||||
$this->centerResolverDispatcher = $centerResolverDispatcher;
|
$this->centerResolverDispatcher = $centerResolverDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function buildQueryOpenedAccompanyingCourseByUser(?User $user)
|
||||||
|
{
|
||||||
|
$qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap');
|
||||||
|
|
||||||
|
$qb->where($qb->expr()->eq('ap.user', ':user'))
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->neq('ap.step', ':draft'),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull('ap.closingDate'),
|
||||||
|
$qb->expr()->gt('ap.closingDate', ':now')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->setParameter('user', $user)
|
||||||
|
->setParameter('now', new DateTime('now'))
|
||||||
|
->setParameter('draft', AccompanyingPeriod::STEP_DRAFT);
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function countByUserOpenedAccompanyingPeriod(?User $user): int
|
||||||
|
{
|
||||||
|
if (null === $user) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->buildQueryOpenedAccompanyingCourseByUser($user)
|
||||||
|
->select('COUNT(ap)')
|
||||||
|
->getQuery()
|
||||||
|
->getSingleScalarResult();
|
||||||
|
}
|
||||||
|
|
||||||
public function findByPerson(
|
public function findByPerson(
|
||||||
Person $person,
|
Person $person,
|
||||||
string $role,
|
string $role,
|
||||||
@ -92,4 +125,25 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC
|
|||||||
|
|
||||||
return $qb->getQuery()->getResult();
|
return $qb->getQuery()->getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|AccompanyingPeriod[]
|
||||||
|
*/
|
||||||
|
public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array
|
||||||
|
{
|
||||||
|
if (null === $user) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb = $this->buildQueryOpenedAccompanyingCourseByUser($user);
|
||||||
|
|
||||||
|
$qb->setFirstResult($offset)
|
||||||
|
->setMaxResults($limit);
|
||||||
|
|
||||||
|
foreach ($orderBy as $field => $direction) {
|
||||||
|
$qb->addOrderBy('ap.' . $field, $direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $qb->getQuery()->getResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Repository;
|
namespace Chill\PersonBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
|
||||||
interface AccompanyingPeriodACLAwareRepositoryInterface
|
interface AccompanyingPeriodACLAwareRepositoryInterface
|
||||||
{
|
{
|
||||||
|
public function countByUserOpenedAccompanyingPeriod(?User $user): int;
|
||||||
|
|
||||||
public function findByPerson(
|
public function findByPerson(
|
||||||
Person $person,
|
Person $person,
|
||||||
string $role,
|
string $role,
|
||||||
@ -22,4 +25,6 @@ interface AccompanyingPeriodACLAwareRepositoryInterface
|
|||||||
?int $limit = null,
|
?int $limit = null,
|
||||||
?int $offset = null
|
?int $offset = null
|
||||||
): array;
|
): array;
|
||||||
|
|
||||||
|
public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array;
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,16 @@ final class AccompanyingPeriodRepository implements ObjectRepository
|
|||||||
->getResult();
|
->getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findConfirmedByUser(User $user)
|
||||||
|
{
|
||||||
|
$qb = $this->createQueryBuilder('ap');
|
||||||
|
$qb->where($qb->expr()->eq('ap.user', ':user'))
|
||||||
|
->andWhere('ap.step', 'CONFIRMED')
|
||||||
|
->setParameter('user', $user);
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
public function findOneBy(array $criteria): ?AccompanyingPeriod
|
public function findOneBy(array $criteria): ?AccompanyingPeriod
|
||||||
{
|
{
|
||||||
return $this->findOneBy($criteria);
|
return $this->findOneBy($criteria);
|
||||||
|
@ -33,10 +33,23 @@ div.banner {
|
|||||||
padding-top: 1em;
|
padding-top: 1em;
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1em;
|
||||||
div.contact {
|
div.contact {
|
||||||
|
display: flex;
|
||||||
|
align-content: center;
|
||||||
& > * {
|
& > * {
|
||||||
margin-right: 1em;
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,22 +19,21 @@ import {fetchResults} from 'ChillMainAssets/lib/api/apiMethods.js';
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
document.querySelectorAll('[data-set-referrer-app]').forEach(function (el) {
|
document.querySelectorAll('[data-set-referrer-app]').forEach(function (el) {
|
||||||
let
|
const periodId = Number.parseInt(el.dataset.setReferrerAccompanyingPeriodId);
|
||||||
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`;
|
const url = `/api/1.0/person/accompanying-course/${periodId}/referrers-suggested.json`;
|
||||||
|
|
||||||
fetchResults(url).then(suggested => {
|
fetchResults(url).then(suggested => {
|
||||||
|
const filteredSuggested = suggested.filter((s) => s.user_job ? s.user_job.id === jobId : false);
|
||||||
const app = createApp({
|
const app = createApp({
|
||||||
components: {
|
components: {
|
||||||
SetReferrer,
|
SetReferrer,
|
||||||
},
|
},
|
||||||
template:
|
template:
|
||||||
'<set-referrer :suggested="suggested" :periodId="periodId" @referrerSet="onReferrerSet"></set-referrer>',
|
'<set-referrer :suggested="filteredSuggested" :periodId="periodId" @referrerSet="onReferrerSet"></set-referrer>',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
periodId, suggested, original: suggested,
|
periodId, filteredSuggested, original: filteredSuggested,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -56,7 +55,7 @@ document.querySelectorAll('[data-set-referrer-app]').forEach(function (el) {
|
|||||||
label.textContent = ref.text;
|
label.textContent = ref.text;
|
||||||
label.classList.remove('chill-no-data-statement');
|
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
|
<ckeditor
|
||||||
name="content"
|
name="content"
|
||||||
v-bind:placeholder="$t('comment.content')"
|
:placeholder="$t('comment.content')"
|
||||||
:editor="editor"
|
:editor="editor"
|
||||||
v-model="content"
|
v-model="content"
|
||||||
tag-name="textarea">
|
tag-name="textarea">
|
||||||
</ckeditor>
|
</ckeditor>
|
||||||
|
|
||||||
<div v-if="pinnedComment" class="metadata">
|
<div class="sub-comment">
|
||||||
|
<div v-if="pinnedComment !== null && typeof pinnedComment.creator !== 'undefined'" class="metadata">
|
||||||
{{ $t('comment.created_by', [
|
{{ $t('comment.created_by', [
|
||||||
pinnedComment.creator.text,
|
pinnedComment.creator.text,
|
||||||
$d(pinnedComment.createdAt.datetime, 'long')
|
$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>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>
|
|
||||||
<button type="submit" class="btn btn-save">{{ $t('action.save') }}</button>
|
|
||||||
</li>
|
|
||||||
<li v-if="pinnedComment !== null">
|
<li v-if="pinnedComment !== null">
|
||||||
<a class="btn btn-delete"
|
<a class="btn btn-delete"
|
||||||
@click="removeComment">
|
@click="removeComment">
|
||||||
@ -50,6 +53,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import CKEditor from '@ckeditor/ckeditor5-vue';
|
import CKEditor from '@ckeditor/ckeditor5-vue';
|
||||||
import ClassicEditor from "ChillMainAssets/module/ckeditor5";
|
import ClassicEditor from "ChillMainAssets/module/ckeditor5";
|
||||||
|
import { mapState } from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Comment",
|
name: "Comment",
|
||||||
@ -59,22 +63,58 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
editor: ClassicEditor,
|
editor: ClassicEditor,
|
||||||
formdata: {
|
loading: false,
|
||||||
type: "accompanying_period_comment",
|
lastRecordedContent: null,
|
||||||
content: ''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
pinnedComment() {
|
...mapState({
|
||||||
return this.$store.state.accompanyingCourse.pinnedComment;
|
pinnedComment: state => state.accompanyingCourse.pinnedComment,
|
||||||
},
|
}),
|
||||||
content: {
|
content: {
|
||||||
set(value) {
|
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() {
|
get() {
|
||||||
return (this.pinnedComment)? this.pinnedComment.content : {};
|
return this.pinnedComment ? this.pinnedComment.content : '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
errors() {
|
errors() {
|
||||||
@ -82,18 +122,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
submitform() {
|
onContentChange() {
|
||||||
this.$store.dispatch('postFirstComment', this.formdata)
|
let lastRecordedContent = this.formData.content;
|
||||||
.catch(({name, violations}) => {
|
|
||||||
if (name === 'ValidationException' || name === 'AccessException') {
|
|
||||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
|
||||||
} else {
|
|
||||||
this.$toast.open({message: 'An error occurred'})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
removeComment() {
|
removeComment() {
|
||||||
this.$store.dispatch('postFirstComment', {})
|
this.$store.dispatch('removePinnedComment', {id: this.pinnedComment.id})
|
||||||
.catch(({name, violations}) => {
|
.catch(({name, violations}) => {
|
||||||
if (name === 'ValidationException' || name === 'AccessException') {
|
if (name === 'ValidationException' || name === 'AccessException') {
|
||||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
div.ck-editor.ck-reset {
|
div.ck-editor.ck-reset {
|
||||||
margin: 0.6em 0;
|
margin: 0.6em 0;
|
||||||
}
|
}
|
||||||
|
div.sub-comment {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
div.loading {
|
||||||
|
margin-right: 6px;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -59,14 +59,6 @@
|
|||||||
ref="addAddress">
|
ref="addAddress">
|
||||||
</add-address>
|
</add-address>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="isPersonLocation">
|
|
||||||
<button
|
|
||||||
class="btn btn-remove"
|
|
||||||
@click="removeAddress"
|
|
||||||
:title="$t('courselocation.remove_button')">
|
|
||||||
{{ $t('action.remove') }}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -180,22 +172,6 @@ export default {
|
|||||||
}
|
}
|
||||||
this.$store.commit('setAddressContext', context);
|
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() {
|
displayErrors() {
|
||||||
return this.$refs.addAddress.errorMsg;
|
return this.$refs.addAddress.errorMsg;
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<input type="checkbox" v-model="requestorIsAnonymous" class="me-2" />
|
<input type="checkbox" v-model="requestorIsAnonymous" class="me-2" />
|
||||||
{{ $t('requestor.is_anonymous') }}
|
{{ $t('requestor.is_anonymous') }}
|
||||||
</label>
|
</label>
|
||||||
<confidential :positionBtn="false" v-if="accompanyingCourse.requestor.type === 'thirdparty'">
|
<confidential v-if="accompanyingCourse.requestor.type === 'thirdparty'">
|
||||||
<template v-slot:confidential-content>
|
<template v-slot:confidential-content>
|
||||||
<third-party-render-box
|
<third-party-render-box
|
||||||
:thirdparty="accompanyingCourse.requestor"
|
:thirdparty="accompanyingCourse.requestor"
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</confidential>
|
</confidential>
|
||||||
|
|
||||||
<confidential :positionBtnFar="false" v-else-if="accompanyingCourse.requestor.type === 'person'">
|
<confidential v-else-if="accompanyingCourse.requestor.type === 'person'">
|
||||||
<template v-slot:confidential-content>
|
<template v-slot:confidential-content>
|
||||||
<person-render-box render="bloc"
|
<person-render-box render="bloc"
|
||||||
:person="accompanyingCourse.requestor"
|
:person="accompanyingCourse.requestor"
|
||||||
@ -339,5 +339,6 @@ div.flex-table {
|
|||||||
|
|
||||||
.confidential {
|
.confidential {
|
||||||
display: block;
|
display: block;
|
||||||
|
margin-right: 0px !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -170,7 +170,9 @@ export default {
|
|||||||
console.log('data', payload.data)
|
console.log('data', payload.data)
|
||||||
body.name = payload.data.name;
|
body.name = payload.data.name;
|
||||||
body.email = payload.data.email;
|
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;
|
body.address = payload.data.address ? { id: payload.data.address.address_id } : null;
|
||||||
|
|
||||||
makeFetch('PATCH', `/api/1.0/thirdparty/thirdparty/${payload.data.id}.json`, body)
|
makeFetch('PATCH', `/api/1.0/thirdparty/thirdparty/${payload.data.id}.json`, body)
|
||||||
|
@ -122,7 +122,7 @@ const appMessages = {
|
|||||||
title: "Observations",
|
title: "Observations",
|
||||||
label: "Ajout d'une note",
|
label: "Ajout d'une note",
|
||||||
content: "Rédigez une première 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: {
|
confirm: {
|
||||||
title: "Confirmation",
|
title: "Confirmation",
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user