mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-16 03:34:59 +00:00
Compare commits
5 Commits
20-update-
...
issue386_d
Author | SHA1 | Date | |
---|---|---|---|
a47fc3dbb7 | |||
fc28ada811 | |||
e121c241c6 | |||
9e2208f29c | |||
c3c80abed1 |
44
CHANGELOG.md
44
CHANGELOG.md
@@ -11,48 +11,9 @@ and this project adheres to
|
||||
## Unreleased
|
||||
|
||||
<!-- write down unreleased development here -->
|
||||
* renommer "dossier numéro" en "parcours numéro" dans les résultats de recherche
|
||||
* renomme date de début en date d'ouverture dans le formulaire parcours
|
||||
|
||||
|
||||
## Test releases
|
||||
|
||||
### test release 2021-01-31
|
||||
|
||||
[fast_actions] improve fast-actions buttons override mechanism, fix https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/413
|
||||
[homepage widget] add vue homepage_widget with asynchone loading, give a global view resume of the user concerned actions, notifications, etc.
|
||||
* [person] accompanying course: optimisation: do not fetch some resources for the banner (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/409)
|
||||
* [person] accompanying course: close modal when edit participation (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/420)
|
||||
* [person] accompanying course: treat validation error when editing on-the-fly entities (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/420)
|
||||
* [activity] show activity attendee (présence) in the activity list (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/412)
|
||||
* [activity] admin: change validation rule for social action visible field (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/413)
|
||||
* [parcours]: component added to change the opening date of a parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/411)
|
||||
* [search]: listing of parcours display changed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/410)
|
||||
* [user]: page with accompanying periods to which is user is referent (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/408)
|
||||
* [person] age added to renderstring + renderbox/ vue component created to display person text (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/389)
|
||||
* [household member editor] allow to push to existing household
|
||||
* [workflow][notification] improve how notifications and workflows are 'attached' to entities: contextual list, counter, buttons and vue modal
|
||||
|
||||
|
||||
### test release 2021-01-28
|
||||
|
||||
* [person] improve filiations vis graph: disable physics, use chill colors for persons-households-course, increase label of relations, remove labels on household arrows and other improvements (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/286, https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/362)
|
||||
* [activity] Order activity by date and by id (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/364)
|
||||
* [main] increase length of 4 Address fields (change to TEXT, no size limits) (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/277)
|
||||
* [main] Add confidential option for address, in edit and view (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/165)
|
||||
* [person] name suggestions within create person form when person is created departing from a search input (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/377)
|
||||
* [person] Add residential address entity, form and list for each person
|
||||
* [aside_activity]: dynamicUserPickerType used (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/399)
|
||||
* dispatching list
|
||||
|
||||
|
||||
### test release 2021-01-26
|
||||
|
||||
* [parcours] comments truncated if too long + link added (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/406)
|
||||
* [person]: possibility to add person resources (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/382)
|
||||
* [person ressources]: module added
|
||||
|
||||
|
||||
### test release 2022-01-24
|
||||
|
||||
* [person] name suggestions within create person form when person is created departing from a search input (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/377)
|
||||
@@ -71,6 +32,7 @@ and this project adheres to
|
||||
* add My workflow section with my opened subscriptions
|
||||
* apply workflow on documents, accompanyingCourseWork and Evaluations
|
||||
* [wopi-link] a new vue component allow to open wopi link in a fullscreen chill-themed modal
|
||||
<!-- end -->
|
||||
|
||||
### test release 2022-01-19
|
||||
* vuejs: add dead information on all on-the-fly person render boxes, in vis graph and other templates (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/271)
|
||||
@@ -88,14 +50,10 @@ and this project adheres to
|
||||
* [main] Add mainLocation field to User entity and add it in user form type
|
||||
* [course list in person context] show full username/label for ref
|
||||
* [accompanying period work] remove the possibility to generate document from an accompanying period work
|
||||
* vuejs: add validation on required fields for AddPerson, Address and Location components
|
||||
* vuejs: treat 422 validation errors in locations and AddPerson components
|
||||
* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380)
|
||||
|
||||
## Test releases
|
||||
* vuejs: add validation on required fields for AddPerson, Address and Location components
|
||||
* vuejs: treat 422 validation errors in locations and AddPerson components
|
||||
* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380)
|
||||
|
||||
### test release 2022-01-12
|
||||
|
||||
|
@@ -52,6 +52,9 @@
|
||||
"twig/string-extra": "^3.3",
|
||||
"twig/twig": "^3.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/symfony": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-fixtures-bundle": "^3.3",
|
||||
"drupol/php-conventions": "^5",
|
||||
@@ -68,17 +71,23 @@
|
||||
"symfony/var-dumper": "^4.4",
|
||||
"symfony/web-profiler-bundle": "^4.4"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/symfony": "*"
|
||||
"config": {
|
||||
"bin-dir": "bin",
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true,
|
||||
"vendor-dir": "tests/app/vendor",
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true,
|
||||
"phpstan/extension-installer": true,
|
||||
"ergebnis/composer-normalize": true,
|
||||
"phpro/grumphp": true
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Chill\\ActivityBundle\\": "src/Bundle/ChillActivityBundle",
|
||||
"Chill\\AsideActivityBundle\\": "src/Bundle/ChillAsideActivityBundle/src",
|
||||
"Chill\\BudgetBundle\\": "src/Bundle/ChillBudgetBundle",
|
||||
"Chill\\CalendarBundle\\": "src/Bundle/ChillCalendarBundle",
|
||||
"Chill\\CustomFieldsBundle\\": "src/Bundle/ChillCustomFieldsBundle",
|
||||
"Chill\\DocGeneratorBundle\\": "src/Bundle/ChillDocGeneratorBundle",
|
||||
"Chill\\DocStoreBundle\\": "src/Bundle/ChillDocStoreBundle",
|
||||
"Chill\\EventBundle\\": "src/Bundle/ChillEventBundle",
|
||||
"Chill\\FamilyMemberBundle\\": "src/Bundle/ChillFamilyMemberBundle",
|
||||
@@ -87,6 +96,9 @@
|
||||
"Chill\\ReportBundle\\": "src/Bundle/ChillReportBundle",
|
||||
"Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle",
|
||||
"Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle",
|
||||
"Chill\\AsideActivityBundle\\": "src/Bundle/ChillAsideActivityBundle/src",
|
||||
"Chill\\DocGeneratorBundle\\": "src/Bundle/ChillDocGeneratorBundle",
|
||||
"Chill\\CalendarBundle\\": "src/Bundle/ChillCalendarBundle",
|
||||
"Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src"
|
||||
}
|
||||
},
|
||||
@@ -99,10 +111,10 @@
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true,
|
||||
"phpstan/extension-installer": true,
|
||||
"ergebnis/composer-normalize": true,
|
||||
"ocramius/package-versions": true,
|
||||
"phpro/grumphp": true,
|
||||
"phpstan/extension-installer": true
|
||||
"ocramius/package-versions": true
|
||||
},
|
||||
"bin-dir": "bin",
|
||||
"optimize-autoloader": true,
|
||||
@@ -111,8 +123,8 @@
|
||||
},
|
||||
"scripts": {
|
||||
"auto-scripts": {
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd",
|
||||
"cache:clear": "symfony-cmd"
|
||||
"cache:clear": "symfony-cmd",
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
package.json.txt
Normal file
3
package.json.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
add npm/yarn dependency in package.json :
|
||||
|
||||
"select2-bootstrap-theme": "0.1.0-beta.10",
|
@@ -80,6 +80,11 @@ parameters:
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Form/ChoiceLoader/PersonChoiceLoader.php
|
||||
|
||||
-
|
||||
message: "#^Foreach overwrites \\$action with its value variable\\.$#"
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php
|
||||
|
||||
-
|
||||
message: "#^Foreach overwrites \\$action with its value variable\\.$#"
|
||||
count: 1
|
||||
|
@@ -30,6 +30,36 @@ parameters:
|
||||
count: 2
|
||||
path: src/Bundle/ChillPersonBundle/Household/MembersEditorFactory.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\$action of method Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkRepository\\:\\:buildQueryBySocialActionWithDescendants\\(\\) has invalid type Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\SocialAction\\.$#"
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\$action of method Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkRepository\\:\\:countBySocialActionWithDescendants\\(\\) has invalid type Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\SocialAction\\.$#"
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php
|
||||
|
||||
-
|
||||
message: "#^Undefined variable\\: \\$action$#"
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php
|
||||
|
||||
-
|
||||
message: "#^Undefined variable\\: \\$limit$#"
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php
|
||||
|
||||
-
|
||||
message: "#^Undefined variable\\: \\$offset$#"
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php
|
||||
|
||||
-
|
||||
message: "#^Undefined variable\\: \\$orderBy$#"
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php
|
||||
|
||||
-
|
||||
message: "#^Variable variables are not allowed\\.$#"
|
||||
count: 4
|
||||
|
@@ -400,6 +400,11 @@ parameters:
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Form/Type/PersonPhoneType.php
|
||||
|
||||
-
|
||||
message: "#^Method Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\AccompanyingPeriodWorkRepository\\:\\:buildQueryBySocialActionWithDescendants\\(\\) has invalid return type Chill\\\\PersonBundle\\\\Repository\\\\AccompanyingPeriod\\\\QueryBuilder\\.$#"
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Repository/AccompanyingPeriod/AccompanyingPeriodWorkRepository.php
|
||||
|
||||
-
|
||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
||||
count: 3
|
||||
|
@@ -256,7 +256,7 @@ final class ActivityController extends AbstractController
|
||||
if ($person instanceof Person) {
|
||||
$this->denyAccessUnlessGranted(ActivityVoter::SEE, $person);
|
||||
$activities = $this->activityACLAwareRepository
|
||||
->findByPerson($person, ActivityVoter::SEE, 0, null, ['date' => 'DESC', 'id' => 'DESC']);
|
||||
->findByPerson($person, ActivityVoter::SEE, 0, null);
|
||||
|
||||
$event = new PrivacyEvent($person, [
|
||||
'element_class' => Activity::class,
|
||||
@@ -269,7 +269,7 @@ final class ActivityController extends AbstractController
|
||||
$this->denyAccessUnlessGranted(ActivityVoter::SEE, $accompanyingPeriod);
|
||||
|
||||
$activities = $this->activityACLAwareRepository
|
||||
->findByAccompanyingPeriod($accompanyingPeriod, ActivityVoter::SEE, 0, null, ['date' => 'DESC', 'id' => 'DESC']);
|
||||
->findByAccompanyingPeriod($accompanyingPeriod, ActivityVoter::SEE);
|
||||
|
||||
$view = 'ChillActivityBundle:Activity:listAccompanyingCourse.html.twig';
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
namespace Chill\ActivityBundle\Entity;
|
||||
|
||||
use Chill\ActivityBundle\Validator\Constraints as ActivityValidator;
|
||||
use Chill\DocStoreBundle\Entity\Document;
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
@@ -61,7 +62,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod")
|
||||
* @Groups({"read"})
|
||||
* @Groups({"read", "docgen:read"})
|
||||
*/
|
||||
private ?AccompanyingPeriod $accompanyingPeriod = null;
|
||||
|
||||
@@ -75,19 +76,16 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="Chill\ActivityBundle\Entity\ActivityPresence")
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
private ?ActivityPresence $attendee = null;
|
||||
|
||||
/**
|
||||
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_")
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
private CommentEmbeddable $comment;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime")
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
private DateTime $date;
|
||||
|
||||
@@ -103,7 +101,6 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default": false})
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
private bool $emergency = false;
|
||||
|
||||
@@ -134,19 +131,16 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="Chill\ActivityBundle\Entity\ActivityReason")
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
private Collection $reasons;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Scope")
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
private ?Scope $scope = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", options={"default": ""})
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
private string $sentReceived = '';
|
||||
|
||||
@@ -177,13 +171,12 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User")
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
private User $user;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="Chill\MainBundle\Entity\User")
|
||||
* @Groups({"read", "docgen:read"})
|
||||
* @Groups({"read"})
|
||||
*/
|
||||
private ?Collection $users = null;
|
||||
|
||||
@@ -310,18 +303,6 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
|
||||
return $this->documents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
public function getDurationMinute(): int
|
||||
{
|
||||
if (null === $this->durationTime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int) round(($this->durationTime->getTimestamp() + $this->durationTime->getOffset()) / 60.0, 0);
|
||||
}
|
||||
|
||||
public function getDurationTime(): ?DateTime
|
||||
{
|
||||
return $this->durationTime;
|
||||
@@ -422,18 +403,6 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
|
||||
return $this->travelTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
public function getTravelTimeMinute(): int
|
||||
{
|
||||
if (null === $this->travelTime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int) round(($this->travelTime->getTimestamp() + $this->travelTime->getOffset()) / 60.0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
|
@@ -12,7 +12,6 @@ declare(strict_types=1);
|
||||
namespace Chill\ActivityBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
/**
|
||||
* Class ActivityPresence.
|
||||
@@ -32,14 +31,11 @@ class ActivityPresence
|
||||
* @ORM\Id
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
* @Serializer\Groups({"docgen:read"})
|
||||
*/
|
||||
private ?int $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="json")
|
||||
* @Serializer\Groups({"docgen:read"})
|
||||
* @Serializer\Context({"is-translatable": true}, groups={"docgen:read"})
|
||||
*/
|
||||
private array $name = [];
|
||||
|
||||
|
@@ -13,10 +13,8 @@ namespace Chill\ActivityBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
/**
|
||||
* Class ActivityType.
|
||||
@@ -120,7 +118,6 @@ class ActivityType
|
||||
* @ORM\Id
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
* @Groups({"docgen:read"})
|
||||
*/
|
||||
private ?int $id;
|
||||
|
||||
@@ -136,8 +133,7 @@ class ActivityType
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="json")
|
||||
* @Groups({"read", "docgen:read"})
|
||||
* @Serializer\Context({"is-translatable": true}, groups={"docgen:read"})
|
||||
* @Groups({"read"})
|
||||
*/
|
||||
private array $name = [];
|
||||
|
||||
@@ -194,6 +190,7 @@ class ActivityType
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="smallint", nullable=false, options={"default": 1})
|
||||
* @Assert\EqualTo(propertyPath="socialIssuesVisible", message="This parameter must be equal to social issue parameter")
|
||||
*/
|
||||
private int $socialActionsVisible = self::FIELD_INVISIBLE;
|
||||
|
||||
@@ -263,23 +260,6 @@ class ActivityType
|
||||
*/
|
||||
private int $userVisible = self::FIELD_REQUIRED;
|
||||
|
||||
/**
|
||||
* @Assert\Callback
|
||||
*
|
||||
* @param mixed $payload
|
||||
*/
|
||||
public function checkSocialActionsVisibility(ExecutionContextInterface $context, $payload)
|
||||
{
|
||||
if ($this->socialIssuesVisible !== $this->socialActionsVisible) {
|
||||
if (!($this->socialIssuesVisible === 2 && $this->socialActionsVisible === 1)) {
|
||||
$context
|
||||
->buildViolation('The socialActionsVisible value is not compatible with the socialIssuesVisible value')
|
||||
->atPath('socialActionsVisible')
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active
|
||||
* return true if the type is active.
|
||||
|
@@ -34,8 +34,6 @@ p.date-label {
|
||||
font-size: 18pt;
|
||||
}
|
||||
div.dashboard,
|
||||
h4.badge-title,
|
||||
h3.badge-title,
|
||||
h2.badge-title {
|
||||
ul.list-content {
|
||||
font-size: 70%;
|
||||
|
@@ -1,48 +1,45 @@
|
||||
<template>
|
||||
<teleport to="#add-persons" v-if="isComponentVisible">
|
||||
<teleport to="#add-persons" v-if="isComponentVisible">
|
||||
|
||||
<div class="flex-bloc concerned-groups" :class="getContext">
|
||||
<persons-bloc
|
||||
v-for="bloc in contextPersonsBlocs"
|
||||
v-bind:key="bloc.key"
|
||||
v-bind:bloc="bloc"
|
||||
v-bind:blocWidth="getBlocWidth"
|
||||
v-bind:setPersonsInBloc="setPersonsInBloc">
|
||||
</persons-bloc>
|
||||
</div>
|
||||
<div v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0">
|
||||
<ul class="list-suggest add-items inline">
|
||||
<li v-for="(p, i) in suggestedEntities" @click="addSuggestedEntity(p)" :key="`suggestedEntities-${i}`">
|
||||
<person-text v-if="p.type === 'person'" :person="p"></person-text>
|
||||
<span v-else>{{ p.text }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex-bloc concerned-groups" :class="getContext">
|
||||
<persons-bloc
|
||||
v-for="bloc in contextPersonsBlocs"
|
||||
v-bind:key="bloc.key"
|
||||
v-bind:bloc="bloc"
|
||||
v-bind:blocWidth="getBlocWidth"
|
||||
v-bind:setPersonsInBloc="setPersonsInBloc">
|
||||
</persons-bloc>
|
||||
</div>
|
||||
<div v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0">
|
||||
<ul class="list-suggest add-items inline">
|
||||
<li v-for="(p, i) in suggestedEntities" @click="addSuggestedEntity(p)" :key="`suggestedEntities-${i}`">
|
||||
<span>{{ p.text }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<add-persons
|
||||
buttonTitle="activity.add_persons"
|
||||
modalTitle="activity.add_persons"
|
||||
v-bind:key="addPersons.key"
|
||||
v-bind:options="addPersonsOptions"
|
||||
@addNewPersons="addNewPersons"
|
||||
ref="addPersons">
|
||||
</add-persons>
|
||||
<add-persons
|
||||
buttonTitle="activity.add_persons"
|
||||
modalTitle="activity.add_persons"
|
||||
v-bind:key="addPersons.key"
|
||||
v-bind:options="addPersonsOptions"
|
||||
@addNewPersons="addNewPersons"
|
||||
ref="addPersons">
|
||||
</add-persons>
|
||||
|
||||
</teleport>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||
import PersonsBloc from './ConcernedGroups/PersonsBloc.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
export default {
|
||||
name: "ConcernedGroups",
|
||||
components: {
|
||||
AddPersons,
|
||||
PersonsBloc,
|
||||
PersonText
|
||||
PersonsBloc
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@@ -1,29 +1,21 @@
|
||||
<template>
|
||||
<li>
|
||||
<span :title="person.text">
|
||||
<span class="chill_denomination" @click.prevent="$emit('remove', person)">
|
||||
<person-text :person="person" :isCut="true"></person-text>
|
||||
</span>
|
||||
<span class="chill_denomination" @click.prevent="$emit('remove', person)">{{ textCutted }}</span>
|
||||
</span>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
|
||||
|
||||
export default {
|
||||
name: "PersonBadge",
|
||||
props: ['person'],
|
||||
components: {
|
||||
PersonText
|
||||
computed: {
|
||||
textCutted() {
|
||||
let more = (this.person.text.length > 15) ?'…' : '';
|
||||
return this.person.text.slice(0,15) + more;
|
||||
}
|
||||
},
|
||||
// computed: {
|
||||
// textCutted() {
|
||||
// let more = (this.person.text.length > 15) ?'…' : '';
|
||||
// return this.person.text.slice(0,15) + more;
|
||||
// }
|
||||
// },
|
||||
emits: ['remove'],
|
||||
}
|
||||
</script>
|
||||
|
@@ -41,17 +41,6 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if activity.attendee and t.attendeeVisible %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title"><h3>{{ 'Attendee'|trans }}</h3></div>
|
||||
<div class="wl-col list">
|
||||
<p class="wl-item">
|
||||
{{ activity.attendee.name|localize_translatable_string }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if activity.sentReceived is not empty and t.sentReceivedVisible %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title"><h3>{{ 'Sent received'|trans }}</h3></div>
|
||||
|
@@ -2,12 +2,10 @@
|
||||
{% if is_granted('CHILL_ACTIVITY_SEE_DETAILS', activity) %}
|
||||
{% if no_action is not defined or no_action == false %}
|
||||
<li>
|
||||
<a class="btn btn-misc" href="{{ chill_path_add_return_path('chill_main_notification_create', {
|
||||
<a class="btn btn-notify" href="{{ chill_path_add_return_path('chill_main_notification_create', {
|
||||
'entityClass': 'Chill\\ActivityBundle\\Entity\\Activity',
|
||||
'entityId': activity.id
|
||||
}) }}">
|
||||
<i class="fa fa-paper-plane fa-fw"></i>
|
||||
{{ 'notification.Notify'|trans }}</a>
|
||||
}) }}">{{ 'notification.Notify'|trans }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if context == 'person' and activity.accompanyingPeriod is not empty %}
|
||||
|
@@ -48,7 +48,7 @@
|
||||
<li class="associated-persons">
|
||||
<span class="item-key">{{ 'Participants'|trans ~ ' : ' }}</span>
|
||||
{% for p in activity.personsAssociated %}
|
||||
<span class="badge-person">{{ p|chill_entity_render_box({'addAgeBadge': true}) }}</span>
|
||||
<span class="badge-person">{{ p|chill_entity_render_box }}</span>
|
||||
{% endfor %}
|
||||
</li>
|
||||
</ul>
|
||||
|
@@ -165,7 +165,11 @@
|
||||
<dt class="inline">{{ 'Attendee'|trans }}</dt>
|
||||
<dd>
|
||||
{% if entity.attendee is not null %}
|
||||
{{ entity.attendee.name|localize_translatable_string }}
|
||||
{% if entity.attendee %}
|
||||
{{ 'present'|trans|capitalize }}
|
||||
{% else %}
|
||||
{{ 'not present'|trans|capitalize }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="chill-no-data-statement">{{ 'None'|trans|capitalize }}</span>
|
||||
{% endif %}
|
||||
@@ -177,13 +181,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="notification notification-list">
|
||||
{% set notifications = chill_list_notifications('Chill\\ActivityBundle\\Entity\\Activity', entity.id) %}
|
||||
{% if notifications is not empty %}
|
||||
{{ notifications|raw }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% set person_id = null %}
|
||||
{% if person %}
|
||||
{% set person_id = person.id %}
|
||||
@@ -200,21 +197,18 @@
|
||||
{{ 'Back to the list'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-notify" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\ActivityBundle\\Entity\\Activity', 'entityId': entity.id}) }}">
|
||||
{{ 'notification.Notify'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% if is_granted('CHILL_ACTIVITY_UPDATE', entity) %}
|
||||
<li>
|
||||
<a href="{{ path('chill_activity_activity_edit', { 'id': entity.id, 'person_id': person_id, 'accompanying_period_id': accompanying_course_id }) }}"
|
||||
class="btn btn-update">{{ 'Edit'|trans }}</a>
|
||||
</li>
|
||||
<a class="btn btn-update" href="{{ path('chill_activity_activity_edit', { 'id': entity.id, 'person_id': person_id, 'accompanying_period_id': accompanying_course_id }) }}">
|
||||
{{ 'Edit'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_ACTIVITY_DELETE', entity) %}
|
||||
<li>
|
||||
<a href="{{ path('chill_activity_activity_delete', { 'id': entity.id, 'person_id' : person_id, 'accompanying_period_id': accompanying_course_id } ) }}"
|
||||
class="btn btn-delete" title="{{ 'Delete'|trans }}"></a>
|
||||
<a href="{{ path('chill_activity_activity_delete', { 'id': entity.id, 'person_id' : person_id, 'accompanying_period_id': accompanying_course_id } ) }}" class="btn btn-delete">
|
||||
{{ 'Delete'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
@@ -25,5 +25,19 @@
|
||||
{% endblock content %}
|
||||
|
||||
{% block block_post_menu %}
|
||||
<div class="post-menu pt-4"></div>
|
||||
<div class="post-menu pt-4">
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<a class="btn btn-primary" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\ActivityBundle\\Entity\\Activity', 'entityId': entity.id}) }}">
|
||||
<i class="fa fa-paper-plane fa-fw"></i>
|
||||
{{ 'notification.Notify'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% set notifications = chill_list_notifications('Chill\\ActivityBundle\\Entity\\Activity', entity.id) %}
|
||||
{% if notifications is not empty %}
|
||||
{{ notifications|raw }}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@@ -28,7 +28,8 @@
|
||||
<div class="post-menu pt-4">
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<a class="btn btn-notify" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\ActivityBundle\\Entity\\Activity', 'entityId': entity.id}) }}">
|
||||
<a class="btn btn-primary" href="{{ chill_path_add_return_path('chill_main_notification_create', {'entityClass': 'Chill\\ActivityBundle\\Entity\\Activity', 'entityId': entity.id}) }}">
|
||||
<i class="fa fa-paper-plane fa-fw"></i>
|
||||
{{ 'notification.Notify'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
|
@@ -24,6 +24,7 @@ use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Templating\Entity\PersonRender;
|
||||
use DateTime;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
@@ -32,6 +33,8 @@ use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
class ActivityContext implements
|
||||
DocGeneratorContextWithAdminFormInterface,
|
||||
DocGeneratorContextWithPublicFormInterface
|
||||
|
@@ -9,7 +9,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Tests\Export\Aggregator;
|
||||
namespace Chill\ActivityBundle\Tests\Aggregator;
|
||||
|
||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Tests\Export\Aggregator;
|
||||
namespace Chill\ActivityBundle\Tests\Aggregator;
|
||||
|
||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Tests\Export\Aggregator;
|
||||
namespace Chill\ActivityBundle\Tests\Aggregator;
|
||||
|
||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Tests\Export\Filter;
|
||||
namespace Chill\ActivityBundle\Tests\Filter;
|
||||
|
||||
use Chill\MainBundle\Test\Export\AbstractFilterTest;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Tests\Export\Filter;
|
||||
namespace Chill\ActivityBundle\Tests\Filter;
|
||||
|
||||
use Chill\MainBundle\Test\Export\AbstractFilterTest;
|
||||
use DateTime;
|
||||
|
@@ -29,13 +29,9 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
final class ActivityVoterTest extends KernelTestCase
|
||||
{
|
||||
use PrepareActivityTrait;
|
||||
|
||||
use PrepareCenterTrait;
|
||||
|
||||
use PreparePersonTrait;
|
||||
|
||||
use PrepareScopeTrait;
|
||||
|
||||
use PrepareUserTrait;
|
||||
|
||||
/**
|
||||
|
@@ -20,4 +20,3 @@ For this type of activity, you must add at least one social action: Pour ce type
|
||||
|
||||
# admin
|
||||
This parameter must be equal to social issue parameter: Ce paramètre doit être égal au paramètre "Visibilité du champs Problématiques sociales"
|
||||
The socialActionsVisible value is not compatible with the socialIssuesVisible value: Cette valeur du paramètre "Visibilité du champs Actions sociales" n'est pas compatible avec la valeur du paramètre "Visibilité du champs Problématiques sociales"
|
@@ -32,8 +32,6 @@ final class AsideActivityController extends CRUDController
|
||||
{
|
||||
$asideActivity = new AsideActivity();
|
||||
|
||||
$asideActivity->setAgent($this->getUser());
|
||||
|
||||
$duration = $request->query->get('duration', '300');
|
||||
$duration = DateTime::createFromFormat('U', $duration);
|
||||
$asideActivity->setDuration($duration);
|
||||
|
@@ -14,9 +14,9 @@ namespace Chill\AsideActivityBundle\Form;
|
||||
use Chill\AsideActivityBundle\Entity\AsideActivity;
|
||||
use Chill\AsideActivityBundle\Entity\AsideActivityCategory;
|
||||
use Chill\AsideActivityBundle\Templating\Entity\CategoryRender;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Form\Type\ChillTextareaType;
|
||||
use Chill\MainBundle\Form\Type\PickUserDynamicType;
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
@@ -68,10 +68,22 @@ final class AsideActivityFormType extends AbstractType
|
||||
];
|
||||
|
||||
$builder
|
||||
->add('agent', PickUserDynamicType::class, [
|
||||
'label' => 'For agent',
|
||||
'required' => true,
|
||||
])
|
||||
->add(
|
||||
'agent',
|
||||
EntityType::class,
|
||||
[
|
||||
'label' => 'For agent',
|
||||
'required' => true,
|
||||
'class' => User::class,
|
||||
'data' => $this->storage->getToken()->getUser(),
|
||||
'query_builder' => static function (EntityRepository $er) {
|
||||
return $er->createQueryBuilder('u')->where('u.enabled = true');
|
||||
},
|
||||
'attr' => ['class' => 'select2 '],
|
||||
'placeholder' => 'Choose the agent for whom this activity is created',
|
||||
'choice_label' => 'username',
|
||||
]
|
||||
)
|
||||
->add(
|
||||
'date',
|
||||
ChillDateType::class,
|
||||
|
@@ -1,15 +1,5 @@
|
||||
{% extends '@ChillMain/Admin/layout.html.twig' %}
|
||||
|
||||
{% block js %}
|
||||
{{ parent() }}
|
||||
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ parent() }}
|
||||
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
{% include('@ChillMain/CRUD/_new_title.html.twig') %}
|
||||
{% endblock %}
|
||||
@@ -18,5 +8,4 @@
|
||||
{% embed '@ChillMain/CRUD/_new_content.html.twig' %}
|
||||
{% block content_form_actions_save_and_show %}{% endblock %}
|
||||
{% endembed %}
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
@@ -9,7 +9,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CustomFieldsBundle\Tests\CustomFields;
|
||||
namespace Chill\CustomFieldsBundle\Tests;
|
||||
|
||||
use Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice;
|
||||
use Chill\CustomFieldsBundle\Entity\CustomField;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CustomFieldsBundle\Tests\CustomFields;
|
||||
namespace Chill\CustomFieldsBundle\Tests;
|
||||
|
||||
use Chill\CustomFieldsBundle\CustomFields\CustomFieldNumber;
|
||||
use Chill\CustomFieldsBundle\Entity\CustomField;
|
||||
|
@@ -9,11 +9,10 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CustomFieldsBundle\Tests\CustomFields;
|
||||
namespace Chill\CustomFieldsBundle\Tests;
|
||||
|
||||
use Chill\CustomFieldsBundle\CustomFields\CustomFieldText;
|
||||
use Chill\CustomFieldsBundle\Entity\CustomField;
|
||||
use Chill\CustomFieldsBundle\Tests\CustomFieldTestHelper;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
/**
|
||||
|
@@ -9,7 +9,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CustomFieldsBundle\Tests\Routing;
|
||||
namespace Chill\CustomFieldsBundle\Tests;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
@@ -17,7 +17,7 @@
|
||||
<select class="form-select" v-model="template">
|
||||
<option disabled selected value="">{{ $t('choose_a_template') }}</option>
|
||||
<template v-for="t in templates">
|
||||
<option v-bind:value="t.id">{{ t.name.fr || 'Aucun nom défini' }}</option>
|
||||
<option v-bind:value="t.id">{{ t.name.fr }}</option>
|
||||
</template>
|
||||
</select>
|
||||
<button v-if="canGenerate" class="btn btn-update btn-sm change-icon" type="button" @click="generateDocument"><i class="fa fa-fw fa-cog"></i></button>
|
||||
@@ -48,7 +48,6 @@ export default {
|
||||
required: true,
|
||||
},
|
||||
templates: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
// beforeMove execute "something" before
|
||||
@@ -74,11 +73,7 @@ export default {
|
||||
return true;
|
||||
},
|
||||
getDescription() {
|
||||
let desc = this.templates.find(t => t.id === this.template);
|
||||
if (null === desc) {
|
||||
return '';
|
||||
}
|
||||
return desc.description || '';
|
||||
return this.templates.find(t => t.id === this.template).description || '';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@@ -21,28 +21,24 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% set freezed = false %}
|
||||
{% for step in entity_workflow.stepsChained %}
|
||||
{% if loop.last %}
|
||||
{% if step.previous is not null and step.previous.freezeAfter == true %}
|
||||
{% set freezed = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if display_action is defined and display_action == true %}
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
{{ m.download_button(document.object, document.title) }}
|
||||
</li>
|
||||
<li>
|
||||
{% if not freezed %}
|
||||
{% set button = {
|
||||
'changeIcon': 'fa-unlock',
|
||||
} %}{#
|
||||
|
||||
{#
|
||||
data-button is optional !
|
||||
OPTIONS:
|
||||
'changeIcon' string
|
||||
'changeClass' string
|
||||
'noText' boolean
|
||||
#}
|
||||
|
||||
#}{% set button = {
|
||||
'changeIcon': 'fa-unlock',
|
||||
} %}
|
||||
|
||||
{# vue component #}
|
||||
<span
|
||||
data-module="wopi-link"
|
||||
@@ -51,11 +47,6 @@
|
||||
data-doc-type="{{ document.object.type|e('html_attr') }}"
|
||||
data-button="{{ button|json_encode }}"
|
||||
></span>
|
||||
{% else %}
|
||||
<a class="btn btn-update change-icon disabled" href="#" title="{{ 'workflow.freezed document'|trans }}">
|
||||
<i class="fa fa-lock me-2"></i>{{ 'Update document'|trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
@@ -56,18 +56,17 @@
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% set workflows_frame = chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) %}
|
||||
{% if workflows_frame is not empty %}
|
||||
<li>
|
||||
{{ workflows_frame|raw }}
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block block_post_menu %}
|
||||
<div class="post-menu pt-4"></div>
|
||||
<div class="post-menu pt-4">
|
||||
{% set workflows_frame = chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) %}
|
||||
{% if workflows_frame is not empty %}
|
||||
{{ workflows_frame|raw }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
|
@@ -13,19 +13,13 @@ namespace Chill\MainBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\Entity\Notification;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Repository\NotificationRepository;
|
||||
use Chill\MainBundle\Security\Authorization\NotificationVoter;
|
||||
use Chill\MainBundle\Serializer\Model\Collection;
|
||||
use Chill\MainBundle\Serializer\Model\Counter;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
@@ -35,26 +29,12 @@ class NotificationApiController
|
||||
{
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
private NotificationRepository $notificationRepository;
|
||||
|
||||
private PaginatorFactory $paginatorFactory;
|
||||
|
||||
private Security $security;
|
||||
|
||||
private SerializerInterface $serializer;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $entityManager,
|
||||
NotificationRepository $notificationRepository,
|
||||
PaginatorFactory $paginatorFactory,
|
||||
Security $security,
|
||||
SerializerInterface $serializer
|
||||
) {
|
||||
public function __construct(EntityManagerInterface $entityManager, Security $security)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->notificationRepository = $notificationRepository;
|
||||
$this->paginatorFactory = $paginatorFactory;
|
||||
$this->security = $security;
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,37 +53,6 @@ class NotificationApiController
|
||||
return $this->markAs('unread', $notification);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/my/unread")
|
||||
*/
|
||||
public function myUnreadNotifications(Request $request): JsonResponse
|
||||
{
|
||||
$total = $this->notificationRepository->countUnreadByUser($this->security->getUser());
|
||||
|
||||
if ($request->query->getBoolean('countOnly')) {
|
||||
return new JsonResponse(
|
||||
$this->serializer->serialize(new Counter($total), 'json', ['groups' => ['read']]),
|
||||
JsonResponse::HTTP_OK,
|
||||
[],
|
||||
true
|
||||
);
|
||||
}
|
||||
$paginator = $this->paginatorFactory->create($total);
|
||||
$notifications = $this->notificationRepository->findUnreadByUser(
|
||||
$this->security->getUser(),
|
||||
$paginator->getItemsPerPage(),
|
||||
$paginator->getCurrentPageFirstItemNumber()
|
||||
);
|
||||
$collection = new Collection($notifications, $paginator);
|
||||
|
||||
return new JsonResponse(
|
||||
$this->serializer->serialize($collection, 'json', ['groups' => ['read']]),
|
||||
JsonResponse::HTTP_OK,
|
||||
[],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
private function markAs(string $target, Notification $notification): JsonResponse
|
||||
{
|
||||
if (!$this->security->isGranted(NotificationVoter::NOTIFICATION_TOGGLE_READ_STATUS, $notification)) {
|
||||
|
@@ -41,11 +41,6 @@ class Configuration implements ConfigurationInterface
|
||||
|
||||
$rootNode
|
||||
->children()
|
||||
->scalarNode('phonenumber_default_country_code')
|
||||
->cannotBeEmpty()
|
||||
->isRequired()
|
||||
->defaultValue('+32')
|
||||
->end() // end of scalar 'phonenumber_default_country_code'
|
||||
->scalarNode('installation_name')
|
||||
->cannotBeEmpty()
|
||||
->defaultValue('Chill')
|
||||
|
@@ -42,16 +42,10 @@ class Address
|
||||
*/
|
||||
private $buildingName;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean")
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private bool $confidential = false;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $corridor;
|
||||
@@ -84,7 +78,7 @@ class Address
|
||||
/**
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $flat;
|
||||
@@ -92,7 +86,7 @@ class Address
|
||||
/**
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $floor;
|
||||
@@ -149,7 +143,7 @@ class Address
|
||||
/**
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $steps;
|
||||
@@ -198,7 +192,6 @@ class Address
|
||||
return (new Address())
|
||||
->setAddressReference($original->getAddressReference())
|
||||
->setBuildingName($original->getBuildingName())
|
||||
->setConfidential($original->getConfidential())
|
||||
->setCorridor($original->getCorridor())
|
||||
->setCustoms($original->getCustoms())
|
||||
->setDistribution($original->getDistribution())
|
||||
@@ -236,11 +229,6 @@ class Address
|
||||
return $this->buildingName;
|
||||
}
|
||||
|
||||
public function getConfidential(): bool
|
||||
{
|
||||
return $this->confidential;
|
||||
}
|
||||
|
||||
public function getCorridor(): ?string
|
||||
{
|
||||
return $this->corridor;
|
||||
@@ -381,13 +369,6 @@ class Address
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setConfidential(bool $confidential): self
|
||||
{
|
||||
$this->confidential = $confidential;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCorridor(?string $corridor): self
|
||||
{
|
||||
$this->corridor = $corridor;
|
||||
|
@@ -20,9 +20,10 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
class CommentEmbeddable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
*/
|
||||
private ?string $comment = null;
|
||||
private $comment;
|
||||
|
||||
/**
|
||||
* @var DateTime
|
||||
@@ -38,7 +39,10 @@ class CommentEmbeddable
|
||||
*/
|
||||
private $userId;
|
||||
|
||||
public function getComment(): ?string
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getComment()
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
@@ -64,6 +68,9 @@ class CommentEmbeddable
|
||||
return empty($this->getComment());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $comment
|
||||
*/
|
||||
public function setComment(?string $comment)
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
@@ -64,7 +64,7 @@ class Location implements TrackCreationInterface, TrackUpdateInterface
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @Serializer\Groups({"read", "write", "docgen:read"})
|
||||
* @Serializer\Groups({"read", "write"})
|
||||
*/
|
||||
private ?string $email = null;
|
||||
|
||||
|
@@ -1,166 +0,0 @@
|
||||
<?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\Entity;
|
||||
|
||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
use Chill\MainBundle\Repository\ResidentialAddressRepository;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass=ResidentialAddressRepository::class)
|
||||
* @ORM\Table(name="chill_main_residential_address")
|
||||
*/
|
||||
class ResidentialAddress
|
||||
{
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Address::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private ?Address $address = null;
|
||||
|
||||
/**
|
||||
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="residentialAddressComment_")
|
||||
*/
|
||||
private CommentEmbeddable $comment;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime_immutable", nullable=true)
|
||||
*/
|
||||
private ?DateTimeImmutable $endDate = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Person::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private ?Person $hostPerson = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=ThirdParty::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private ?ThirdParty $hostThirdParty = null;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Person::class)
|
||||
* @ORM\JoinColumn(nullable=false)
|
||||
*/
|
||||
private Person $person;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime_immutable")
|
||||
*/
|
||||
private ?DateTimeImmutable $startDate = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->comment = new CommentEmbeddable();
|
||||
}
|
||||
|
||||
public function getAddress(): ?Address
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
public function getComment(): CommentEmbeddable
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
public function getEndDate(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->endDate;
|
||||
}
|
||||
|
||||
public function getHostPerson(): ?Person
|
||||
{
|
||||
return $this->hostPerson;
|
||||
}
|
||||
|
||||
public function getHostThirdParty(): ?ThirdParty
|
||||
{
|
||||
return $this->hostThirdParty;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getPerson(): ?Person
|
||||
{
|
||||
return $this->person;
|
||||
}
|
||||
|
||||
public function getStartDate(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->startDate;
|
||||
}
|
||||
|
||||
public function setAddress(?Address $address): self
|
||||
{
|
||||
$this->address = $address;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setComment(CommentEmbeddable $comment): self
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setEndDate(?DateTimeImmutable $endDate): self
|
||||
{
|
||||
$this->endDate = $endDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHostPerson(?Person $hostPerson): self
|
||||
{
|
||||
$this->hostPerson = $hostPerson;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHostThirdParty(?ThirdParty $hostThirdParty): self
|
||||
{
|
||||
$this->hostThirdParty = $hostThirdParty;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPerson(?Person $person): self
|
||||
{
|
||||
$this->person = $person;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setStartDate(DateTimeImmutable $startDate): self
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -25,7 +25,6 @@ use Iterator;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
use function count;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
@@ -38,7 +37,6 @@ use function is_array;
|
||||
class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
/**
|
||||
@@ -52,6 +50,7 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
@@ -73,11 +72,6 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
*/
|
||||
private Collection $steps;
|
||||
|
||||
/**
|
||||
* @var null|array|EntityWorkflowStep[]
|
||||
*/
|
||||
private ?array $stepsChainedCache = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity=User::class)
|
||||
* @ORM\JoinTable(name="chill_main_workflow_entity_subscriber_to_final")
|
||||
@@ -135,6 +129,10 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
if (!$this->steps->contains($step)) {
|
||||
$this->steps[] = $step;
|
||||
$step->setEntityWorkflow($this);
|
||||
|
||||
if ($this->isFinalize()) {
|
||||
$step->setFinalizeAfter(true);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -255,33 +253,27 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
|
||||
public function getStepsChained(): array
|
||||
{
|
||||
if (is_array($this->stepsChainedCache)) {
|
||||
return $this->stepsChainedCache;
|
||||
}
|
||||
|
||||
$iterator = $this->steps->getIterator();
|
||||
$current = null;
|
||||
$previous = $next = $current = null;
|
||||
$steps = [];
|
||||
|
||||
$iterator->rewind();
|
||||
|
||||
do {
|
||||
while ($iterator->valid()) {
|
||||
$previous = $current;
|
||||
$current = $iterator->current();
|
||||
$steps[] = $current;
|
||||
|
||||
$steps[] = $current = $iterator->current();
|
||||
$current->setPrevious($previous);
|
||||
|
||||
$iterator->next();
|
||||
|
||||
if ($iterator->valid()) {
|
||||
$current->setNext($iterator->current());
|
||||
$next = $iterator->current();
|
||||
} else {
|
||||
$current->setNext(null);
|
||||
$next = null;
|
||||
}
|
||||
} while ($iterator->valid());
|
||||
|
||||
$this->stepsChainedCache = $steps;
|
||||
$current->setNext($next);
|
||||
}
|
||||
|
||||
return $steps;
|
||||
}
|
||||
@@ -316,7 +308,7 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
return $this->workflowName;
|
||||
}
|
||||
|
||||
public function isFinal(): bool
|
||||
public function isFinalize(): bool
|
||||
{
|
||||
$steps = $this->getStepsChained();
|
||||
|
||||
@@ -328,7 +320,7 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
/** @var EntityWorkflowStep $last */
|
||||
$last = end($steps);
|
||||
|
||||
return $last->isFinal();
|
||||
return $last->getPrevious()->isFinalizeAfter();
|
||||
}
|
||||
|
||||
public function isFreeze(): bool
|
||||
|
@@ -24,7 +24,6 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
class EntityWorkflowComment implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
/**
|
||||
|
@@ -53,6 +53,11 @@ class EntityWorkflowStep
|
||||
*/
|
||||
private ?EntityWorkflow $entityWorkflow = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default": false})
|
||||
*/
|
||||
private bool $finalizeAfter = false;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default": false})
|
||||
*/
|
||||
@@ -65,11 +70,6 @@ class EntityWorkflowStep
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default": false})
|
||||
*/
|
||||
private bool $isFinal = false;
|
||||
|
||||
/**
|
||||
* filled by @see{EntityWorkflow::getStepsChained}.
|
||||
*/
|
||||
@@ -187,9 +187,9 @@ class EntityWorkflowStep
|
||||
return $this->transitionByEmail;
|
||||
}
|
||||
|
||||
public function isFinal(): bool
|
||||
public function isFinalizeAfter(): bool
|
||||
{
|
||||
return $this->isFinal;
|
||||
return $this->finalizeAfter;
|
||||
}
|
||||
|
||||
public function isFreezeAfter(): bool
|
||||
@@ -244,16 +244,16 @@ class EntityWorkflowStep
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFreezeAfter(bool $freezeAfter): EntityWorkflowStep
|
||||
public function setFinalizeAfter(bool $finalizeAfter): EntityWorkflowStep
|
||||
{
|
||||
$this->freezeAfter = $freezeAfter;
|
||||
$this->finalizeAfter = $finalizeAfter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setIsFinal(bool $isFinal): EntityWorkflowStep
|
||||
public function setFreezeAfter(bool $freezeAfter): EntityWorkflowStep
|
||||
{
|
||||
$this->isFinal = $isFinal;
|
||||
$this->freezeAfter = $freezeAfter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@@ -12,15 +12,11 @@ declare(strict_types=1);
|
||||
namespace Chill\MainBundle\Form\Type\DataTransformer;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use Symfony\Component\Form\DataTransformerInterface;
|
||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use UnexpectedValueException;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
class EntityToJsonTransformer implements DataTransformerInterface
|
||||
@@ -56,10 +52,6 @@ class EntityToJsonTransformer implements DataTransformerInterface
|
||||
);
|
||||
}
|
||||
|
||||
if ('' === $value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->denormalizeOne($denormalized);
|
||||
}
|
||||
|
||||
@@ -77,7 +69,7 @@ class EntityToJsonTransformer implements DataTransformerInterface
|
||||
]);
|
||||
}
|
||||
|
||||
private function denormalizeOne(array $item)
|
||||
private function denormalizeOne(array $item): User
|
||||
{
|
||||
if (!array_key_exists('type', $item)) {
|
||||
throw new TransformationFailedException('the key "type" is missing on element');
|
||||
@@ -87,30 +79,10 @@ class EntityToJsonTransformer implements DataTransformerInterface
|
||||
throw new TransformationFailedException('the key "id" is missing on element');
|
||||
}
|
||||
|
||||
switch ($this->type) {
|
||||
case 'user':
|
||||
$class = User::class;
|
||||
|
||||
break;
|
||||
|
||||
case 'person':
|
||||
$class = Person::class;
|
||||
|
||||
break;
|
||||
|
||||
case 'thirdparty':
|
||||
$class = ThirdParty::class;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new UnexpectedValueException('This type is not supported');
|
||||
}
|
||||
|
||||
return
|
||||
$this->denormalizer->denormalize(
|
||||
['type' => $item['type'], 'id' => $item['id']],
|
||||
$class,
|
||||
$this->type,
|
||||
'json',
|
||||
[AbstractNormalizer::GROUPS => ['read']],
|
||||
);
|
||||
|
@@ -1,73 +0,0 @@
|
||||
<?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\Form\Type;
|
||||
|
||||
use Chill\MainBundle\Entity\ResidentialAddress;
|
||||
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||
use Chill\ThirdPartyBundle\Form\Type\PickThirdpartyDynamicType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
final class ResidentialAddressType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('startDate', DateType::class, [
|
||||
'required' => true,
|
||||
'input' => 'datetime_immutable',
|
||||
'widget' => 'single_text',
|
||||
])
|
||||
->add('endDate', DateType::class, [
|
||||
'required' => false,
|
||||
'input' => 'datetime_immutable',
|
||||
'widget' => 'single_text',
|
||||
])
|
||||
->add('comment', CommentType::class, [
|
||||
'required' => false,
|
||||
]);
|
||||
|
||||
if ('person' === $options['kind']) {
|
||||
$builder
|
||||
->add('hostPerson', PickPersonDynamicType::class, [
|
||||
'label' => 'Person',
|
||||
]);
|
||||
}
|
||||
|
||||
if ('thirdparty' === $options['kind']) {
|
||||
$builder
|
||||
->add('hostThirdParty', PickThirdpartyDynamicType::class, [
|
||||
'label' => 'Third party',
|
||||
]);
|
||||
}
|
||||
|
||||
if ('address' === $options['kind']) {
|
||||
$builder
|
||||
->add('address', PickAddressType::class, [
|
||||
'required' => false,
|
||||
'label' => 'Address',
|
||||
'use_valid_from' => false,
|
||||
'use_valid_to' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => ResidentialAddress::class,
|
||||
'kind' => null,
|
||||
]);
|
||||
}
|
||||
}
|
@@ -15,7 +15,6 @@ use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStep;
|
||||
use Chill\MainBundle\Form\Type\ChillTextareaType;
|
||||
use Chill\MainBundle\Form\Type\PickUserDynamicType;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
@@ -25,7 +24,6 @@ use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Workflow\Registry;
|
||||
use Symfony\Component\Workflow\Transition;
|
||||
use function array_key_exists;
|
||||
|
||||
class WorkflowStepType extends AbstractType
|
||||
{
|
||||
@@ -33,13 +31,10 @@ class WorkflowStepType extends AbstractType
|
||||
|
||||
private Registry $registry;
|
||||
|
||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||
|
||||
public function __construct(EntityWorkflowManager $entityWorkflowManager, Registry $registry, TranslatableStringHelperInterface $translatableStringHelper)
|
||||
public function __construct(EntityWorkflowManager $entityWorkflowManager, Registry $registry)
|
||||
{
|
||||
$this->entityWorkflowManager = $entityWorkflowManager;
|
||||
$this->registry = $registry;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
@@ -47,7 +42,6 @@ class WorkflowStepType extends AbstractType
|
||||
/** @var \Chill\MainBundle\Entity\Workflow\EntityWorkflow $entityWorkflow */
|
||||
$entityWorkflow = $options['entity_workflow'];
|
||||
$handler = $this->entityWorkflowManager->getHandler($entityWorkflow);
|
||||
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
|
||||
|
||||
if (true === $options['transition']) {
|
||||
if (null === $options['entity_workflow']) {
|
||||
@@ -59,49 +53,20 @@ class WorkflowStepType extends AbstractType
|
||||
->getEnabledTransitions($entityWorkflow);
|
||||
|
||||
$choices = array_combine(
|
||||
array_map(
|
||||
static function (Transition $transition) {
|
||||
return $transition->getName();
|
||||
},
|
||||
$transitions
|
||||
),
|
||||
array_map(static function (Transition $transition) { return $transition->getName(); }, $transitions),
|
||||
$transitions
|
||||
);
|
||||
|
||||
$builder
|
||||
->add('transition', ChoiceType::class, [
|
||||
'label' => 'workflow.Transition to apply',
|
||||
'label' => 'workflow.Transition',
|
||||
'mapped' => false,
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'choices' => $choices,
|
||||
'choice_label' => function (Transition $transition) use ($workflow) {
|
||||
$meta = $workflow->getMetadataStore()->getTransitionMetadata($transition);
|
||||
|
||||
if (array_key_exists('label', $meta)) {
|
||||
return $this->translatableStringHelper->localize($meta['label']);
|
||||
}
|
||||
|
||||
return $transition->getName();
|
||||
},
|
||||
'choice_attr' => static function (Transition $transition) use ($workflow) {
|
||||
$toFinal = true;
|
||||
|
||||
foreach ($transition->getTos() as $to) {
|
||||
$meta = $workflow->getMetadataStore()->getPlaceMetadata($to);
|
||||
|
||||
if (
|
||||
!array_key_exists('isFinal', $meta) || false === $meta['isFinal']
|
||||
) {
|
||||
$toFinal = false;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'data-is-transition' => 'data-is-transition',
|
||||
'data-to-final' => $toFinal ? '1' : '0',
|
||||
];
|
||||
},
|
||||
'choice_label' => static function (Transition $transition) {
|
||||
return implode(', ', $transition->getTos());
|
||||
},
|
||||
])
|
||||
->add('future_dest_users', PickUserDynamicType::class, [
|
||||
'label' => 'workflow.dest for next steps',
|
||||
@@ -123,6 +88,11 @@ class WorkflowStepType extends AbstractType
|
||||
}
|
||||
|
||||
$builder
|
||||
->add('finalizeAfter', CheckboxType::class, [
|
||||
'required' => false,
|
||||
'label' => 'workflow.Finalize',
|
||||
'help' => 'workflow.The workflow will be finalized',
|
||||
])
|
||||
->add('comment', ChillTextareaType::class, [
|
||||
'required' => false,
|
||||
'label' => 'Comment',
|
||||
|
@@ -11,27 +11,17 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Notification\Templating;
|
||||
|
||||
use Chill\MainBundle\Entity\NotificationComment;
|
||||
use Chill\MainBundle\Form\NotificationCommentType;
|
||||
use Chill\MainBundle\Notification\NotificationPresence;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Twig\Environment;
|
||||
use Twig\Extension\RuntimeExtensionInterface;
|
||||
|
||||
class NotificationTwigExtensionRuntime implements RuntimeExtensionInterface
|
||||
{
|
||||
private FormFactoryInterface $formFactory;
|
||||
|
||||
private NotificationPresence $notificationPresence;
|
||||
|
||||
private UrlGeneratorInterface $urlGenerator;
|
||||
|
||||
public function __construct(FormFactoryInterface $formFactory, NotificationPresence $notificationPresence, UrlGeneratorInterface $urlGenerator)
|
||||
public function __construct(NotificationPresence $notificationPresence)
|
||||
{
|
||||
$this->formFactory = $formFactory;
|
||||
$this->notificationPresence = $notificationPresence;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
}
|
||||
|
||||
public function counterNotificationFor(Environment $environment, string $relatedEntityClass, int $relatedEntityId, array $options = []): string
|
||||
@@ -57,24 +47,8 @@ class NotificationTwigExtensionRuntime implements RuntimeExtensionInterface
|
||||
return '';
|
||||
}
|
||||
|
||||
$appendCommentForms = [];
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
$appendComment = new NotificationComment();
|
||||
$appendCommentForms[$notification->getId()] = $this->formFactory->create(
|
||||
NotificationCommentType::class,
|
||||
$appendComment,
|
||||
[
|
||||
'action' => $this->urlGenerator->generate(
|
||||
'chill_main_notification_show',
|
||||
['id' => $notification->getId()]
|
||||
),
|
||||
]
|
||||
)->createView();
|
||||
}
|
||||
|
||||
return $environment->render('@ChillMain/Notification/extension_list_notifications_for.html.twig', [
|
||||
'notifications' => $notifications, 'appendCommentForms' => $appendCommentForms,
|
||||
'notifications' => $notifications,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@@ -193,29 +193,6 @@ final class NotificationRepository implements ObjectRepository
|
||||
return $this->repository->findOneBy($criteria, $orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|Notification[]
|
||||
*/
|
||||
public function findUnreadByUser(User $user, int $limit = 20, int $offset = 0): array
|
||||
{
|
||||
$rsm = new Query\ResultSetMappingBuilder($this->em);
|
||||
$rsm->addRootEntityFromClassMetadata(Notification::class, 'cmn');
|
||||
|
||||
$sql = 'SELECT ' . $rsm->generateSelectClause(['cmn' => 'cmn']) . ' ' .
|
||||
'FROM chill_main_notification cmn ' .
|
||||
'WHERE ' .
|
||||
'EXISTS (select 1 FROM chill_main_notification_addresses_unread cmnau WHERE cmnau.user_id = :userId and cmnau.notification_id = cmn.id) ' .
|
||||
'ORDER BY cmn.date DESC ' .
|
||||
'LIMIT :limit OFFSET :offset';
|
||||
|
||||
$nq = $this->em->createNativeQuery($sql, $rsm)
|
||||
->setParameter('userId', $user->getId())
|
||||
->setParameter('limit', $limit)
|
||||
->setParameter('offset', $offset);
|
||||
|
||||
return $nq->getResult();
|
||||
}
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return Notification::class;
|
||||
|
@@ -1,59 +0,0 @@
|
||||
<?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\Repository;
|
||||
|
||||
use Chill\MainBundle\Entity\ResidentialAddress;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @method ResidentialAddress|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method ResidentialAddress|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method ResidentialAddress[] findAll()
|
||||
* @method ResidentialAddress[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class ResidentialAddressRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, ResidentialAddress::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return ResidentialAddress[] Returns an array of ResidentialAddress objects
|
||||
// */
|
||||
/*
|
||||
public function findByExampleField($value)
|
||||
{
|
||||
return $this->createQueryBuilder('r')
|
||||
->andWhere('r.exampleField = :val')
|
||||
->setParameter('val', $value)
|
||||
->orderBy('r.id', 'ASC')
|
||||
->setMaxResults(10)
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public function findOneBySomeField($value): ?ResidentialAddress
|
||||
{
|
||||
return $this->createQueryBuilder('r')
|
||||
->andWhere('r.exampleField = :val')
|
||||
->setParameter('val', $value)
|
||||
->getQuery()
|
||||
->getOneOrNullResult()
|
||||
;
|
||||
}
|
||||
*/
|
||||
}
|
@@ -474,7 +474,6 @@ div.workflow {
|
||||
// Override bootstrap popover styles
|
||||
div.popover {
|
||||
box-shadow: 0 0 10px -5px $dark;
|
||||
z-index: 9999;
|
||||
.popover-arrow {}
|
||||
.popover-header {}
|
||||
.popover-body {}
|
||||
|
@@ -12,7 +12,6 @@
|
||||
display: block;
|
||||
top: calc(50% - 7px);
|
||||
right: 10px;
|
||||
line-height: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,19 +62,14 @@ ul.list-suggest {
|
||||
& span:hover {
|
||||
color: $chill-l-gray;
|
||||
}
|
||||
.person-text {
|
||||
span {
|
||||
padding-left: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.remove-items {
|
||||
li {
|
||||
position: relative;
|
||||
& > span {
|
||||
span {
|
||||
display: block;
|
||||
padding-right: 1.75rem;
|
||||
padding-right: .75rem;
|
||||
@include remove_link;
|
||||
}
|
||||
}
|
||||
|
@@ -21,8 +21,7 @@ $chill-theme-buttons: (
|
||||
"download": $gray-300,
|
||||
"cancel": $gray-300,
|
||||
"choose": $gray-300,
|
||||
"notify": $chill-blue,
|
||||
"search": $gray-300,
|
||||
"notify": $gray-300,
|
||||
"unlink": $chill-red,
|
||||
"tpchild": $chill-pink,
|
||||
);
|
||||
@@ -81,7 +80,6 @@ $chill-theme-buttons: (
|
||||
&.btn-notify::before,
|
||||
&.btn-tpchild::before,
|
||||
&.btn-download::before,
|
||||
&.btn-search::before,
|
||||
&.btn-cancel::before {
|
||||
font: normal normal normal 14px/1 ForkAwesome;
|
||||
margin-right: 0.5em;
|
||||
@@ -110,7 +108,6 @@ $chill-theme-buttons: (
|
||||
&.btn-notify::before { content: "\f1d8"; } // fa-paper-plane
|
||||
&.btn-tpchild::before { content: "\f007"; } // fa-user
|
||||
&.btn-download::before { content: "\f019"; } // fa-download
|
||||
&.btn-search::before { content: "\f002"; } // fa-search
|
||||
}
|
||||
|
||||
|
||||
@@ -136,18 +133,3 @@ $chill-theme-buttons: (
|
||||
.btn-sm, .btn-group-sm > .btn {
|
||||
min-width: 36px;
|
||||
}
|
||||
|
||||
// Homepage special fast action buttons
|
||||
div.sticky-buttons {
|
||||
position: fixed;
|
||||
bottom: 3em;
|
||||
right: 2em;
|
||||
.btn-circle {
|
||||
width: 50px; height: 50px;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
padding: 0.45rem 0.7rem;
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
@@ -39,7 +39,6 @@ var ShowHide = function(options) {
|
||||
contents.push(el);
|
||||
}
|
||||
container_content.push(contents);
|
||||
// console.log('container content', container_content);
|
||||
}
|
||||
|
||||
// attach the listener on each input
|
||||
|
@@ -1,19 +1,21 @@
|
||||
require('./blur.scss');
|
||||
|
||||
document.querySelectorAll('.confidential').forEach(function (el) {
|
||||
let i = document.createElement('i');
|
||||
const classes = ['fa', 'fa-eye', 'toggle'];
|
||||
i.classList.add(...classes);
|
||||
el.appendChild(i);
|
||||
const toggleBlur = function(e) {
|
||||
for (let child of el.children) {
|
||||
if (!child.classList.contains('toggle')) {
|
||||
child.classList.toggle('blur');
|
||||
}
|
||||
}
|
||||
i.classList.toggle('fa-eye');
|
||||
i.classList.toggle('fa-eye-slash');
|
||||
}
|
||||
i.addEventListener('click', toggleBlur);
|
||||
toggleBlur();
|
||||
});
|
||||
var toggleBlur = function(e){
|
||||
|
||||
var btn = e.target;
|
||||
|
||||
btn.previousElementSibling.classList.toggle("blur");
|
||||
btn.classList.toggle("fa-eye");
|
||||
btn.classList.toggle("fa-eye-slash");
|
||||
|
||||
}
|
||||
|
||||
var infos = document.getElementsByClassName("confidential");
|
||||
for(var i=0; i < infos.length; i++){
|
||||
infos[i].insertAdjacentHTML('beforeend', '<i class="fa fa-eye toggle" aria-hidden="true"></i>');
|
||||
}
|
||||
|
||||
var toggles = document.getElementsByClassName("toggle");
|
||||
for(var i=0; i < toggles.length; i++){
|
||||
toggles[i].addEventListener("click", toggleBlur);
|
||||
}
|
@@ -1,34 +1,49 @@
|
||||
import { createApp } from "vue";
|
||||
import ListWorkflowModalVue from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue';
|
||||
import { _createI18n } from "ChillMainAssets/vuejs/_js/i18n";
|
||||
import PickWorkflowVue from 'ChillMainAssets/vuejs/_components/EntityWorkflow/PickWorkflow.vue';
|
||||
import ListWorkflowVue from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflow.vue';
|
||||
|
||||
const i18n = _createI18n({});
|
||||
|
||||
// list workflow
|
||||
document.querySelectorAll('[data-list-workflows]')
|
||||
.forEach(function (el) {
|
||||
// pick workflow
|
||||
document.querySelectorAll('[data-pick-workflow]')
|
||||
.forEach(function(el) {
|
||||
const app = {
|
||||
components: {
|
||||
ListWorkflowModalVue,
|
||||
PickWorkflowVue
|
||||
},
|
||||
template:
|
||||
'<list-workflow-modal-vue ' +
|
||||
':workflows="workflows" ' +
|
||||
':allowCreate="allowCreate" ' +
|
||||
'<pick-workflow-vue ' +
|
||||
':relatedEntityClass="relatedEntityClass" ' +
|
||||
':relatedEntityId="relatedEntityId" ' +
|
||||
':workflowsAvailables="workflowsAvailables" ' +
|
||||
'></list-workflow-modal-vue>',
|
||||
'></pick-workflow-vue>',
|
||||
data() {
|
||||
return {
|
||||
workflows: JSON.parse(el.dataset.workflows),
|
||||
allowCreate: el.dataset.allowCreate === "1",
|
||||
relatedEntityClass: el.dataset.relatedEntityClass,
|
||||
relatedEntityId: Number.parseInt(el.dataset.relatedEntityId),
|
||||
workflowsAvailables: JSON.parse(el.dataset.workflowsAvailables),
|
||||
}
|
||||
}
|
||||
};
|
||||
createApp(app).use(i18n).mount(el);
|
||||
createApp(app).mount(el);
|
||||
})
|
||||
;
|
||||
|
||||
// list workflow
|
||||
document.querySelectorAll('[data-list-workflows]')
|
||||
.forEach(function (el) {
|
||||
const app = {
|
||||
components: {
|
||||
ListWorkflowVue,
|
||||
},
|
||||
template:
|
||||
'<list-workflow-vue ' +
|
||||
':workflows="workflows" ' +
|
||||
'></list-workflow-vue>',
|
||||
data() {
|
||||
return {
|
||||
workflows: JSON.parse(el.dataset.workflows),
|
||||
}
|
||||
}
|
||||
};
|
||||
createApp(app).mount(el);
|
||||
})
|
||||
;
|
@@ -5,27 +5,18 @@ import { appMessages } from 'ChillMainAssets/vuejs/PickEntity/i18n';
|
||||
|
||||
const i18n = _createI18n(appMessages);
|
||||
|
||||
let appsOnPage = new Map();
|
||||
window.addEventListener('DOMContentLoaded', function(e) {
|
||||
|
||||
function loadDynamicPicker(element) {
|
||||
|
||||
let apps = element.querySelectorAll('[data-module="pick-dynamic"]');
|
||||
let apps = document.querySelectorAll('[data-module="pick-dynamic"]');
|
||||
|
||||
apps.forEach(function(el) {
|
||||
|
||||
const
|
||||
isMultiple = parseInt(el.dataset.multiple) === 1,
|
||||
uniqId = el.dataset.uniqid,
|
||||
input = element.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'),
|
||||
picked = (isMultiple) ? (JSON.parse(input.value)) : ((input.value === '[]') ? (null) : ([JSON.parse(input.value)]));
|
||||
input = document.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'),
|
||||
picked = isMultiple ? JSON.parse(input.value) : [JSON.parse(input.value)];
|
||||
|
||||
if (!isMultiple) {
|
||||
if (input.value === '[]'){
|
||||
input.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
const app = createApp({
|
||||
createApp({
|
||||
template: '<pick-entity ' +
|
||||
':multiple="multiple" ' +
|
||||
':types="types" ' +
|
||||
@@ -74,36 +65,5 @@ function loadDynamicPicker(element) {
|
||||
})
|
||||
.use(i18n)
|
||||
.mount(el);
|
||||
|
||||
appsOnPage.set(uniqId, app);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
document.addEventListener('show-hide-show', function(e) {
|
||||
console.log('creation event caught')
|
||||
loadDynamicPicker(e.detail.container)
|
||||
})
|
||||
|
||||
document.addEventListener('show-hide-hide', function(e) {
|
||||
console.log('hiding event caught')
|
||||
e.detail.container.querySelectorAll('[data-module="pick-dynamic"]').forEach((el) => {
|
||||
let uniqId = el.dataset.uniqid;
|
||||
console.log(uniqId);
|
||||
if (appsOnPage.has(uniqId)) {
|
||||
appsOnPage.get(uniqId).unmount();
|
||||
console.log('App has been unmounted')
|
||||
appsOnPage.delete(uniqId);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function(e) {
|
||||
console.log('loaded event', e)
|
||||
loadDynamicPicker(document)
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
@@ -1,16 +0,0 @@
|
||||
import { createApp } from 'vue';
|
||||
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n';
|
||||
import { appMessages } from 'ChillMainAssets/vuejs/HomepageWidget/js/i18n';
|
||||
import { store } from 'ChillMainAssets/vuejs/HomepageWidget/js/store';
|
||||
import App from 'ChillMainAssets/vuejs/HomepageWidget/App';
|
||||
|
||||
const i18n = _createI18n(appMessages);
|
||||
|
||||
const app = createApp({
|
||||
template: `<app></app>`,
|
||||
})
|
||||
.use(store)
|
||||
.use(i18n)
|
||||
.component('app', App)
|
||||
.mount('#homepage_widget')
|
||||
;
|
@@ -562,7 +562,6 @@ export default {
|
||||
this.entity.loaded.cities = [];
|
||||
this.entity.loaded.countries = [];
|
||||
|
||||
this.entity.selected.confidential = this.context.edit ? this.entity.address.confidential : false;
|
||||
this.entity.selected.isNoAddress = (this.context.edit && this.entity.address.text === '') ? true : false;
|
||||
|
||||
this.entity.selected.country = this.context.edit ? this.entity.address.country : {};
|
||||
@@ -594,7 +593,6 @@ export default {
|
||||
{
|
||||
console.log('apply changes');
|
||||
let newAddress = {
|
||||
'confidential': this.entity.selected.confidential,
|
||||
'isNoAddress': this.entity.selected.isNoAddress,
|
||||
'street': this.entity.selected.isNoAddress ? '' : this.entity.selected.address.street,
|
||||
'streetNumber': this.entity.selected.isNoAddress ? '' : this.entity.selected.address.streetNumber,
|
||||
|
@@ -6,6 +6,7 @@
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
name="floor"
|
||||
maxlength=16
|
||||
:placeholder="$t('floor')"
|
||||
v-model="floor"/>
|
||||
<label for="floor">{{ $t('floor') }}</label>
|
||||
@@ -14,6 +15,7 @@
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
name="corridor"
|
||||
maxlength=16
|
||||
:placeholder="$t('corridor')"
|
||||
v-model="corridor"/>
|
||||
<label for="corridor">{{ $t('corridor') }}</label>
|
||||
@@ -22,6 +24,7 @@
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
name="steps"
|
||||
maxlength=16
|
||||
:placeholder="$t('steps')"
|
||||
v-model="steps"/>
|
||||
<label for="steps">{{ $t('steps') }}</label>
|
||||
@@ -30,6 +33,7 @@
|
||||
<input class="form-control"
|
||||
type="text"
|
||||
name="flat"
|
||||
maxlength=16
|
||||
:placeholder="$t('flat')"
|
||||
v-model="flat"/>
|
||||
<label for="flat">{{ $t('flat') }}</label>
|
||||
|
@@ -17,22 +17,12 @@
|
||||
<div class="row my-3">
|
||||
<div class="col-lg-6">
|
||||
|
||||
<div class="form-check">
|
||||
<input type="checkbox"
|
||||
class="form-check-input"
|
||||
id="isConfidential"
|
||||
v-model="isConfidential"
|
||||
:value="valueConfidential" />
|
||||
<label class="form-check-label" for="isConfidential">
|
||||
{{ $t('isConfidential') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input type="checkbox"
|
||||
class="form-check-input"
|
||||
id="isNoAddress"
|
||||
v-model="isNoAddress"
|
||||
:value="value" />
|
||||
v-bind:value="value" />
|
||||
<label class="form-check-label" for="isNoAddress">
|
||||
{{ $t('isNoAddress') }}
|
||||
</label>
|
||||
@@ -128,8 +118,7 @@ export default {
|
||||
emits: ['getCities', 'getReferenceAddresses'],
|
||||
data() {
|
||||
return {
|
||||
value: false,
|
||||
valueConfidential: false,
|
||||
value: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -145,14 +134,6 @@ export default {
|
||||
addressMap() {
|
||||
return this.entity.addressMap;
|
||||
},
|
||||
isConfidential: {
|
||||
set(value) {
|
||||
this.entity.selected.confidential = value;
|
||||
},
|
||||
get() {
|
||||
return this.entity.selected.confidential;
|
||||
}
|
||||
},
|
||||
isNoAddress: {
|
||||
set(value) {
|
||||
console.log('isNoAddress value', value);
|
||||
|
@@ -18,7 +18,6 @@ const addressMessages = {
|
||||
other_address: 'Autre adresse',
|
||||
create_address: 'Adresse inconnue. Cliquez ici pour créer une nouvelle adresse',
|
||||
isNoAddress: 'Pas d\'adresse complète',
|
||||
isConfidential: 'Adresse confidentielle',
|
||||
street: 'Nom de rue',
|
||||
streetNumber: 'Numéro',
|
||||
floor: 'Étage',
|
||||
|
@@ -1,140 +0,0 @@
|
||||
<template>
|
||||
|
||||
<h2>{{ $t('main_title') }}</h2>
|
||||
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link"
|
||||
:class="{'active': activeTab === 'MyCustoms'}"
|
||||
@click="selectTab('MyCustoms')">
|
||||
<i class="fa fa-dashboard"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link"
|
||||
:class="{'active': activeTab === 'MyNotifications'}"
|
||||
@click="selectTab('MyNotifications')">
|
||||
{{ $t('my_notifications.tab') }}
|
||||
<tab-counter :count="state.notifications.count"></tab-counter>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link"
|
||||
:class="{'active': activeTab === 'MyAccompanyingCourses'}"
|
||||
@click="selectTab('MyAccompanyingCourses')">
|
||||
{{ $t('my_accompanying_courses.tab') }}
|
||||
<tab-counter :count="state.accompanyingCourses.count"></tab-counter>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link"
|
||||
:class="{'active': activeTab === 'MyWorks'}"
|
||||
@click="selectTab('MyWorks')">
|
||||
{{ $t('my_works.tab') }}
|
||||
<tab-counter :count="state.works.count"></tab-counter>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link"
|
||||
:class="{'active': activeTab === 'MyEvaluations'}"
|
||||
@click="selectTab('MyEvaluations')">
|
||||
{{ $t('my_evaluations.tab') }}
|
||||
<tab-counter :count="state.evaluations.count"></tab-counter>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link"
|
||||
:class="{'active': activeTab === 'MyTasks'}"
|
||||
@click="selectTab('MyTasks')">
|
||||
{{ $t('my_tasks.tab') }}
|
||||
<tab-counter :count="state.tasks.warning.count"></tab-counter>
|
||||
<tab-counter :count="state.tasks.alert.count"></tab-counter>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item loading ms-auto py-2" v-if="loading">
|
||||
<i class="fa fa-circle-o-notch fa-spin fa-lg text-chill-gray" :title="$t('loading')"></i>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="my-4">
|
||||
<my-customs
|
||||
v-if="activeTab === 'MyCustoms'">
|
||||
</my-customs>
|
||||
<my-works
|
||||
v-else-if="activeTab === 'MyWorks'">
|
||||
</my-works>
|
||||
<my-evaluations
|
||||
v-else-if="activeTab === 'MyEvaluations'">
|
||||
</my-evaluations>
|
||||
<my-tasks
|
||||
v-else-if="activeTab === 'MyTasks'">
|
||||
</my-tasks>
|
||||
<my-accompanying-courses
|
||||
v-else-if="activeTab === 'MyAccompanyingCourses'">
|
||||
</my-accompanying-courses>
|
||||
<my-notifications
|
||||
v-else-if="activeTab === 'MyNotifications'">
|
||||
</my-notifications>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MyCustoms from './MyCustoms';
|
||||
import MyWorks from './MyWorks';
|
||||
import MyEvaluations from './MyEvaluations';
|
||||
import MyTasks from './MyTasks';
|
||||
import MyAccompanyingCourses from './MyAccompanyingCourses';
|
||||
import MyNotifications from './MyNotifications';
|
||||
import TabCounter from './TabCounter';
|
||||
import { mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
components: {
|
||||
MyCustoms,
|
||||
MyWorks,
|
||||
MyEvaluations,
|
||||
MyTasks,
|
||||
MyAccompanyingCourses,
|
||||
MyNotifications,
|
||||
TabCounter,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'MyCustoms'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'loading',
|
||||
]),
|
||||
// just to see all in devtool :
|
||||
...mapState({
|
||||
state: (state) => state,
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
selectTab(tab) {
|
||||
this.$store.dispatch('getByTab', { tab: tab });
|
||||
this.activeTab = tab;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
for (const m of [
|
||||
'MyNotifications',
|
||||
'MyAccompanyingCourses',
|
||||
'MyWorks',
|
||||
'MyEvaluations',
|
||||
'MyTasks',
|
||||
]) {
|
||||
this.$store.dispatch('getByTab', { tab: m, param: "countOnly=1" });
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
a.nav-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
@@ -1,60 +0,0 @@
|
||||
<template>
|
||||
<div class="alert alert-light">{{ $t('my_accompanying_courses.description') }}</div>
|
||||
<span v-if="noResults" class="chill-no-data-statement">{{ $t('no_data') }}</span>
|
||||
<tab-table v-else>
|
||||
<template v-slot:thead>
|
||||
<th scope="col">id</th>
|
||||
<th scope="col">Ouvert le</th>
|
||||
<th scope="col">Usagers concernés</th>
|
||||
<th scope="col"></th>
|
||||
</template>
|
||||
<template v-slot:tbody>
|
||||
<tr v-for="(c, i) in accompanyingCourses.results" :key="`course-${i}`">
|
||||
<td>{{ c.id}}</td>
|
||||
<td>{{ $d(c.openingDate.datetime, 'long') }}</td>
|
||||
<td>{{ c.participations.length }}</td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-show" :href="getUrl(c)">
|
||||
{{ $t('show_entity', { entity: $t('the_course') }) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tab-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import TabTable from "./TabTable";
|
||||
|
||||
export default {
|
||||
name: "MyAccompanyingCourses",
|
||||
components: {
|
||||
TabTable
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'accompanyingCourses',
|
||||
]),
|
||||
...mapGetters([
|
||||
'isAccompanyingCoursesLoaded',
|
||||
]),
|
||||
noResults() {
|
||||
if (!this.isAccompanyingCoursesLoaded) {
|
||||
return false;
|
||||
} else {
|
||||
return this.accompanyingCourses.count === 0;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getUrl(c) {
|
||||
return `/fr/parcours/${c.id}`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -1,77 +0,0 @@
|
||||
<template>
|
||||
<span v-if="noResults" class="chill-no-data-statement">{{ $t('no_dashboard') }}</span>
|
||||
<div v-else id="dashboards" class="row g-3" data-masonry='{"percentPosition": true }'>
|
||||
|
||||
<div class="mbloc col col-sm-6 col-lg-4">
|
||||
<div class="custom1">
|
||||
<ul class="list-unstyled">
|
||||
<li v-if="counter.notifications > 0">
|
||||
<b>{{ counter.notifications }}</b> {{ $t('counter.unread_notifications') }}
|
||||
</li>
|
||||
<li v-if="counter.accompanyingCourses > 0">
|
||||
<b>{{ counter.accompanyingCourses }}</b> {{ $t('counter.assignated_courses') }}
|
||||
</li>
|
||||
<li v-if="counter.works > 0">
|
||||
<b>{{ counter.works }}</b> {{ $t('counter.assignated_actions') }}
|
||||
</li>
|
||||
<li v-if="counter.evaluations > 0">
|
||||
<b>{{ counter.evaluations }}</b> {{ $t('counter.assignated_evaluations') }}
|
||||
</li>
|
||||
<li v-if="counter.tasksAlert > 0">
|
||||
<b>{{ counter.tasksAlert }}</b> {{ $t('counter.alert_tasks') }}
|
||||
</li>
|
||||
<li v-if="counter.tasksWarning > 0">
|
||||
<b>{{ counter.tasksWarning }}</b> {{ $t('counter.warning_tasks') }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="mbloc col col-sm-6 col-lg-4">
|
||||
<div class="custom2">
|
||||
Mon dashboard personnalisé
|
||||
</div>
|
||||
</div>
|
||||
<div class="mbloc col col-sm-6 col-lg-4">
|
||||
<div class="custom3">
|
||||
Mon dashboard personnalisé
|
||||
</div>
|
||||
</div>
|
||||
<div class="mbloc col col-sm-6 col-lg-4">
|
||||
<div class="custom4">
|
||||
Mon dashboard personnalisé
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import Masonry from 'masonry-layout/masonry';
|
||||
|
||||
export default {
|
||||
name: "MyCustoms",
|
||||
computed: {
|
||||
...mapGetters(['counter']),
|
||||
noResults() {
|
||||
return false
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const elem = document.querySelector('#dashboards');
|
||||
const masonry = new Masonry(elem, {});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
div.custom4,
|
||||
div.custom3,
|
||||
div.custom2 {
|
||||
font-style: italic;
|
||||
color: var(--bs-chill-gray);
|
||||
}
|
||||
</style>
|
@@ -1,57 +0,0 @@
|
||||
<template>
|
||||
<div class="alert alert-light">{{ $t('my_evaluations.description') }}</div>
|
||||
<span v-if="noResults" class="chill-no-data-statement">{{ $t('no_data') }}</span>
|
||||
<tab-table v-else>
|
||||
<template v-slot:thead>
|
||||
<th scope="col">id</th>
|
||||
<th scope="col"></th>
|
||||
</template>
|
||||
<template v-slot:tbody>
|
||||
<tr v-for="(e, i) in evaluations.results" :key="`evaluation-${i}`">
|
||||
<td>{{ e.id}}</td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-show" :href="getUrl(e)">
|
||||
{{ $t('show_entity', { entity: $t('the_evaluation') }) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tab-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import TabTable from "./TabTable";
|
||||
|
||||
export default {
|
||||
name: "MyEvaluations",
|
||||
components: {
|
||||
TabTable
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'evaluations',
|
||||
]),
|
||||
...mapGetters([
|
||||
'isEvaluationsLoaded',
|
||||
]),
|
||||
noResults() {
|
||||
if (!this.isEvaluationsLoaded) {
|
||||
return false;
|
||||
} else {
|
||||
return this.evaluations.count === 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getUrl(e) {
|
||||
let anchor = '#evaluations';
|
||||
return `/fr/person/accompanying-period/work/${e.id}/edit${anchor}`
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -1,96 +0,0 @@
|
||||
<template>
|
||||
<div class="alert alert-light">{{ $t('my_notifications.description') }}</div>
|
||||
<span v-if="noResults" class="chill-no-data-statement">{{ $t('no_data') }}</span>
|
||||
<tab-table v-else>
|
||||
<template v-slot:thead>
|
||||
<th scope="col">{{ $t('Date') }}</th>
|
||||
<th scope="col">{{ $t('Subject') }}</th>
|
||||
<th scope="col">{{ $t('From') }}</th>
|
||||
<th scope="col"></th>
|
||||
</template>
|
||||
<template v-slot:tbody>
|
||||
<tr v-for="(n, i) in notifications.results" :key="`notify-${i}`">
|
||||
<td>{{ $d(n.date.datetime, 'long') }}</td>
|
||||
<td>
|
||||
<span class="unread">
|
||||
<i class="fa fa-envelope-o"></i>
|
||||
<a :href="getNotificationUrl(n)">{{ n.title }}</a>
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ n.sender.text }}</td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-show"
|
||||
:href="getEntityUrl(n)">
|
||||
{{ $t('show_entity', { entity: getEntityName(n) }) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tab-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import TabTable from "./TabTable";
|
||||
import { appMessages } from 'ChillMainAssets/vuejs/HomepageWidget/js/i18n';
|
||||
|
||||
|
||||
export default {
|
||||
name: "MyNotifications",
|
||||
components: {
|
||||
TabTable
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'notifications',
|
||||
]),
|
||||
...mapGetters([
|
||||
'isNotificationsLoaded',
|
||||
]),
|
||||
noResults() {
|
||||
if (!this.isNotificationsLoaded) {
|
||||
return false;
|
||||
} else {
|
||||
return this.notifications.count === 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getNotificationUrl(n) {
|
||||
return `/fr/notification/${n.id}/show`
|
||||
},
|
||||
getEntityName(n) {
|
||||
switch (n.relatedEntityClass) {
|
||||
case 'Chill\\ActivityBundle\\Entity\\Activity':
|
||||
return appMessages.fr.the_activity;
|
||||
case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod':
|
||||
return appMessages.fr.the_course;
|
||||
default:
|
||||
throw 'notification type unknown';
|
||||
}
|
||||
},
|
||||
getEntityUrl(n) {
|
||||
switch (n.relatedEntityClass) {
|
||||
case 'Chill\\ActivityBundle\\Entity\\Activity':
|
||||
return `/fr/activity/${n.relatedEntityId}/show`
|
||||
case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod':
|
||||
return `/fr/parcours/${n.relatedEntityId}`
|
||||
default:
|
||||
throw 'notification type unknown';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
span.unread {
|
||||
font-weight: bold;
|
||||
i {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
a {
|
||||
text-decoration: unset;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,85 +0,0 @@
|
||||
<template>
|
||||
|
||||
<div class="alert alert-light">{{ $t('my_tasks.description_alert') }}</div>
|
||||
<span v-if="noResultsWarning" class="chill-no-data-statement">{{ $t('no_data') }}</span>
|
||||
<tab-table v-else>
|
||||
<template v-slot:thead>
|
||||
<th scope="col">id</th>
|
||||
<th scope="col"></th>
|
||||
</template>
|
||||
<template v-slot:tbody>
|
||||
<tr v-for="(t, i) in tasks.warning" :key="`task-warning-${i}`">
|
||||
<td>{{ t.id}}</td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-show" :href="getUrl(t)">
|
||||
{{ $t('show_entity', { entity: $t('the_task') }) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tab-table>
|
||||
|
||||
<div class="alert alert-light">{{ $t('my_tasks.description_warning') }}</div>
|
||||
<span v-if="noResultsAlert" class="chill-no-data-statement">{{ $t('no_data') }}</span>
|
||||
<tab-table v-else>
|
||||
<template v-slot:thead>
|
||||
<th scope="col">id</th>
|
||||
<th scope="col"></th>
|
||||
</template>
|
||||
<template v-slot:tbody>
|
||||
<tr v-for="(t, i) in tasks.alert" :key="`task-alert-${i}`">
|
||||
<td>{{ t.id}}</td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-show" :href="getUrl(t)">
|
||||
{{ $t('show_entity', { entity: $t('the_task') }) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tab-table>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import TabTable from "./TabTable";
|
||||
|
||||
export default {
|
||||
name: "MyTasks",
|
||||
components: {
|
||||
TabTable
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'tasks',
|
||||
]),
|
||||
...mapGetters([
|
||||
'isTasksWarningLoaded',
|
||||
'isTasksAlertLoaded',
|
||||
]),
|
||||
noResultsAlert() {
|
||||
if (!this.isTasksAlertLoaded) {
|
||||
return false;
|
||||
} else {
|
||||
return this.tasks.alert.count === 0;
|
||||
}
|
||||
},
|
||||
noResultsWarning() {
|
||||
if (!this.isTasksWarningLoaded) {
|
||||
return false;
|
||||
} else {
|
||||
return this.tasks.warning.count === 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getUrl(t) {
|
||||
return `/fr/task/single-task/${t.id}/show`
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -1,79 +0,0 @@
|
||||
<template>
|
||||
<div class="accompanying_course_work">
|
||||
<div class="alert alert-light">{{ $t('my_works.description') }}</div>
|
||||
<span v-if="noResults" class="chill-no-data-statement">{{ $t('no_data') }}</span>
|
||||
<tab-table v-else>
|
||||
<template v-slot:thead>
|
||||
<th scope="col">{{ $t('StartDate') }}</th>
|
||||
<th scope="col">{{ $t('SocialAction') }}</th>
|
||||
<th scope="col"></th>
|
||||
</template>
|
||||
<template v-slot:tbody>
|
||||
<tr v-for="(w, i) in works.results" :key="`works-${i}`">
|
||||
<td>{{ $d(w.startDate.datetime, 'short') }}</td>
|
||||
<td>
|
||||
<h4 class="badge-title">
|
||||
<span class="title_label"></span>
|
||||
<span class="title_action">
|
||||
{{ w.socialAction.text }}
|
||||
</span>
|
||||
</h4>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group" role="group" aria-label="Actions">
|
||||
<a class="btn btn-sm btn-update" :href="getUrl(w)">
|
||||
{{ $t('show_entity', { entity: $t('the_action') }) }}
|
||||
</a>
|
||||
<a class="btn btn-sm btn-show" :href="getUrl(w.accompanyingPeriod)">
|
||||
{{ $t('show_entity', { entity: $t('the_course') }) }}
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tab-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import TabTable from "./TabTable";
|
||||
|
||||
export default {
|
||||
name: "MyWorks",
|
||||
components: {
|
||||
TabTable
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'works',
|
||||
]),
|
||||
...mapGetters([
|
||||
'isWorksLoaded',
|
||||
]),
|
||||
noResults() {
|
||||
if (!this.isWorksLoaded) {
|
||||
return false;
|
||||
} else {
|
||||
return this.works.count === 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getUrl(e) {
|
||||
switch (e.type) {
|
||||
case 'accompanying_period_work':
|
||||
return `/fr/person/accompanying-period/work/${e.id}/edit`
|
||||
case 'accompanying_period':
|
||||
return `/fr/parcours/${e.id}`
|
||||
default:
|
||||
throw 'entity type unknown';
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<span v-if="isCounterAvailable"
|
||||
class="badge rounded-pill bg-danger counter">
|
||||
{{ count }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "TabCounter",
|
||||
props: ['count'],
|
||||
computed: {
|
||||
isCounterAvailable() {
|
||||
return (typeof this.count !== 'undefined' && this.count > 0 )
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -1,21 +0,0 @@
|
||||
<template>
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<slot name="thead"></slot>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<slot name="tbody"></slot>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "TabTable",
|
||||
props: []
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
@@ -1,54 +0,0 @@
|
||||
const appMessages = {
|
||||
fr: {
|
||||
main_title: "Vue d'ensemble",
|
||||
my_works: {
|
||||
tab: "Mes actions",
|
||||
description: "Liste des actions d'accompagnement dont je suis référent et qui arrivent à échéance.",
|
||||
},
|
||||
my_evaluations: {
|
||||
tab: "Mes évaluations",
|
||||
description: "Liste des évaluations dont je suis référent et qui arrivent à échéance.",
|
||||
},
|
||||
my_tasks: {
|
||||
tab: "Mes tâches",
|
||||
description_alert: "Liste des tâches auxquelles je suis assigné et dont la date de rappel est dépassée.",
|
||||
description_warning: "Liste des tâches auxquelles je suis assigné et dont la date d'échéance est dépassée.",
|
||||
},
|
||||
my_accompanying_courses: {
|
||||
tab: "Mes parcours",
|
||||
description: "Liste des parcours d'accompagnement que l'on vient de m'attribuer.",
|
||||
},
|
||||
my_notifications: {
|
||||
tab: "Mes notifications",
|
||||
description: "Liste des notifications reçues et non lues.",
|
||||
},
|
||||
Date: "Date",
|
||||
From: "De",
|
||||
Subject: "Objet",
|
||||
Entity: "Associé à",
|
||||
show_entity: "Voir {entity}",
|
||||
the_activity: "l'échange",
|
||||
the_course: "le parcours",
|
||||
the_action: "l'action",
|
||||
the_evaluation: "l'évaluation",
|
||||
the_task: "la tâche",
|
||||
StartDate: "Date d'ouverture",
|
||||
SocialAction: "Action d'accompagnement",
|
||||
no_data: "Aucun résultats",
|
||||
no_dashboard: "Pas de tableaux de bord",
|
||||
counter: {
|
||||
unread_notifications: "notifications non lues",
|
||||
assignated_courses: "parcours récents assignés",
|
||||
assignated_actions: "actions assignées",
|
||||
assignated_evaluations: "évaluations assignées",
|
||||
alert_tasks: "tâches en rappel",
|
||||
warning_tasks: "tâches à échéances",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Object.assign(appMessages.fr);
|
||||
|
||||
export {
|
||||
appMessages
|
||||
};
|
@@ -1,200 +0,0 @@
|
||||
import 'es6-promise/auto';
|
||||
import { createStore } from 'vuex';
|
||||
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
||||
import MyCustoms from "../MyCustoms";
|
||||
import MyWorks from "../MyWorks";
|
||||
import MyEvaluations from "../MyEvaluations";
|
||||
import MyTasks from "../MyTasks";
|
||||
import MyAccompanyingCourses from "../MyAccompanyingCourses";
|
||||
import MyNotifications from "../MyNotifications";
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production';
|
||||
|
||||
const isEmpty = (obj) => {
|
||||
return obj
|
||||
&& Object.keys(obj).length <= 1
|
||||
&& Object.getPrototypeOf(obj) === Object.prototype;
|
||||
};
|
||||
|
||||
const store = createStore({
|
||||
strict: debug,
|
||||
state: {
|
||||
works: {},
|
||||
evaluations: {},
|
||||
tasks: {
|
||||
warning: {},
|
||||
alert: {}
|
||||
},
|
||||
accompanyingCourses: {},
|
||||
notifications: {},
|
||||
errorMsg: [],
|
||||
loading: false
|
||||
},
|
||||
getters: {
|
||||
isWorksLoaded(state) {
|
||||
return !isEmpty(state.works);
|
||||
},
|
||||
isEvaluationsLoaded(state) {
|
||||
return !isEmpty(state.evaluations);
|
||||
},
|
||||
isTasksWarningLoaded(state) {
|
||||
return !isEmpty(state.tasks.warning);
|
||||
},
|
||||
isTasksAlertLoaded(state) {
|
||||
return !isEmpty(state.tasks.alert);
|
||||
},
|
||||
isAccompanyingCoursesLoaded(state) {
|
||||
return !isEmpty(state.accompanyingCourses);
|
||||
},
|
||||
isNotificationsLoaded(state) {
|
||||
return !isEmpty(state.notifications);
|
||||
},
|
||||
counter(state) {
|
||||
return {
|
||||
works: state.works.count,
|
||||
evaluations: state.evaluations.count,
|
||||
tasksWarning: state.tasks.warning.count,
|
||||
tasksAlert: state.tasks.alert.count,
|
||||
accompanyingCourses: state.accompanyingCourses.count,
|
||||
notifications: state.notifications.count,
|
||||
}
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
addWorks(state, works) {
|
||||
console.log('addWorks', works);
|
||||
state.works = works;
|
||||
},
|
||||
addEvaluations(state, evaluations) {
|
||||
console.log('addEvaluations', evaluations);
|
||||
state.evaluations = evaluations;
|
||||
},
|
||||
addTasksWarning(state, tasks) {
|
||||
console.log('addTasksWarning', tasks);
|
||||
state.tasks.warning = tasks;
|
||||
},
|
||||
addTasksAlert(state, tasks) {
|
||||
console.log('addTasksAlert', tasks);
|
||||
state.tasks.alert = tasks;
|
||||
},
|
||||
addCourses(state, courses) {
|
||||
console.log('addCourses', courses);
|
||||
state.accompanyingCourses = courses;
|
||||
},
|
||||
addNotifications(state, notifications) {
|
||||
console.log('addNotifications', notifications);
|
||||
state.notifications = notifications;
|
||||
},
|
||||
setLoading(state, bool) {
|
||||
state.loading = bool;
|
||||
},
|
||||
catchError(state, error) {
|
||||
state.errorMsg.push(error);
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
getByTab({ commit, getters }, { tab, param }) {
|
||||
switch (tab) {
|
||||
case 'MyCustoms':
|
||||
break;
|
||||
case 'MyWorks':
|
||||
if (!getters.isWorksLoaded) {
|
||||
commit('setLoading', true);
|
||||
const url = `/api/1.0/person/accompanying-period/work/my-near-end${'?'+ param}`;
|
||||
makeFetch('GET', url)
|
||||
.then((response) => {
|
||||
commit('addWorks', response);
|
||||
commit('setLoading', false);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
;
|
||||
}
|
||||
break;
|
||||
case 'MyEvaluations':
|
||||
if (!getters.isEvaluationsLoaded) {
|
||||
commit('setLoading', true);
|
||||
const url = `/api/1.0/person/accompanying-period/work/evaluation/my-near-end${'?'+ param}`;
|
||||
makeFetch('GET', url)
|
||||
.then((response) => {
|
||||
commit('addEvaluations', response);
|
||||
commit('setLoading', false);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
;
|
||||
}
|
||||
break;
|
||||
case 'MyTasks':
|
||||
if (!(getters.isTasksWarningLoaded && getters.isTasksAlertLoaded)) {
|
||||
commit('setLoading', true);
|
||||
const
|
||||
urlWarning = `/api/1.0/task/single-task/list/my?f[q]=&f[checkboxes][status][]=warning&f[checkboxes][states][]=new&f[checkboxes][states][]=in_progress${'&'+ param}`,
|
||||
urlAlert = `/api/1.0/task/single-task/list/my?f[q]=&f[checkboxes][status][]=alert&f[checkboxes][states][]=new&f[checkboxes][states][]=in_progress${'&'+ param}`
|
||||
;
|
||||
makeFetch('GET', urlWarning)
|
||||
.then((response) => {
|
||||
commit('addTasksWarning', response);
|
||||
commit('setLoading', false);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
;
|
||||
makeFetch('GET', urlAlert)
|
||||
.then((response) => {
|
||||
commit('addTasksAlert', response);
|
||||
commit('setLoading', false);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
;
|
||||
}
|
||||
break;
|
||||
case 'MyAccompanyingCourses':
|
||||
if (!getters.isAccompanyingCoursesLoaded) {
|
||||
commit('setLoading', true);
|
||||
const url = `/api/1.0/person/accompanying-course/list/by-recent-attributions${'?'+ param}`;
|
||||
makeFetch('GET', url)
|
||||
.then((response) => {
|
||||
commit('addCourses', response);
|
||||
commit('setLoading', false);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
;
|
||||
}
|
||||
break;
|
||||
case 'MyNotifications':
|
||||
if (!getters.isNotificationsLoaded) {
|
||||
commit('setLoading', true);
|
||||
const url = `/api/1.0/main/notification/my/unread${'?'+ param}`;
|
||||
makeFetch('GET', url)
|
||||
.then((response) => {
|
||||
commit('addNotifications', response);
|
||||
commit('setLoading', false);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw 'tab '+ tab;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export { store };
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ul class="list-suggest remove-items" v-if="picked.length">
|
||||
<ul class="list-suggest remove-items">
|
||||
<li v-for="p in picked" @click="removeEntity(p)" :key="p.type+p.id">
|
||||
<span class="chill_denomination">{{ p.text }}</span>
|
||||
</li>
|
||||
@@ -79,15 +79,11 @@ export default {
|
||||
);
|
||||
this.$refs.addPersons.resetSearch(); // to cast child method
|
||||
modal.showModal = false;
|
||||
console.log(this.picked)
|
||||
},
|
||||
removeEntity(entity) {
|
||||
console.log('remove entity', entity);
|
||||
this.$emit('removeEntity', entity);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.picked);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@@ -24,11 +24,6 @@
|
||||
{{ $t('user')}}
|
||||
</span>
|
||||
|
||||
<span v-if="entity.type === 'household'" class="badge rounded-pill bg-user">
|
||||
{{ $t('household')}}
|
||||
</span>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -45,8 +40,7 @@ export default {
|
||||
company: "Personne morale",
|
||||
contact: "Personne physique",
|
||||
},
|
||||
user: 'TMS',
|
||||
household: 'Ménage',
|
||||
user: 'TMS'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,26 +1,22 @@
|
||||
<template>
|
||||
<div :class="classes">
|
||||
<div class="confidential-content" :class="{ 'blur': isBlurred }">
|
||||
<div class="confidential" v-on:click="toggleBlur">
|
||||
<div class="confidential-content blur">
|
||||
<slot name="confidential-content"></slot>
|
||||
</div>
|
||||
<div>
|
||||
<i class="fa fa-eye toggle" aria-hidden="true" @click="toggleBlur"></i>
|
||||
</div>
|
||||
<i class="fa fa-eye toggle" aria-hidden="true"></i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Confidential",
|
||||
data() {
|
||||
return {
|
||||
isBlurred: true,
|
||||
};
|
||||
},
|
||||
methods : {
|
||||
toggleBlur() {
|
||||
console.log('toggle blur');
|
||||
this.isBlurred = !this.isBlurred;
|
||||
toggleBlur: function(e){
|
||||
if(e.target.matches('.toggle')){
|
||||
e.target.previousElementSibling.classList.toggle("blur");
|
||||
e.target.classList.toggle("fa-eye");
|
||||
e.target.classList.toggle("fa-eye-slash");
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -43,4 +39,4 @@ export default {
|
||||
-moz-filter: blur(5px);
|
||||
filter: blur(5px);
|
||||
}
|
||||
</style>
|
||||
</style>
|
@@ -1,58 +1,26 @@
|
||||
<template>
|
||||
|
||||
<component :is="component" class="chill-entity entity-address my-3">
|
||||
|
||||
<component :is="component" class="address" :class="multiline">
|
||||
|
||||
<div v-if="isConfidential">
|
||||
<confidential>
|
||||
<template v-slot:confidential-content>
|
||||
<div v-if="isMultiline === true">
|
||||
<p v-for="(l, i) in address.lines" :key="`line-${i}`">
|
||||
{{ l }}
|
||||
</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p v-if="address.text"
|
||||
class="street">
|
||||
{{ address.text }}
|
||||
</p>
|
||||
<p v-if="address.postcode"
|
||||
class="postcode">
|
||||
{{ address.postcode.code }} {{ address.postcode.name }}
|
||||
</p>
|
||||
<p v-if="address.country"
|
||||
class="country">
|
||||
{{ address.country.name.fr }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</confidential>
|
||||
<div v-if="isMultiline === true">
|
||||
<p v-for="(l, i) in address.lines" :key="`line-${i}`">
|
||||
{{ l }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-if="!isConfidential">
|
||||
<div v-if="isMultiline === true">
|
||||
<p v-for="(l, i) in address.lines" :key="`line-${i}`">
|
||||
{{ l }}
|
||||
</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p v-if="address.text"
|
||||
class="street">
|
||||
{{ address.text }}
|
||||
</p>
|
||||
<p v-if="address.postcode"
|
||||
class="postcode">
|
||||
{{ address.postcode.code }} {{ address.postcode.name }}
|
||||
</p>
|
||||
<p v-if="address.country"
|
||||
class="country">
|
||||
{{ address.country.name.fr }}
|
||||
</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p v-if="address.text"
|
||||
class="street">
|
||||
{{ address.text }}
|
||||
</p>
|
||||
<p v-if="address.postcode"
|
||||
class="postcode">
|
||||
{{ address.postcode.code }} {{ address.postcode.name }}
|
||||
</p>
|
||||
<p v-if="address.country"
|
||||
class="country">
|
||||
{{ address.country.name.fr }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</component>
|
||||
|
||||
<!-- <div v-if="isMultiline === true" class="address-more">
|
||||
@@ -110,14 +78,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||
|
||||
export default {
|
||||
name: 'AddressRenderBox',
|
||||
components: {
|
||||
Confidential
|
||||
},
|
||||
props: {
|
||||
address: {
|
||||
type: Object
|
||||
@@ -138,9 +100,6 @@ export default {
|
||||
multiline() {
|
||||
//console.log(this.isMultiline, typeof this.isMultiline);
|
||||
return this.isMultiline === true ? "multiline" : "";
|
||||
},
|
||||
isConfidential() {
|
||||
return this.address.confidential;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -1,86 +1,26 @@
|
||||
<template>
|
||||
<div class="flex-table workflow" id="workflow-list">
|
||||
<div v-for="(w, i) in workflows" :key="`workflow-${i}`"
|
||||
class="item-bloc">
|
||||
|
||||
<div>
|
||||
<div class="item-row col">
|
||||
<h2>Workflow</h2>
|
||||
<div class="flex-grow-1 ms-3 h3">
|
||||
<div class="visually-hidden">
|
||||
{{ w.relatedEntityClass }}
|
||||
{{ w.relatedEntityId }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="breadcrumb">
|
||||
<template v-for="(step, j) in w.steps" :key="`step-${j}`">
|
||||
<span class="mx-2"
|
||||
tabindex="0"
|
||||
data-bs-trigger="focus hover"
|
||||
data-bs-toggle="popover"
|
||||
data-bs-placement="bottom"
|
||||
data-bs-custom-class="workflow-transition"
|
||||
:title="getPopTitle(step)"
|
||||
:data-bs-content="getPopContent(step)">
|
||||
|
||||
<i v-if="step.currentStep.name === 'initial'"
|
||||
class="fa fa-circle me-1 text-chill-yellow">
|
||||
</i>
|
||||
<i v-if="step.isFreezed"
|
||||
class="fa fa-snowflake-o fa-sm me-1">
|
||||
</i>
|
||||
{{ step.currentStep.text }}
|
||||
</span>
|
||||
<span v-if="j !== Object.keys(w.steps).length - 1">
|
||||
→
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-row">
|
||||
<div class="item-col flex-grow-1">
|
||||
<p v-if="isUserSubscribedToStep(w)">
|
||||
<i class="fa fa-check fa-fw"></i>
|
||||
{{ $t('you_subscribed_to_all_steps') }}
|
||||
</p>
|
||||
<p v-if="isUserSubscribedToFinal(w)">
|
||||
<i class="fa fa-check fa-fw"></i>
|
||||
{{ $t('you_subscribed_to_final_step') }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="item-col">
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a :href="goToUrl(w)" class="btn btn-sm btn-show" :title="$t('action.show')"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="list-group my-2 workflow workflow-box">
|
||||
<div class="list-group-item">
|
||||
<h4>Workflow associés</h4>
|
||||
</div>
|
||||
<div class="list-group-item" v-for="w in workflows">
|
||||
{{ w.id }}
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a class="btn btn-sm btn-outline-primary"
|
||||
title="voir"
|
||||
:href="goToUrl(w)">
|
||||
<i class="fa fa-eye fa-fw"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Popover from 'bootstrap/js/src/popover';
|
||||
|
||||
const i18n = {
|
||||
messages: {
|
||||
fr: {
|
||||
you_subscribed_to_all_steps: "Vous recevrez une notification à chaque étape",
|
||||
you_subscribed_to_final_step: "Vous recevrez une notification à l'étape finale",
|
||||
by: "Par",
|
||||
at: "Le"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "ListWorkflow",
|
||||
i18n: i18n,
|
||||
props: {
|
||||
workflows: {
|
||||
type: Array,
|
||||
@@ -90,42 +30,7 @@ export default {
|
||||
methods: {
|
||||
goToUrl(w) {
|
||||
return `/fr/main/workflow/${w.id}/show`;
|
||||
},
|
||||
getPopTitle(step) {
|
||||
if (step.transitionPrevious != null) {
|
||||
let freezed = step.isFreezed ? `<i class="fa fa-snowflake-o fa-sm me-1"></i>` : ``;
|
||||
return `${freezed}${step.currentStep.text}`;
|
||||
}
|
||||
},
|
||||
getPopContent(step) {
|
||||
if (step.transitionPrevious != null) {
|
||||
return `<ul class="small_in_title">
|
||||
<li><span class="item-key">${i18n.messages.fr.by} : </span><b>${step.transitionPreviousBy.text}</b></li>
|
||||
<li><span class="item-key">${i18n.messages.fr.at} : </span><b>${this.formatDate(step.transitionPreviousAt.datetime)}</b></li>
|
||||
</ul>`
|
||||
;
|
||||
}
|
||||
},
|
||||
formatDate(datetime) {
|
||||
return datetime.split('T')[0] +' '+ datetime.split('T')[1].substring(0,5)
|
||||
},
|
||||
isUserSubscribedToStep(w) {
|
||||
// todo
|
||||
return false;
|
||||
},
|
||||
isUserSubscribedToFinal(w) {
|
||||
// todo
|
||||
return false;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const triggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
|
||||
const popoverList = triggerList.map(function (el) {
|
||||
//console.log('popover', el)
|
||||
return new Popover(el, {
|
||||
html: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
@@ -1,111 +0,0 @@
|
||||
<template>
|
||||
|
||||
<button v-if="hasWorkflow"
|
||||
class="btn btn-primary"
|
||||
@click="openModal">
|
||||
<b>{{ countWorkflows }}</b>
|
||||
<template v-if="countWorkflows > 1">{{ $t('workflows') }}</template>
|
||||
<template v-else>{{ $t('workflow') }}</template>
|
||||
</button>
|
||||
|
||||
<pick-workflow v-else-if="allowCreate"
|
||||
:relatedEntityClass="this.relatedEntityClass"
|
||||
:relatedEntityId="this.relatedEntityId"
|
||||
:workflowsAvailables="workflowsAvailables"
|
||||
></pick-workflow>
|
||||
|
||||
<teleport to="body">
|
||||
<modal v-if="modal.showModal"
|
||||
:modalDialogClass="modal.modalDialogClass"
|
||||
@close="modal.showModal = false">
|
||||
|
||||
<template v-slot:header>
|
||||
<h2 class="modal-title">{{ $t('workflow_list') }}</h2>
|
||||
</template>
|
||||
|
||||
<template v-slot:body>
|
||||
<list-workflow-vue
|
||||
:workflows="workflows"
|
||||
></list-workflow-vue>
|
||||
</template>
|
||||
|
||||
<template v-slot:footer>
|
||||
<pick-workflow v-if="allowCreate"
|
||||
:relatedEntityClass="this.relatedEntityClass"
|
||||
:relatedEntityId="this.relatedEntityId"
|
||||
:workflowsAvailables="workflowsAvailables"
|
||||
></pick-workflow>
|
||||
</template>
|
||||
|
||||
</modal>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
|
||||
import PickWorkflow from 'ChillMainAssets/vuejs/_components/EntityWorkflow/PickWorkflow.vue';
|
||||
import ListWorkflowVue from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflow.vue';
|
||||
|
||||
export default {
|
||||
name: "ListWorkflowModal",
|
||||
components: {
|
||||
Modal,
|
||||
PickWorkflow,
|
||||
ListWorkflowVue
|
||||
},
|
||||
props: {
|
||||
workflows: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
allowCreate: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
relatedEntityClass: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
relatedEntityId: {
|
||||
type: Number,
|
||||
required: false,
|
||||
},
|
||||
workflowsAvailables: {
|
||||
type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
modal: {
|
||||
showModal: false,
|
||||
modalDialogClass: "modal-dialog-scrollable modal-xl"
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
countWorkflows() {
|
||||
return this.workflows.length;
|
||||
},
|
||||
hasWorkflow() {
|
||||
return this.countWorkflows > 0;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openModal() {
|
||||
this.modal.showModal = true;
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
messages: {
|
||||
fr: {
|
||||
workflow_list: "Liste des workflows associés",
|
||||
workflow: " workflow associé",
|
||||
workflows: " workflows associés",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
@@ -61,15 +61,14 @@ const messages = {
|
||||
woman: "Née le"
|
||||
},
|
||||
deathdate: "Date de décès",
|
||||
years_old: "ans",
|
||||
household_without_address: "Le ménage de l'usager est sans adresse",
|
||||
no_data: "Aucune information renseignée",
|
||||
type: {
|
||||
thirdparty: "Tiers",
|
||||
person: "Usager"
|
||||
},
|
||||
holder: "Titulaire",
|
||||
years_old: "an | {n} an | {n} ans",
|
||||
|
||||
holder: "Titulaire"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -59,7 +59,7 @@
|
||||
must be shown in such list
|
||||
#}
|
||||
{%- if render == 'list' -%}
|
||||
<li class="chill-entity entity-address {% if address.confidential %}confidential{% endif %}">
|
||||
<li class="chill-entity entity-address">
|
||||
{% if options['with_picto'] %}
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
{% endif %}
|
||||
@@ -68,7 +68,7 @@
|
||||
{%- endif -%}
|
||||
|
||||
{%- if render == 'inline' -%}
|
||||
<span class="chill-entity entity-address {% if address.confidential %}confidential{% endif %}">
|
||||
<span class="chill-entity entity-address">
|
||||
{% if options['with_picto'] %}
|
||||
<i class="fa fa-fw fa-map-marker"></i>
|
||||
{% endif %}
|
||||
@@ -77,7 +77,7 @@
|
||||
{%- endif -%}
|
||||
|
||||
{%- if render == 'bloc' -%}
|
||||
<div class="chill-entity entity-address {% if address.confidential %}confidential{% endif %}">
|
||||
<div class="chill-entity entity-address">
|
||||
{% if options['has_no_address'] == true and address.isNoAddress == true %}
|
||||
{% if address.postCode is not empty %}
|
||||
<div class="address{% if options['multiline'] %} multiline{% endif %}{% if options['with_delimiter'] %} delimiter{% endif %}">
|
||||
|
@@ -1,3 +0,0 @@
|
||||
<div class="sticky-buttons">
|
||||
{# Override this file to add fast actions buttons #}
|
||||
</div>
|
@@ -1,15 +0,0 @@
|
||||
<div class="col-10 mt-5">
|
||||
|
||||
{# vue component #}
|
||||
<div id="homepage_widget"></div>
|
||||
|
||||
{% include '@ChillMain/Homepage/fast_actions.html.twig' %}
|
||||
</div>
|
||||
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('page_homepage_widget') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags('page_homepage_widget') }}
|
||||
{% endblock %}
|
@@ -1,77 +0,0 @@
|
||||
{% import '@ChillPerson/AccompanyingCourse/Comment/macro_showItem.html.twig' as m %}
|
||||
|
||||
{% macro recordAction(comment) %}
|
||||
{% if is_granted('CHILL_MAIN_NOTIFICATION_COMMENT_EDIT', comment) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_forward_return_path('chill_main_notification_show', {
|
||||
'_fragment': 'comment-' ~ comment.id,
|
||||
'edit': comment.id,
|
||||
'id': comment.notification.id
|
||||
}) }}" class="btn btn-edit" title="{{ 'Edit'|trans }}"
|
||||
></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
<div class="notification-comment-list my-5">
|
||||
<h2 class="chill-blue">{{ 'notification.comments_list'|trans }}</h2>
|
||||
|
||||
{% if notification.comments|length > 0 %}
|
||||
<div class="flex-table">
|
||||
{% for comment in notification.comments %}
|
||||
|
||||
{% if editedCommentForm is null or editedCommentId != comment.id %}
|
||||
{{ m.show_comment(comment, {
|
||||
'recordAction': _self.recordAction(comment)
|
||||
}) }}
|
||||
{% else %}
|
||||
<div class="item-bloc">
|
||||
<div class="item-row row">
|
||||
<a id="comment-{{ comment.id }}"></a>
|
||||
|
||||
{{ form_start(editedCommentForm) }}
|
||||
{{ form_errors(editedCommentForm) }}
|
||||
{{ form_widget(editedCommentForm.content) }}
|
||||
<input type="hidden" name="form" value="edit" />
|
||||
<ul class="record_actions">
|
||||
<li class="cancel">
|
||||
<a href="{{ chill_path_forward_return_path('chill_main_notification_show', {
|
||||
'_fragment': 'comment-' ~ comment.id,
|
||||
'id': notification.id }) }}" class="btn btn-cancel">
|
||||
{{ 'cancel'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<button class="btn btn-save" type="submit">{{ 'Save'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(editedCommentForm) }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<span class="chill-no-data-statement">{{ 'No comments'|trans }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if appendCommentForm is not null %}
|
||||
<div class="new-comment my-5">
|
||||
<h2 class="chill-blue mb-4">{{ 'Write a new comment'|trans }}</h2>
|
||||
|
||||
{{ form_start(appendCommentForm) }}
|
||||
{{ form_errors(appendCommentForm) }}
|
||||
{{ form_widget(appendCommentForm.content) }}
|
||||
<input type="hidden" name="form" value="append" />
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button class="btn btn-create" type="submit">{{ 'notification.append_comment'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(appendCommentForm) }}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
@@ -52,11 +52,9 @@
|
||||
|
||||
{% macro content(c) %}
|
||||
<div class="item-row separator">
|
||||
{% if c.data is defined %}
|
||||
<div class="mx-3 flex-grow-1">
|
||||
{% include c.data.template with c.data.template_data %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="mx-3 flex-grow-1">
|
||||
{% include c.data.template with c.data.template_data %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-row">
|
||||
<div class="notification-content">
|
||||
@@ -70,44 +68,34 @@
|
||||
</div>
|
||||
{% if c.action_button is not defined or c.action_button != false %}
|
||||
<div class="item-row separator">
|
||||
<div class="item-col item-meta">
|
||||
|
||||
{# TODO twig extension to count comments #}
|
||||
<div class="comment-counter visually-hidden">
|
||||
<span>x commentaires</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="item-col">
|
||||
<ul class="record_actions">
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
{# Vue component #}
|
||||
<span class="notification_toggle_read_status"
|
||||
data-notification-id="{{ c.notification.id }}"
|
||||
data-notification-current-is-read="{{ c.notification.isReadBy(app.user) }}"
|
||||
data-container="notification-status"
|
||||
></span>
|
||||
</li>
|
||||
{% if is_granted('CHILL_MAIN_NOTIFICATION_UPDATE', c.notification) %}
|
||||
<li>
|
||||
{# Vue component #}
|
||||
<span class="notification_toggle_read_status"
|
||||
data-notification-id="{{ c.notification.id }}"
|
||||
data-notification-current-is-read="{{ c.notification.isReadBy(app.user) }}"
|
||||
data-container="notification-status"
|
||||
></span>
|
||||
<a href="{{ chill_path_add_return_path('chill_main_notification_edit', {'id': c.notification.id}) }}"
|
||||
class="btn btn-edit" title="{{ 'Edit'|trans }}"></a>
|
||||
</li>
|
||||
{% if is_granted('CHILL_MAIN_NOTIFICATION_UPDATE', c.notification) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_main_notification_edit', {'id': c.notification.id}) }}"
|
||||
class="btn btn-edit" title="{{ 'Edit'|trans }}"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_MAIN_NOTIFICATION_SEE', c.notification) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_main_notification_show', {'id': c.notification.id}) }}"
|
||||
class="btn {% if not c.notification.isSystem %}btn-show change-icon{% else %}btn-misc{% endif %}" title="{{ 'notification.see_comments_thread'|trans }}">
|
||||
{% if not c.notification.isSystem() %}
|
||||
<i class="fa fa-comment"></i>
|
||||
{% else %}
|
||||
{{ 'Read more'|trans }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_MAIN_NOTIFICATION_SEE', c.notification) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_main_notification_show', {'id': c.notification.id}) }}"
|
||||
class="btn {% if not c.notification.isSystem %}btn-show change-icon{% else %}btn-misc{% endif %}" title="{{ 'notification.see_comments_thread'|trans }}">
|
||||
{% if not c.notification.isSystem() %}
|
||||
<i class="fa fa-comment"></i>
|
||||
{% else %}
|
||||
{{ 'Read more'|trans }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
@@ -119,19 +107,15 @@
|
||||
<button type="button" class="accordion-button collapsed"
|
||||
data-bs-toggle="collapse" data-bs-target="#flush-collapse-{{ notification.id }}"
|
||||
aria-expanded="false" aria-controls="flush-collapse-{{ notification.id }}">
|
||||
|
||||
{{ _self.title(_context) }}
|
||||
</button>
|
||||
{{ _self.header(_context) }}
|
||||
|
||||
</div>
|
||||
<div id="flush-collapse-{{ notification.id }}"
|
||||
class="accordion-collapse collapse"
|
||||
aria-labelledby="flush-heading-{{ notification.id }}"
|
||||
data-bs-parent="#notification-fold">
|
||||
|
||||
{{ _self.content(_context) }}
|
||||
|
||||
</div>
|
||||
{% else %}
|
||||
{{ _self.title(_context) }}
|
||||
|
@@ -20,8 +20,6 @@
|
||||
|
||||
{{ form_row(form.title, { 'label': 'notification.subject'|trans }) }}
|
||||
{{ form_row(form.addressees, { 'label': 'notification.sent_to'|trans }) }}
|
||||
|
||||
{% include handler.template(notification) with handler.templateData(notification) %}
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label class="col-form-label col-sm-4" for="notification_message">{{ form_label(form.message) }}</label>
|
||||
@@ -30,6 +28,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include handler.template(notification) with handler.templateData(notification) %}
|
||||
|
||||
{{ form_end(form) }}
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
|
@@ -1,12 +1,46 @@
|
||||
<h1 class="mt-5"><a id="notification-list"></a>{{ 'notification.Notifications'|trans }}</h1>
|
||||
|
||||
<div class="flex-table accordion accordion-flush" id="notification-fold">
|
||||
<div class="list-group my-2 notification notification-box">
|
||||
<div class="list-group-item">
|
||||
<h4>{{ 'notification.Sent'|trans }}</h4>
|
||||
</div>
|
||||
{# TODO pagination or limit #}
|
||||
{% for notification in notifications %}
|
||||
{% include 'ChillMainBundle:Notification:_list_item.html.twig' with {
|
||||
'full_content': true,
|
||||
'fold_item': true,
|
||||
'action_button': true,
|
||||
} %}{#
|
||||
#}
|
||||
<div class="list-group-item notification-status {% if notification.isReadBy(app.user) %}read{% else %}unread{% endif %}">
|
||||
|
||||
{% if not notification.isSystem %}
|
||||
{% if notification.sender == app.user %}
|
||||
|
||||
<h6 class="notification-title">
|
||||
<abbr title="{{ 'Le ' ~ notification.date|format_date('long') ~ '\n' ~ notification.title }}">
|
||||
{{ notification.date|format_datetime('short','short') }}
|
||||
</abbr>
|
||||
{# Vue component #}
|
||||
<span class="notification_toggle_read_status"
|
||||
data-notification-id="{{ notification.id }}"
|
||||
data-notification-current-is-read="{{ notification.isReadBy(app.user) }}"
|
||||
data-container="notification-status"
|
||||
data-show-button-url="{{ chill_path_add_return_path('chill_main_notification_show', {'id': notification.id}, false) }}"
|
||||
data-button-class="btn-outline-primary"
|
||||
data-button-text="false"
|
||||
></span>
|
||||
</h6>
|
||||
|
||||
{% if notification.addressees|length > 0 %}
|
||||
<abbr title="{{ 'notification.sent_to'|trans }}">{{ 'notification.to'|trans }}:</abbr>
|
||||
{% endif %}
|
||||
|
||||
{% for a in notification.addressees %}
|
||||
<span class="badge-user">
|
||||
{{ a|chill_entity_render_string }}
|
||||
</span>
|
||||
{% endfor %}
|
||||
|
||||
{% else %}
|
||||
<div>{{ 'notification.you were notified by %sender%'|trans({'%sender%': notification.sender|chill_entity_render_string }) }}</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div>{{ 'notification.you were notified by system'|trans }}</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
@@ -14,6 +14,21 @@
|
||||
{{ encore_entry_link_tags('mod_notification_toggle_read_status') }}
|
||||
{% endblock %}
|
||||
|
||||
{% import '@ChillPerson/AccompanyingCourse/Comment/macro_showItem.html.twig' as m %}
|
||||
|
||||
{% macro recordAction(comment) %}
|
||||
{% if is_granted('CHILL_MAIN_NOTIFICATION_COMMENT_EDIT', comment) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_forward_return_path('chill_main_notification_show', {
|
||||
'_fragment': 'comment-' ~ comment.id,
|
||||
'edit': comment.id,
|
||||
'id': comment.notification.id
|
||||
}) }}" class="btn btn-edit" title="{{ 'Edit'|trans }}"
|
||||
></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-10 notification notification-show">
|
||||
|
||||
@@ -26,12 +41,70 @@
|
||||
'template_data': handler.getTemplateData(notification)
|
||||
},
|
||||
'action_button': false,
|
||||
'full_content': true,
|
||||
'fold_item': false
|
||||
'full_content': true
|
||||
} %}
|
||||
</div>
|
||||
|
||||
{% include 'ChillMainBundle:Notification:_item_comments.html.twig' %}
|
||||
<div class="notification-comment-list my-5">
|
||||
<h2 class="chill-blue">{{ 'notification.comments_list'|trans }}</h2>
|
||||
|
||||
{% if notification.comments|length > 0 %}
|
||||
<div class="flex-table">
|
||||
{% for comment in notification.comments %}
|
||||
|
||||
{% if editedCommentForm is null or editedCommentId != comment.id %}
|
||||
{{ m.show_comment(comment, {
|
||||
'recordAction': _self.recordAction(comment)
|
||||
}) }}
|
||||
{% else %}
|
||||
<div class="item-bloc">
|
||||
<div class="item-row row">
|
||||
<a id="comment-{{ comment.id }}"></a>
|
||||
|
||||
{{ form_start(editedCommentForm) }}
|
||||
{{ form_errors(editedCommentForm) }}
|
||||
{{ form_widget(editedCommentForm.content) }}
|
||||
<input type="hidden" name="form" value="edit" />
|
||||
<ul class="record_actions">
|
||||
<li class="cancel">
|
||||
<a href="{{ chill_path_forward_return_path('chill_main_notification_show', {
|
||||
'_fragment': 'comment-' ~ comment.id,
|
||||
'id': notification.id }) }}" class="btn btn-cancel">
|
||||
{{ 'cancel'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<button class="btn btn-save" type="submit">{{ 'Save'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(editedCommentForm) }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if appendCommentForm is not null %}
|
||||
<div class="new-comment my-5">
|
||||
<h2 class="chill-blue mb-4">{{ 'Write a new comment'|trans }}</h2>
|
||||
|
||||
{{ form_start(appendCommentForm) }}
|
||||
{{ form_errors(appendCommentForm) }}
|
||||
{{ form_widget(appendCommentForm.content) }}
|
||||
<input type="hidden" name="form" value="append" />
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button class="btn btn-create" type="submit">{{ 'notification.append_comment'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(appendCommentForm) }}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li class="cancel">
|
||||
|
@@ -42,3 +42,6 @@
|
||||
{% endif %}
|
||||
|
||||
></span>
|
||||
|
||||
{{ encore_entry_script_tags('vue_onthefly') }}
|
||||
{{ encore_entry_link_tags('vue_onthefly') }}
|
||||
|
@@ -5,10 +5,14 @@
|
||||
|
||||
{{ form_row(transition_form.transition) }}
|
||||
|
||||
<div id="finalizeAfter">
|
||||
{{ form_row(transition_form.finalizeAfter) }}
|
||||
</div>
|
||||
|
||||
{% if transition_form.freezeAfter is defined %}
|
||||
{{ form_row(transition_form.freezeAfter) }}
|
||||
{% endif %}
|
||||
|
||||
|
||||
<div id="futureDestUsers">
|
||||
{{ form_row(transition_form.future_dest_users) }}
|
||||
</div>
|
||||
@@ -27,7 +31,7 @@
|
||||
{% else %}
|
||||
<div class="alert alert-chill-yellow">
|
||||
|
||||
{% if entity_workflow.currentStep.isFinal %}
|
||||
{% if entity_workflow.currentStep.isFinalizeAfter %}
|
||||
<p>{{ 'workflow.This workflow is finalized'|trans }}</p>
|
||||
{% else %}
|
||||
<p>{{ 'workflow.You are not allowed to apply a transition on this workflow'|trans }}</p>
|
||||
|
@@ -1,13 +1,13 @@
|
||||
{% set acl = "0" %}
|
||||
{% if is_granted('CHILL_MAIN_WORKFLOW_CREATE', blank_workflow) %}
|
||||
{% set acl = "1" %}
|
||||
{# vue component #}
|
||||
<div data-pick-workflow="1"
|
||||
data-related-entity-class="{{ blank_workflow.relatedEntityClass }}"
|
||||
data-related-entity-id="{{ blank_workflow.relatedEntityId }}"
|
||||
data-workflows-availables="{{ workflows_availables|json_encode()|e('html_attr') }}"
|
||||
></div>
|
||||
{% endif %}
|
||||
|
||||
{# vue component #}
|
||||
<div data-list-workflows="1"
|
||||
data-workflows="{{ entity_workflows_json|json_encode|e('html_attr') }}"
|
||||
data-allow-create="{{ acl }}"
|
||||
data-related-entity-class="{{ blank_workflow.relatedEntityClass }}"
|
||||
data-related-entity-id="{{ blank_workflow.relatedEntityId }}"
|
||||
data-workflows-availables="{{ workflows_availables|json_encode()|e('html_attr') }}"
|
||||
></div>
|
||||
{% if entity_workflows|length > 0 %}
|
||||
{# vue component #}
|
||||
<div data-list-workflows="1" data-workflows="{{ entity_workflows_json|json_encode|e('html_attr') }}"></div>
|
||||
{% endif %}
|
||||
|
@@ -2,42 +2,30 @@
|
||||
|
||||
<div class="flex-table">
|
||||
{% for step in entity_workflow.stepsChained %}
|
||||
{% set place_labels = workflow_metadata(entity_workflow, 'label', step.currentStep) %}
|
||||
{% set place_label = place_labels is null ? step.currentStep : place_labels|localize_translatable_string %}
|
||||
|
||||
<div class="item-bloc {{ 'bloc' ~ step.id }} {% if loop.first %}initial{% endif %}">
|
||||
<div class="item-row">
|
||||
|
||||
{% if loop.first and step.next is null %}
|
||||
<div class="item-col">
|
||||
{{ 'workflow.No transitions'|trans }}
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
<div class="item-col">
|
||||
{% if step.previous is not null and step.previous.freezeAfter == true %}
|
||||
<i class="fa fa-snowflake-o fa-sm me-1" title="{{ 'workflow.Freezed'|trans }}"></i>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="item-col flex-column align-items-end">
|
||||
<div class="decided">
|
||||
{{ place_label }}
|
||||
</div>
|
||||
{#
|
||||
<div class="decided">
|
||||
<i class="fa fa-times fa-fw text-danger"></i>
|
||||
Refusé
|
||||
</div>
|
||||
#}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="item-col flex-column align-items-end">
|
||||
<div class="decided">
|
||||
{% if not loop.first %}
|
||||
<i class="fa fa-check fa-fw text-success"></i>
|
||||
{% endif %}
|
||||
{{ step.currentStep }}
|
||||
</div>
|
||||
{#
|
||||
<div class="decided">
|
||||
<i class="fa fa-times fa-fw text-danger"></i>
|
||||
Refusé
|
||||
</div>
|
||||
#}
|
||||
</div>
|
||||
</div>
|
||||
{% if step.next is not null %}
|
||||
{% set transition = chill_workflow_transition_by_string(step.entityWorkflow, step.transitionAfter) %}
|
||||
{% set transition_labels = workflow_metadata(step.entityWorkflow, 'label', transition) %}
|
||||
{% set transition_label = transition_labels is null ? step.transitionAfter : transition_labels|localize_translatable_string %}
|
||||
{% set forward = workflow_metadata(step.entityWorkflow, 'isForward', transition) %}
|
||||
<div class="item-row separator">
|
||||
<div class="item-col" style="width: inherit;">
|
||||
{% if step.transitionBy is not null %}
|
||||
@@ -52,12 +40,7 @@
|
||||
<div class="item-col flex-column align-items-end">
|
||||
<div class="to-decision">
|
||||
<i class="fa fa-share fa-fw text-secondary" title="transféré"></i>
|
||||
{% if forward %}
|
||||
<i class="fa fa-check fa-fw text-success"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-times fa-fw text-danger"></i>
|
||||
{% endif %}
|
||||
{{ transition_label }}
|
||||
{{ step.next.currentStep }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,62 +1,41 @@
|
||||
{% macro popoverContent(step) %}
|
||||
<ul class="small_in_title">
|
||||
{% if step.previous is not null %}
|
||||
<li>
|
||||
<span class="item-key">{{ 'By'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.previous.transitionBy|chill_entity_render_box }}</b>
|
||||
</li>
|
||||
<li>
|
||||
<span class="item-key">{{ 'Le'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.previous.transitionAt|format_datetime('short', 'short') }}</b>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<span class="item-key">{{ 'workflow.Created by'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.entityWorkflow.createdBy|chill_entity_render_box }}</b>
|
||||
</li>
|
||||
<li>
|
||||
<span class="item-key">{{ 'Le'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.entityWorkflow.createdAt|format_datetime('short', 'short') }}</b>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<span class="item-key">{{ 'By'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.transitionBy|chill_entity_render_box }}</b>
|
||||
</li>
|
||||
<li>
|
||||
<span class="item-key">{{ 'Le'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.transitionAt|format_datetime('short', 'short') }}</b>
|
||||
</li>
|
||||
</ul>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro popoverTitle(step) %}
|
||||
{% if step.previous is not null and step.previous.freezeAfter == true %}
|
||||
<i class="fa fa-snowflake-o fa-sm me-1" title="{{ 'workflow.Freezed'|trans }}"></i>
|
||||
{% endif %}
|
||||
{% if step.previous is not null %}
|
||||
{% set transition = chill_workflow_transition_by_string(step.entityWorkflow, step.previous.transitionAfter) %}
|
||||
{% set labels = workflow_metadata(step.entityWorkflow, 'label', transition) %}
|
||||
{% set label = labels is null ? step.previous.transitionAfter : labels|localize_translatable_string %}
|
||||
{{ label }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro breadcrumb(_ctx) %}
|
||||
<div class="breadcrumb">
|
||||
{% for step in _ctx.entity_workflow.stepsChained %}
|
||||
{% set labels = workflow_metadata(_ctx.entity_workflow, 'label', step.currentStep) %}
|
||||
{% set label = labels is null ? step.currentStep : labels|localize_translatable_string %}
|
||||
{% set popTitle = _self.popoverTitle(step) %}
|
||||
{% set popContent = _self.popoverContent(step) %}
|
||||
{% if step.previous is null %}
|
||||
{#
|
||||
{% set popContent = "Point de départ du workflow" %}
|
||||
{{ dump(step) }}
|
||||
#}
|
||||
{% set popContent = _self.popoverContent(step) %}
|
||||
{% else %}
|
||||
{% set popContent = _self.popoverContent(step.previous) %}
|
||||
{% endif %}
|
||||
<span class="mx-2"
|
||||
tabindex="0"
|
||||
data-bs-trigger="focus hover"
|
||||
data-bs-toggle="popover"
|
||||
data-bs-placement="bottom"
|
||||
data-bs-custom-class="workflow-transition"
|
||||
title="{{ popTitle|e('html_attr') }}"
|
||||
title="{{ step.currentStep }}"
|
||||
data-bs-content="{{ popContent|e('html_attr') }}"
|
||||
>
|
||||
{% if step.currentStep == 'initial' %}
|
||||
<i class="fa fa-circle me-1 text-chill-yellow"></i>
|
||||
{% endif %}
|
||||
{% if step.previous is not null and step.previous.freezeAfter == true %}
|
||||
<i class="fa fa-snowflake-o fa-sm me-1" title="{{ 'workflow.Freezed'|trans }}"></i>
|
||||
{% endif %}
|
||||
{{ label }}
|
||||
{{ step.currentStep }}
|
||||
</span>
|
||||
{% if not loop.last %}
|
||||
→
|
||||
|
@@ -13,7 +13,6 @@
|
||||
{{ encore_entry_link_tags('mod_ckeditor5') }}
|
||||
{{ encore_entry_link_tags('chill') }}
|
||||
{{ encore_entry_link_tags('mod_blur') }}
|
||||
{{ encore_entry_link_tags('vue_onthefly') }}
|
||||
{% block css %}<!-- nothing added to css -->{% endblock %}
|
||||
</head>
|
||||
|
||||
@@ -60,26 +59,26 @@
|
||||
{% endif %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-8 main_search">
|
||||
<h2>{{ 'Search'|trans }}</h2>
|
||||
|
||||
<form action="{{ path('chill_main_search') }}" method="get">
|
||||
<input class="form-control form-control-lg" name="q" type="search" placeholder="{{ 'Search persons, ...'|trans }}" />
|
||||
<center>
|
||||
<button type="submit" class="btn btn-lg btn-warning mt-3">
|
||||
<i class="fa fa-fw fa-search"></i> {{ 'Search'|trans }}
|
||||
</button>
|
||||
<a class="btn btn-lg btn-misc mt-3" href="{{ path('chill_main_advanced_search_list') }}">
|
||||
<i class="fa fa-fw fa-search"></i> {{ 'Advanced search'|trans }}
|
||||
</a>
|
||||
</center>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{# DISABLED {{ chill_widget('homepage', {} ) }} #}
|
||||
|
||||
{% include '@ChillMain/Homepage/index.html.twig' %}
|
||||
|
||||
<div class="col-8 main_search">
|
||||
<h2>{{ 'Search'|trans }}</h2>
|
||||
|
||||
<form action="{{ path('chill_main_search') }}" method="get">
|
||||
<input class="form-control form-control-lg" name="q" type="search" placeholder="{{ 'Search persons, ...'|trans }}" />
|
||||
<center>
|
||||
<button type="submit" class="btn btn-lg btn-warning mt-3">
|
||||
<i class="fa fa-fw fa-search"></i> {{ 'Search'|trans }}
|
||||
</button>
|
||||
<a class="btn btn-lg btn-misc mt-3" href="{{ path('chill_main_advanced_search_list') }}">
|
||||
<i class="fa fa-fw fa-search"></i> {{ 'Advanced search'|trans }}
|
||||
</a>
|
||||
</center>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<a href="{{ path('chill_crud_aside_activity_new', {'type' : 7, 'duration' : '600', 'note' : 'Pas des remarques' }) }}"><div class="bloc btn btn-success btn-md btn-block">Appel téléphonique</div></a>
|
||||
</div>
|
||||
|
||||
{{ chill_widget('homepage', {} ) }}
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
@@ -95,7 +94,6 @@
|
||||
{{ encore_entry_script_tags('mod_ckeditor5') }}
|
||||
{{ encore_entry_script_tags('mod_blur') }}
|
||||
{{ encore_entry_script_tags('chill') }}
|
||||
{{ encore_entry_script_tags('vue_onthefly') }}
|
||||
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('DOMContentLoaded', function(e) {
|
||||
|
@@ -45,15 +45,13 @@ class SearchUserApiProvider implements SearchApiInterface
|
||||
$query
|
||||
->setSelectKey('user')
|
||||
->setSelectJsonbMetadata("jsonb_build_object('id', u.id)")
|
||||
->setSelectPertinence('GREATEST(SIMILARITY(LOWER(UNACCENT(?)), u.label),
|
||||
SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical))', [$pattern, $pattern])
|
||||
->setSelectPertinence('GREATEST(SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical),
|
||||
SIMILARITY(LOWER(UNACCENT(?)), u.emailcanonical))', [$pattern, $pattern])
|
||||
->setFromClause('users AS u')
|
||||
->setWhereClauses('
|
||||
SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical) > 0.15
|
||||
OR u.usernamecanonical LIKE \'%\' || LOWER(UNACCENT(?)) || \'%\'
|
||||
OR SIMILARITY(LOWER(UNACCENT(?)), LOWER(UNACCENT(u.label))) > 0.15
|
||||
OR u.label LIKE \'%\' || LOWER(UNACCENT(?)) || \'%\'
|
||||
', [$pattern, $pattern, $pattern, $pattern]);
|
||||
->setWhereClauses('SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical) > 0.15
|
||||
OR
|
||||
SIMILARITY(LOWER(UNACCENT(?)), u.emailcanonical) > 0.15
|
||||
', [$pattern, $pattern]);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
@@ -22,10 +22,6 @@ class SearchApiQuery
|
||||
|
||||
private array $fromClauseParams = [];
|
||||
|
||||
private bool $isDistinct = false;
|
||||
|
||||
private ?string $isDistinctKey = null;
|
||||
|
||||
private ?string $jsonbMetadata = null;
|
||||
|
||||
private array $jsonbMetadataParams = [];
|
||||
@@ -109,11 +105,6 @@ class SearchApiQuery
|
||||
]);
|
||||
}
|
||||
|
||||
public function getDistinct(): bool
|
||||
{
|
||||
return $this->isDistinct;
|
||||
}
|
||||
|
||||
public function getFromClause(): string
|
||||
{
|
||||
return $this->fromClause;
|
||||
@@ -148,14 +139,6 @@ class SearchApiQuery
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDistinct(bool $distinct, string $distinctKey): self
|
||||
{
|
||||
$this->isDistinct = $distinct;
|
||||
$this->isDistinctKey = $distinctKey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFromClause(string $fromClause, array $params = []): self
|
||||
{
|
||||
$this->fromClause = $fromClause;
|
||||
@@ -202,11 +185,7 @@ class SearchApiQuery
|
||||
private function buildSelectClause(bool $countOnly = false): string
|
||||
{
|
||||
if ($countOnly) {
|
||||
if (!$this->isDistinct) {
|
||||
return 'count(*) AS c';
|
||||
}
|
||||
|
||||
return 'count(distinct ' . $this->isDistinctKey . ') AS c';
|
||||
return 'count(*) AS c';
|
||||
}
|
||||
|
||||
$selects = $this->getSelectClauses();
|
||||
@@ -223,7 +202,7 @@ class SearchApiQuery
|
||||
$selects[] = strtr('{pertinence} AS pertinence', ['{pertinence}' => $this->pertinence]);
|
||||
}
|
||||
|
||||
return ($this->isDistinct ? 'DISTINCT ' : '') . implode(', ', $selects);
|
||||
return implode(', ', $selects);
|
||||
}
|
||||
|
||||
private function buildSelectParams(bool $count = false): array
|
||||
|
@@ -1,41 +0,0 @@
|
||||
<?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\Serializer\Model;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
class Counter implements JsonSerializable
|
||||
{
|
||||
private int $counter;
|
||||
|
||||
public function __construct(?int $counter)
|
||||
{
|
||||
$this->counter = $counter;
|
||||
}
|
||||
|
||||
public function getCounter(): ?int
|
||||
{
|
||||
return $this->counter;
|
||||
}
|
||||
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return ['count' => $this->counter];
|
||||
}
|
||||
|
||||
public function setCounter(?int $counter): Counter
|
||||
{
|
||||
$this->counter = $counter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -45,7 +45,6 @@ class AddressNormalizer implements ContextAwareNormalizerInterface, NormalizerAw
|
||||
'extra',
|
||||
'validFrom' => DateTimeInterface::class,
|
||||
'validTo' => DateTimeInterface::class,
|
||||
'confidential',
|
||||
];
|
||||
|
||||
private AddressRender $addressRender;
|
||||
@@ -84,7 +83,6 @@ class AddressNormalizer implements ContextAwareNormalizerInterface, NormalizerAw
|
||||
'buildingName' => $address->getBuildingName(),
|
||||
'distribution' => $address->getDistribution(),
|
||||
'extra' => $address->getExtra(),
|
||||
'confidential' => $address->getConfidential(),
|
||||
'lines' => $this->addressRender->renderLines($address),
|
||||
];
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user