mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch '327_pinned_comment' into issue321_layout_improvements_actionForm
This commit is contained in:
commit
d588c36308
17
CHANGELOG.md
17
CHANGELOG.md
@ -11,6 +11,17 @@ and this project adheres to
|
||||
## Unreleased
|
||||
|
||||
<!-- write down unreleased development here -->
|
||||
* [asideactivity] creation of aside activity category fixed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/262)
|
||||
* [vendee/person] fix typo "situation professionelle" => "situation professionnelle"
|
||||
* [main] add availableForUsers condition from locationType in the location API endpoint (champs-libres/departement-de-la-vendee/accent-suivi-developpement#248)
|
||||
* [main] add the current location of the user as API point + add it in the activity location list (champs-libres/departement-de-la-vendee/accent-suivi-developpement#247)
|
||||
* [activity] improve show/new/edit templates, fix SEE and SEE_DETAILS acl
|
||||
* [badges] create specific badge for TMS, and make person/thirdparty badges clickable with on-the-fly modal in :
|
||||
* concerned groups items (activity, calendar)
|
||||
* accompanyingCourseWork lists
|
||||
* accompanyingCourse lists
|
||||
* [acompanyingCourse] add initial comment on Resume page
|
||||
* [person] create button full width (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/330)
|
||||
|
||||
## Test releases
|
||||
|
||||
@ -35,6 +46,8 @@ and this project adheres to
|
||||
* [asideactivity] creation of aside activity category fixed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/262)
|
||||
* [vendee/person] fix typo "situation professionelle" => "situation professionnelle"
|
||||
* [accompanyingcourse_work] Changes in layout/behavior of edit form (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/321)
|
||||
* [badge-entity] design coherency between pills badge-person and 3 kinds of badge-thirdparty
|
||||
* [AddPersons] suggestions row are clickable, not only checkbox
|
||||
|
||||
### test release 2021-12-06
|
||||
|
||||
@ -51,10 +64,6 @@ and this project adheres to
|
||||
* [visgraph] improve and fix bugs on vis-network relationship graph
|
||||
* [bugfix] posting of birth- and deathdate through api fixed.
|
||||
* [suggestions] improve suggestions lists
|
||||
* [badge-entity] design coherency between badge-person and 3 kinds of badge-thirdparty
|
||||
* [AddPersons] suggestions row are clickable, not only checkbox
|
||||
* [activity] improve show/new/edit templates, fix SEE and SEE_DETAILS acl
|
||||
* [activity][calendar] concerned groups items are clickable with on-the-fly modal, create specific badge for TMS column
|
||||
|
||||
### Test release 2021-11-19 - bis
|
||||
|
||||
|
@ -17,6 +17,14 @@ const getLocations = () => fetchResults('/api/1.0/main/location.json');
|
||||
|
||||
const getLocationTypes = () => fetchResults('/api/1.0/main/location-type.json');
|
||||
|
||||
const getUserCurrentLocation =
|
||||
() => fetch('/api/1.0/main/user-current-location.json')
|
||||
.then(response => {
|
||||
if (response.ok) { return response.json(); }
|
||||
throw Error('Error with request resource response');
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* Load Location Type by defaultFor
|
||||
* @param {string} entity - can be "person" or "thirdparty"
|
||||
@ -48,5 +56,6 @@ export {
|
||||
getLocations,
|
||||
getLocationTypes,
|
||||
getLocationTypeByDefaultFor,
|
||||
postLocation
|
||||
postLocation,
|
||||
getUserCurrentLocation
|
||||
};
|
||||
|
@ -15,7 +15,7 @@
|
||||
:searchable="true"
|
||||
:placeholder="$t('activity.choose_location')"
|
||||
:custom-label="customLabel"
|
||||
:options="locations"
|
||||
:options="availableLocations"
|
||||
group-values="locations"
|
||||
group-label="locationGroup"
|
||||
v-model="location"
|
||||
@ -32,7 +32,7 @@
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import VueMultiselect from "vue-multiselect";
|
||||
import NewLocation from "./Location/NewLocation.vue";
|
||||
import { getLocations, getLocationTypeByDefaultFor } from "../api.js";
|
||||
import { getLocations, getLocationTypeByDefaultFor, getUserCurrentLocation } from "../api.js";
|
||||
|
||||
export default {
|
||||
name: "Location",
|
||||
@ -40,13 +40,8 @@ export default {
|
||||
NewLocation,
|
||||
VueMultiselect,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
locations: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["activity"]),
|
||||
...mapState(["activity", "availableLocations"]),
|
||||
...mapGetters(["suggestedEntities"]),
|
||||
location: {
|
||||
get() {
|
||||
@ -57,53 +52,6 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
getLocations().then(
|
||||
(results) => {
|
||||
getLocationTypeByDefaultFor('person').then(
|
||||
(personLocationType) => {
|
||||
if (personLocationType) {
|
||||
const personLocation = this.makeAccompanyingPeriodLocation(personLocationType);
|
||||
const concernedPersonsLocation =
|
||||
this.makeConcernedPersonsLocation(personLocationType);
|
||||
getLocationTypeByDefaultFor('thirdparty').then(
|
||||
thirdpartyLocationType => {
|
||||
const concernedThirdPartiesLocation =
|
||||
this.makeConcernedThirdPartiesLocation(thirdpartyLocationType);
|
||||
this.locations = [
|
||||
{
|
||||
locationGroup: 'Localisation du parcours',
|
||||
locations: [personLocation]
|
||||
},
|
||||
{
|
||||
locationGroup: 'Parties concernées',
|
||||
locations: [...concernedPersonsLocation, ...concernedThirdPartiesLocation]
|
||||
},
|
||||
{
|
||||
locationGroup: 'Autres localisations',
|
||||
locations: results
|
||||
}
|
||||
];
|
||||
}
|
||||
)
|
||||
} else {
|
||||
this.locations = [
|
||||
{
|
||||
locationGroup: 'Localisations',
|
||||
locations: response.results
|
||||
}
|
||||
];
|
||||
}
|
||||
if (window.default_location_id) {
|
||||
let location = this.locations.filter(
|
||||
(l) => l.id === window.default_location_id
|
||||
);
|
||||
this.$store.dispatch("updateLocation", location);
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
labelAccompanyingCourseLocation(value) {
|
||||
return `${value.address.text} (${value.locationType.title.fr})`
|
||||
@ -117,58 +65,6 @@ export default {
|
||||
: value.locationType.title.fr
|
||||
: '';
|
||||
},
|
||||
makeConcernedPersonsLocation(locationType) {
|
||||
let locations = [];
|
||||
this.suggestedEntities.forEach(
|
||||
(e) => {
|
||||
if (e.type === 'person' && e.current_household_address !== null){
|
||||
locations.push({
|
||||
type: 'location',
|
||||
id: -this.suggestedEntities.indexOf(e)*10,
|
||||
onthefly: true,
|
||||
name: e.text,
|
||||
address: {
|
||||
id: e.current_household_address.address_id,
|
||||
},
|
||||
locationType: locationType
|
||||
});
|
||||
}
|
||||
}
|
||||
)
|
||||
return locations;
|
||||
},
|
||||
makeConcernedThirdPartiesLocation(locationType) {
|
||||
let locations = [];
|
||||
this.suggestedEntities.forEach(
|
||||
(e) => {
|
||||
if (e.type === 'thirdparty' && e.address !== null){
|
||||
locations.push({
|
||||
type: 'location',
|
||||
id: -this.suggestedEntities.indexOf(e)*10,
|
||||
onthefly: true,
|
||||
name: e.text,
|
||||
address: { id: e.address.address_id },
|
||||
locationType: locationType
|
||||
});
|
||||
}
|
||||
}
|
||||
)
|
||||
return locations;
|
||||
},
|
||||
makeAccompanyingPeriodLocation(locationType) {
|
||||
const accPeriodLocation = this.activity.accompanyingPeriod.location;
|
||||
return {
|
||||
type: 'location',
|
||||
id: -1,
|
||||
onthefly: true,
|
||||
name: '__AccompanyingCourseLocation__',
|
||||
address: {
|
||||
id: accPeriodLocation.address_id,
|
||||
text: `${accPeriodLocation.text} - ${accPeriodLocation.postcode.code} ${accPeriodLocation.postcode.name}`
|
||||
},
|
||||
locationType: locationType
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'es6-promise/auto';
|
||||
import { createStore } from 'vuex';
|
||||
import { postLocation } from './api';
|
||||
import prepareLocations from './store.locations.js';
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production';
|
||||
//console.log('window.activity', window.activity);
|
||||
@ -25,6 +26,7 @@ const store = createStore({
|
||||
activity: window.activity,
|
||||
socialIssuesOther: [],
|
||||
socialActionsList: [],
|
||||
availableLocations: [],
|
||||
},
|
||||
getters: {
|
||||
suggestedEntities(state) {
|
||||
@ -200,6 +202,9 @@ const store = createStore({
|
||||
console.log("### mutation: updateLocation", value);
|
||||
state.activity.location = value;
|
||||
},
|
||||
addAvailableLocationGroup(state, group) {
|
||||
state.availableLocations.push(group);
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
addIssueSelected({ commit }, issue) {
|
||||
@ -335,4 +340,6 @@ const store = createStore({
|
||||
},
|
||||
});
|
||||
|
||||
prepareLocations(store);
|
||||
|
||||
export default store;
|
||||
|
@ -0,0 +1,123 @@
|
||||
import {getLocations, getLocationTypeByDefaultFor, getUserCurrentLocation} from "./api";
|
||||
|
||||
const makeConcernedPersonsLocation = (locationType, store) => {
|
||||
let locations = [];
|
||||
store.getters.suggestedEntities.forEach(
|
||||
(e) => {
|
||||
if (e.type === 'person' && e.current_household_address !== null){
|
||||
locations.push({
|
||||
type: 'location',
|
||||
id: -store.getters.suggestedEntities.indexOf(e)*10,
|
||||
onthefly: true,
|
||||
name: e.text,
|
||||
address: {
|
||||
id: e.current_household_address.address_id,
|
||||
},
|
||||
locationType: locationType
|
||||
});
|
||||
}
|
||||
}
|
||||
)
|
||||
return locations;
|
||||
};
|
||||
const makeConcernedThirdPartiesLocation = (locationType, store) => {
|
||||
let locations = [];
|
||||
store.getters.suggestedEntities.forEach(
|
||||
(e) => {
|
||||
if (e.type === 'thirdparty' && e.address !== null){
|
||||
locations.push({
|
||||
type: 'location',
|
||||
id: -store.getters.suggestedEntities.indexOf(e)*10,
|
||||
onthefly: true,
|
||||
name: e.text,
|
||||
address: { id: e.address.address_id },
|
||||
locationType: locationType
|
||||
});
|
||||
}
|
||||
}
|
||||
)
|
||||
return locations;
|
||||
};
|
||||
const makeAccompanyingPeriodLocation = (locationType, store) => {
|
||||
const accPeriodLocation = store.state.activity.accompanyingPeriod.location;
|
||||
return {
|
||||
type: 'location',
|
||||
id: -1,
|
||||
onthefly: true,
|
||||
name: '__AccompanyingCourseLocation__',
|
||||
address: {
|
||||
id: accPeriodLocation.address_id,
|
||||
text: `${accPeriodLocation.text} - ${accPeriodLocation.postcode.code} ${accPeriodLocation.postcode.name}`
|
||||
},
|
||||
locationType: locationType
|
||||
}
|
||||
};
|
||||
|
||||
export default function prepareLocations(store) {
|
||||
|
||||
// find the locations
|
||||
let allLocations = getLocations().then(
|
||||
(results) => {
|
||||
store.commit('addAvailableLocationGroup', {
|
||||
locationGroup: 'Autres localisations',
|
||||
locations: results
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
let currentLocation = getUserCurrentLocation().then(
|
||||
userCurrentLocation => {
|
||||
if (null !== userCurrentLocation) {
|
||||
store.commit('addAvailableLocationGroup', {
|
||||
locationGroup: 'Ma localisation',
|
||||
locations: [userCurrentLocation]
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let partiesLocations = [], partyPromise;
|
||||
['person', 'thirdparty'].forEach(kind => {
|
||||
partyPromise = getLocationTypeByDefaultFor(kind).then(
|
||||
(kindLocationType) => {
|
||||
if (kindLocationType) {
|
||||
let concernedKindLocations;
|
||||
if (kind === 'person') {
|
||||
concernedKindLocations = makeConcernedPersonsLocation(kindLocationType, store);
|
||||
// add location for the parcours into suggestions
|
||||
const personLocation = makeAccompanyingPeriodLocation(kindLocationType, store);
|
||||
store.commit('addAvailableLocationGroup', {
|
||||
locationGroup: 'Localisation du parcours',
|
||||
locations: [personLocation]
|
||||
});
|
||||
} else {
|
||||
concernedKindLocations = makeConcernedThirdPartiesLocation(kindLocationType, store);
|
||||
}
|
||||
|
||||
store.commit('addAvailableLocationGroup', {
|
||||
locationGroup: kind === 'person' ? 'Usagers concernés' : 'Tiers concernés',
|
||||
locations: concernedKindLocations,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
partiesLocations.push(partyPromise);
|
||||
});
|
||||
|
||||
// when all location are loaded
|
||||
Promise.all([allLocations, currentLocation, ...partiesLocations]).then(() => {
|
||||
console.log('current location in activity', store.state.activity.location);
|
||||
console.log('default loation id', window.default_location_id);
|
||||
if (window.default_location_id) {
|
||||
for (let group of store.state.availableLocations) {
|
||||
console.log(group);
|
||||
let location = group.locations.find((l) => l.id === window.default_location_id);
|
||||
console.log(location);
|
||||
if (location !== undefined) {
|
||||
store.dispatch('updateLocation', location);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
@ -127,24 +127,25 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if activity.comment.comment is not empty and is_granted('CHILL_ACTIVITY_SEE_DETAILS', activity) %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
<h3>{{ 'Comment'|trans }}</h3>
|
||||
</div>
|
||||
<div class="wl-col list">
|
||||
{{ activity.comment|chill_entity_render_box({
|
||||
'disable_markdown': false,
|
||||
'limit_lines': 3,
|
||||
'metadata': false
|
||||
}) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Only if ACL SEE_DETAILS AND/OR only on template SHOW ??
|
||||
durationTime
|
||||
travelTime
|
||||
comment
|
||||
{% if activity.comment.comment is not empty and is_granted('CHILL_ACTIVITY_SEE_DETAILS', activity) %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
<h3>{{ 'Comment'|trans }}</h3>
|
||||
</div>
|
||||
<div class="wl-col list">
|
||||
{{ activity.comment|chill_entity_render_box({
|
||||
'disable_markdown': false,
|
||||
'limit_lines': 3,
|
||||
'metadata': false
|
||||
}) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
documents
|
||||
attendee
|
||||
#}
|
||||
|
@ -1,6 +1,10 @@
|
||||
import 'es6-promise/auto';
|
||||
import { createStore } from 'vuex';
|
||||
import { postLocation } from 'ChillActivityAssets/vuejs/Activity/api';
|
||||
import {
|
||||
getLocations, getLocationTypeByDefaultFor,
|
||||
getUserCurrentLocation
|
||||
} from "../../../../../ChillActivityBundle/Resources/public/vuejs/Activity/api";
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production';
|
||||
|
||||
@ -217,9 +221,7 @@ const store = createStore({
|
||||
hiddenLocation.value = value.id;
|
||||
}
|
||||
commit("updateLocation", value);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -92,8 +92,11 @@
|
||||
%}
|
||||
<div class="item-row details">
|
||||
<div class="item-col">
|
||||
|
||||
{% include 'ChillActivityBundle:Activity:concernedGroups.html.twig' with {'context': accompanyingCourse, 'with_display': 'row', 'entity': calendar } %}
|
||||
{% include 'ChillActivityBundle:Activity:concernedGroups.html.twig' with {
|
||||
'context': accompanyingCourse,
|
||||
'with_display': 'row',
|
||||
'entity': calendar
|
||||
} %}
|
||||
</div>
|
||||
|
||||
{% if calendar.comment.comment is not empty %}
|
||||
|
@ -21,11 +21,14 @@ class LocationApiController extends ApiController
|
||||
{
|
||||
public function customizeQuery(string $action, Request $request, $query): void
|
||||
{
|
||||
$query->andWhere(
|
||||
$query->expr()->andX(
|
||||
$query
|
||||
->leftJoin('e.locationType', 'lt')
|
||||
->andWhere(
|
||||
$query->expr()->andX(
|
||||
$query->expr()->eq('e.availableForUsers', "'TRUE'"),
|
||||
$query->expr()->eq('lt.availableForUsers', "'TRUE'"),
|
||||
$query->expr()->eq('e.active', "'TRUE'"),
|
||||
)
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,27 @@ use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class UserApiController extends ApiController
|
||||
{
|
||||
/**
|
||||
* @Route(
|
||||
* "/api/1.0/main/user-current-location.{_format}",
|
||||
* name="chill_main_user_current_location",
|
||||
* requirements={
|
||||
* "_format": "json"
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @param mixed $_format
|
||||
*/
|
||||
public function currentLocation($_format): JsonResponse
|
||||
{
|
||||
return $this->json(
|
||||
$this->getUser()->getCurrentLocation(),
|
||||
JsonResponse::HTTP_OK,
|
||||
[],
|
||||
['groups' => ['read']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* "/api/1.0/main/whoami.{_format}",
|
||||
|
@ -33,6 +33,13 @@ ul.record_actions {
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
ul.dropdown-menu {
|
||||
li {
|
||||
display: block;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.sticky-form-buttons {
|
||||
margin-top: 4em;
|
||||
|
@ -55,6 +55,15 @@ final class UserApiControllerTest extends WebTestCase
|
||||
return $data['results'][0];
|
||||
}
|
||||
|
||||
public function testUserCurrentLocation()
|
||||
{
|
||||
$client = $this->getClientAuthenticated();
|
||||
|
||||
$client->request(Request::METHOD_GET, '/api/1.0/main/user-current-location.json');
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
}
|
||||
|
||||
public function testWhoami()
|
||||
{
|
||||
$client = $this->getClientAuthenticated();
|
||||
|
@ -546,6 +546,14 @@ paths:
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
/1.0/main/user-current-location.json:
|
||||
get:
|
||||
tags:
|
||||
- user
|
||||
summary: Return the current location of the currently authenticated user
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
/1.0/main/user/{id}.json:
|
||||
get:
|
||||
tags:
|
||||
|
@ -56,6 +56,7 @@ centers: centres
|
||||
Centers: Centres
|
||||
comment: commentaire
|
||||
Comment: Commentaire
|
||||
Pinned comment: Commentaire épinglé
|
||||
Any comment: Aucun commentaire
|
||||
|
||||
# comment embeddable
|
||||
|
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Form\AccompanyingCourseCommentType;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class AccompanyingCourseCommentController extends Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Comments page of Accompanying Course section.
|
||||
*
|
||||
* @Route("/{_locale}/parcours/{accompanying_period_id}/comments", name="chill_person_accompanying_period_comment_list")
|
||||
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
|
||||
*/
|
||||
public function commentAction(AccompanyingPeriod $accompanyingCourse, Request $request): Response
|
||||
{
|
||||
$newComment = new AccompanyingPeriod\Comment();
|
||||
$newComment->setAccompanyingPeriod($accompanyingCourse);
|
||||
|
||||
$form = $this->createCommentForm($newComment, 'new');
|
||||
|
||||
if ($request->query->has('edit')) {
|
||||
foreach ($accompanyingCourse->getComments() as $comment) {
|
||||
if ($comment->getId() === $request->query->getInt('edit')) {
|
||||
$editForm = $this->createCommentForm($comment, 'edit');
|
||||
$commentEditId = $comment->getId();
|
||||
}
|
||||
}
|
||||
$pinnedComment = $accompanyingCourse->getPinnedComment();
|
||||
if ($pinnedComment->getId() === $request->query->getInt('edit')) {
|
||||
$editForm = $this->createCommentForm($pinnedComment, 'edit');
|
||||
$commentEditId = $pinnedComment->getId();
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->getMethod() === Request::METHOD_POST) {
|
||||
if (array_key_exists('edit', $request->request->all()[$editForm->getName()])) {
|
||||
$currentForm = $editForm->handleRequest($request);
|
||||
$isEditingNew = false;
|
||||
} else {
|
||||
$currentForm = $form->handleRequest($request);
|
||||
$isEditingNew = true;
|
||||
}
|
||||
|
||||
if ($currentForm->isSubmitted() && $currentForm->isValid()) {
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
if ($isEditingNew) {
|
||||
$em->persist($newComment);
|
||||
}
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('chill_person_accompanying_period_comment_list', [
|
||||
'accompanying_period_id' => $accompanyingCourse->getId()
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->render('@ChillPerson/AccompanyingCourse/comment_list.html.twig', [
|
||||
'accompanyingCourse' => $accompanyingCourse,
|
||||
'form' => $form->createView(),
|
||||
'edit_form' => isset($editForm) ? $editForm->createView() : null,
|
||||
'commentEditId' => $commentEditId ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
private function createCommentForm(AccompanyingPeriod\Comment $comment, string $step): FormInterface
|
||||
{
|
||||
$form = $this->createForm(AccompanyingCourseCommentType::class, $comment);
|
||||
|
||||
if ('edit' === $step) {
|
||||
$form->add('edit', HiddenType::class, ['mapped' => false ]);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
}
|
@ -95,7 +95,7 @@ class LoadAccompanyingPeriodWork extends \Doctrine\Bundle\FixturesBundle\Fixture
|
||||
// 1 of 10, force an evaluation
|
||||
if (0 === $i % 10) {
|
||||
$evaluation = $this->getRandomEvaluation();
|
||||
$action = $evaluation->getSocialAction();
|
||||
$action = $evaluation->getSocialActions()->first();
|
||||
$issue = $action->getIssue();
|
||||
|
||||
$period->addSocialIssue($issue);
|
||||
|
@ -180,14 +180,6 @@ class AccompanyingPeriod implements
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(
|
||||
* targetEntity=Comment::class
|
||||
* )
|
||||
* @Groups({"read"})
|
||||
*/
|
||||
private ?Comment $initialComment = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(type="string", nullable=true)
|
||||
@ -229,6 +221,14 @@ class AccompanyingPeriod implements
|
||||
*/
|
||||
private ?Person $personLocation = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(
|
||||
* targetEntity=Comment::class
|
||||
* )
|
||||
* @Groups({"read"})
|
||||
*/
|
||||
private ?Comment $pinnedComment = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text")
|
||||
* @Groups({"read", "write"})
|
||||
@ -563,7 +563,7 @@ class AccompanyingPeriod implements
|
||||
public function getComments(): Collection
|
||||
{
|
||||
return $this->comments->filter(function (Comment $c) {
|
||||
return $c !== $this->initialComment;
|
||||
return $c !== $this->pinnedComment;
|
||||
});
|
||||
}
|
||||
|
||||
@ -603,14 +603,6 @@ class AccompanyingPeriod implements
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Groups({"read"})
|
||||
*/
|
||||
public function getInitialComment(): ?Comment
|
||||
{
|
||||
return $this->initialComment;
|
||||
}
|
||||
|
||||
public function getIntensity(): ?string
|
||||
{
|
||||
return $this->intensity;
|
||||
@ -738,6 +730,14 @@ class AccompanyingPeriod implements
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Groups({"read"})
|
||||
*/
|
||||
public function getPinnedComment(): ?Comment
|
||||
{
|
||||
return $this->pinnedComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection|SocialAction[] All the descendant social actions of all
|
||||
* the descendants of the entity
|
||||
@ -1027,24 +1027,6 @@ class AccompanyingPeriod implements
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
public function setInitialComment(?Comment $comment = null): self
|
||||
{
|
||||
if (null !== $this->initialComment) {
|
||||
$this->removeComment($this->initialComment);
|
||||
}
|
||||
|
||||
if ($comment instanceof Comment) {
|
||||
$this->addComment($comment);
|
||||
}
|
||||
|
||||
$this->initialComment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setIntensity(string $intensity): self
|
||||
{
|
||||
$this->intensity = $intensity;
|
||||
@ -1083,6 +1065,24 @@ class AccompanyingPeriod implements
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
public function setPinnedComment(?Comment $comment = null): self
|
||||
{
|
||||
if (null !== $this->pinnedComment) {
|
||||
$this->removeComment($this->pinnedComment);
|
||||
}
|
||||
|
||||
if ($comment instanceof Comment) {
|
||||
$this->addComment($comment);
|
||||
}
|
||||
|
||||
$this->pinnedComment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRemark(?string $remark = null): self
|
||||
{
|
||||
$this->remark = (string) $remark;
|
||||
|
@ -112,6 +112,11 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
|
||||
return $this->updatedBy;
|
||||
}
|
||||
|
||||
public function isPinned(): bool
|
||||
{
|
||||
return $this->getAccompanyingPeriod()->getPinnedComment() === $this;
|
||||
}
|
||||
|
||||
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
|
||||
{
|
||||
$this->accompanyingPeriod = $accompanyingPeriod;
|
||||
|
@ -244,7 +244,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @Assert\Date(
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
* @Assert\GreaterThan(propertyPath="birthDate")
|
||||
* @Assert\GreaterThanOrEqual(propertyPath="birthdate")
|
||||
* @Assert\LessThanOrEqual("today")
|
||||
*/
|
||||
private ?DateTimeImmutable $deathdate = null;
|
||||
|
@ -12,6 +12,8 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Entity\SocialWork;
|
||||
|
||||
use DateInterval;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
@ -45,12 +47,13 @@ class Evaluation
|
||||
private ?DateInterval $notificationDelay = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(
|
||||
* @ORM\ManyToMany(
|
||||
* targetEntity=SocialAction::class,
|
||||
* inversedBy="evaluations"
|
||||
* )
|
||||
* @ORM\JoinTable(name="chill_person_social_work_evaluation_action")
|
||||
*/
|
||||
private ?SocialAction $socialAction = null;
|
||||
private Collection $socialActions;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="json")
|
||||
@ -59,6 +62,20 @@ class Evaluation
|
||||
*/
|
||||
private array $title = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->socialActions = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function addSocialAction(SocialAction $socialAction): self
|
||||
{
|
||||
if (!$this->socialActions->contains($socialAction)) {
|
||||
$this->socialActions->add($socialAction);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDelay(): ?DateInterval
|
||||
{
|
||||
return $this->delay;
|
||||
@ -74,9 +91,9 @@ class Evaluation
|
||||
return $this->notificationDelay;
|
||||
}
|
||||
|
||||
public function getSocialAction(): ?SocialAction
|
||||
public function getSocialActions(): Collection
|
||||
{
|
||||
return $this->socialAction;
|
||||
return $this->socialActions;
|
||||
}
|
||||
|
||||
public function getTitle(): array
|
||||
@ -84,6 +101,15 @@ class Evaluation
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function removeSocialAction(SocialAction $socialAction): self
|
||||
{
|
||||
if ($this->socialActions->contains($socialAction)) {
|
||||
$this->socialActions->remove($socialAction);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDelay(DateInterval $delay): self
|
||||
{
|
||||
$this->delay = $delay;
|
||||
@ -98,13 +124,6 @@ class Evaluation
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSocialAction(?SocialAction $socialAction): self
|
||||
{
|
||||
$this->socialAction = $socialAction;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTitle(array $title): self
|
||||
{
|
||||
$this->title = $title;
|
||||
|
@ -46,9 +46,9 @@ class SocialAction
|
||||
private $desactivationDate;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(
|
||||
* @ORM\ManyToMany(
|
||||
* targetEntity=Evaluation::class,
|
||||
* mappedBy="socialAction"
|
||||
* mappedBy="socialActions"
|
||||
* )
|
||||
*/
|
||||
private Collection $evaluations;
|
||||
@ -71,6 +71,11 @@ class SocialAction
|
||||
*/
|
||||
private $issue;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="float", name="ordering", options={"default": 0.0})
|
||||
*/
|
||||
private float $ordering = 0.0;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=SocialAction::class, inversedBy="children")
|
||||
*/
|
||||
@ -92,6 +97,7 @@ class SocialAction
|
||||
$this->children = new ArrayCollection();
|
||||
$this->goals = new ArrayCollection();
|
||||
$this->results = new ArrayCollection();
|
||||
$this->evaluations = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function addChild(self $child): self
|
||||
@ -199,6 +205,11 @@ class SocialAction
|
||||
return $this->issue;
|
||||
}
|
||||
|
||||
public function getOrdering(): float
|
||||
{
|
||||
return $this->ordering;
|
||||
}
|
||||
|
||||
public function getParent(): ?self
|
||||
{
|
||||
return $this->parent;
|
||||
@ -273,6 +284,13 @@ class SocialAction
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setOrdering(float $ordering): SocialAction
|
||||
{
|
||||
$this->ordering = $ordering;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal use $parent->addChild() instead (@see{self::addChild()})
|
||||
*/
|
||||
|
@ -44,6 +44,11 @@ class SocialIssue
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="float", name="ordering", options={"default": 0.0})
|
||||
*/
|
||||
private float $ordering = 0.0;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=SocialIssue::class, inversedBy="children")
|
||||
*/
|
||||
@ -215,6 +220,11 @@ class SocialIssue
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getOrdering(): float
|
||||
{
|
||||
return $this->ordering;
|
||||
}
|
||||
|
||||
public function getParent(): ?self
|
||||
{
|
||||
return $this->parent;
|
||||
@ -305,6 +315,13 @@ class SocialIssue
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setOrdering(float $ordering): SocialIssue
|
||||
{
|
||||
$this->ordering = $ordering;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal use @see{SocialIssue::addChild()} instead
|
||||
*/
|
||||
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Form;
|
||||
|
||||
use Chill\MainBundle\Form\Type\ChillTextareaType;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class AccompanyingCourseCommentType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder->add('content', ChillTextareaType::class, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefault('class', Comment::class);
|
||||
}
|
||||
}
|
@ -73,6 +73,13 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
|
||||
], ])
|
||||
->setExtras(['order' => 40]);
|
||||
|
||||
$menu->addChild($this->translator->trans('Accompanying Course Comment'), [
|
||||
'route' => 'chill_person_accompanying_period_comment_list',
|
||||
'routeParameters' => [
|
||||
'accompanying_period_id' => $period->getId(),
|
||||
], ])
|
||||
->setExtras(['order' => 50]);
|
||||
|
||||
$workflow = $this->registry->get($period, 'accompanying_period_lifecycle');
|
||||
|
||||
if ($workflow->can($period, 'close')) {
|
||||
|
@ -20,10 +20,10 @@
|
||||
tag-name="textarea">
|
||||
</ckeditor>
|
||||
|
||||
<div v-if="initialComment" class="metadata">
|
||||
<div v-if="pinnedComment" class="metadata">
|
||||
{{ $t('comment.created_by', [
|
||||
initialComment.creator.text,
|
||||
$d(initialComment.createdAt.datetime, 'long')
|
||||
pinnedComment.creator.text,
|
||||
$d(pinnedComment.createdAt.datetime, 'long')
|
||||
]) }}
|
||||
</div>
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
<li>
|
||||
<button type="submit" class="btn btn-save">{{ $t('action.save') }}</button>
|
||||
</li>
|
||||
<li v-if="initialComment !== null">
|
||||
<li v-if="pinnedComment !== null">
|
||||
<a class="btn btn-delete"
|
||||
@click="removeComment">
|
||||
{{ $t('action.delete') }}
|
||||
@ -66,15 +66,15 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
initialComment() {
|
||||
return this.$store.state.accompanyingCourse.initialComment;
|
||||
pinnedComment() {
|
||||
return this.$store.state.accompanyingCourse.pinnedComment;
|
||||
},
|
||||
content: {
|
||||
set(value) {
|
||||
this.formdata.content = value;
|
||||
},
|
||||
get() {
|
||||
return (this.initialComment)? this.initialComment.content : {};
|
||||
return (this.pinnedComment)? this.pinnedComment.content : {};
|
||||
}
|
||||
},
|
||||
errors() {
|
||||
@ -107,7 +107,7 @@ export default {
|
||||
/*
|
||||
* TODO
|
||||
* - [x] delete button in ul record_actions, but not in form
|
||||
* - [ ] display updatedAt => initialComment fetch PATCH content changes MUST NOT change object id !!
|
||||
* - [ ] display updatedAt => pinnedComment fetch PATCH content changes MUST NOT change object id !!
|
||||
*/
|
||||
</script>
|
||||
|
||||
|
@ -132,10 +132,6 @@ const appMessages = {
|
||||
sure_description: "Une fois le changement confirmé, il ne sera plus possible de le remettre à l'état de brouillon !",
|
||||
ok: "Confirmer le parcours"
|
||||
},
|
||||
action: {
|
||||
choose_other_social_issue: "Veuillez choisir un autre problématique",
|
||||
cancel: "Annuler",
|
||||
},
|
||||
// catch errors
|
||||
'Error while updating AccompanyingPeriod Course.': "Erreur du serveur lors de la mise à jour du parcours d'accompagnement.",
|
||||
'Error while retriving AccompanyingPeriod Course.': "Erreur du serveur lors du chargement du parcours d'accompagnement.",
|
||||
|
@ -163,7 +163,7 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
|
||||
},
|
||||
postFirstComment(state, comment) {
|
||||
//console.log('### mutation: postFirstComment', comment);
|
||||
state.accompanyingCourse.initialComment = comment;
|
||||
state.accompanyingCourse.pinnedComment = comment;
|
||||
},
|
||||
updateSocialIssues(state, value) {
|
||||
console.log('updateSocialIssues', value);
|
||||
@ -565,11 +565,11 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
|
||||
},
|
||||
postFirstComment({ commit }, payload) {
|
||||
const url = `/api/1.0/person/accompanying-course/${id}.json`
|
||||
const body = { type: "accompanying_period", initialComment: payload }
|
||||
const body = { type: "accompanying_period", pinnedComment: payload }
|
||||
|
||||
return makeFetch('PATCH', url, body)
|
||||
.then((response) => {
|
||||
commit('postFirstComment', response.initialComment);
|
||||
commit('postFirstComment', response.pinnedComment);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
|
@ -8,10 +8,10 @@
|
||||
<div id="picking">
|
||||
<p>{{ $t('pick_social_issue_linked_with_action') }}</p>
|
||||
<div v-for="si in socialIssues">
|
||||
<input type="radio" checked v-bind:value="si.id" name="socialIssue" v-model="socialIssuePicked"><span class="badge bg-chill-l-gray text-dark">{{ si.text }}</span>
|
||||
<input type="radio" v-bind:value="si.id" name="socialIssue" v-model="socialIssuePicked"><span class="badge bg-chill-l-gray text-dark">{{ si.text }}</span>
|
||||
</div>
|
||||
<div class="my-3">
|
||||
<div class="col-8">
|
||||
<div class="col-11">
|
||||
<vue-multiselect
|
||||
name="otherIssues"
|
||||
label="text"
|
||||
@ -27,7 +27,7 @@
|
||||
:allow-empty="true"
|
||||
:show-labels="false"
|
||||
:loading="issueIsLoading"
|
||||
:placeholder="$t('action.choose_other_social_issue')"
|
||||
:placeholder="$t('choose_other_social_issue')"
|
||||
:options="socialIssuesOther"
|
||||
@select="addIssueInList">
|
||||
</vue-multiselect>
|
||||
@ -35,7 +35,7 @@
|
||||
</div>
|
||||
<div v-if="hasSocialIssuePicked">
|
||||
<h2>{{ $t('pick_an_action') }}</h2>
|
||||
<div class="col-8">
|
||||
<div class="col-11">
|
||||
<vue-multiselect
|
||||
v-model="socialActionPicked"
|
||||
label="text"
|
||||
@ -77,7 +77,7 @@
|
||||
<p>{{ $t('form_has_errors') }}</p>
|
||||
|
||||
<ul>
|
||||
<li v-for="e in errors">
|
||||
<li v-for="e in errors" :key="e.id">
|
||||
{{ e }}
|
||||
</li>
|
||||
</ul>
|
||||
@ -120,10 +120,11 @@ const i18n = {
|
||||
endDate: "Date de fin",
|
||||
form_has_errors: "Le formulaire comporte des erreurs",
|
||||
pick_social_issue: "Choisir une problématique sociale",
|
||||
pick_other_social_issue: "Veuillez choisir un autre problématique",
|
||||
pick_an_action: "Choisir une action d'accompagnement",
|
||||
pick_social_issue_linked_with_action: "Indiquez la problématique sociale liée à l'action d'accompagnement",
|
||||
persons_involved: "Usagers concernés",
|
||||
|
||||
choose_other_social_issue: "Veuillez choisir un autre problématique",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -178,12 +179,10 @@ export default {
|
||||
personsPicked: {
|
||||
get() {
|
||||
let s = this.$store.state.personsPicked.map(p => p.id);
|
||||
// console.log('persons picked', s);
|
||||
|
||||
return s;
|
||||
},
|
||||
set(v) {
|
||||
// console.log('persons picked', v);
|
||||
this.$store.commit('setPersonsPickedIds', v);
|
||||
}
|
||||
},
|
||||
@ -226,6 +225,11 @@ export default {
|
||||
this.$store.commit('setEndDate', ISOToDate(value));
|
||||
}
|
||||
},
|
||||
setSocialIssue: {
|
||||
set() {
|
||||
this.$store.dispatch('setSocialIssue', socialIssues[socialIssues.length - 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,6 @@ const store = createStore({
|
||||
return null !== state.socialActionPicked;
|
||||
},
|
||||
hasSocialIssuePicked(state) {
|
||||
console.log(state.socialIssuePicked);
|
||||
return null !== state.socialIssuePicked;
|
||||
},
|
||||
isLoadingSocialActions(state) {
|
||||
@ -74,36 +73,27 @@ const store = createStore({
|
||||
},
|
||||
mutations: {
|
||||
setSocialActionsReachables(state, actions) {
|
||||
// console.log('set social action reachables');
|
||||
// console.log(actions);
|
||||
|
||||
state.socialActionsReachables = actions;
|
||||
},
|
||||
setSocialAction(state, socialAction) {
|
||||
// console.log('socialAction', socialAction);
|
||||
state.socialActionPicked = socialAction;
|
||||
},
|
||||
setSocialIssue(state, socialIssueId) {
|
||||
// console.log('set social issue', socialIssueId);
|
||||
if (socialIssueId === null) {
|
||||
state.socialIssuePicked = null;
|
||||
} else {
|
||||
let mapped = state.socialIssues
|
||||
.find(e => e.id === socialIssueId);
|
||||
state.socialIssuePicked = mapped;
|
||||
// console.log('social issue setted', state.socialIssuePicked);
|
||||
}
|
||||
},
|
||||
addIssueInList(state, issue) {
|
||||
//console.log('add issue list', issue.id);
|
||||
state.socialIssues.push(issue);
|
||||
},
|
||||
updateIssuesOther(state, payload) {
|
||||
//console.log('update issues other');
|
||||
state.socialIssuesOther = payload;
|
||||
},
|
||||
removeIssueInOther(state, issue) {
|
||||
//console.log('remove issue other', issue.id);
|
||||
state.socialIssuesOther = state.socialIssuesOther.filter(
|
||||
(i) => i.id !== issue.id
|
||||
);
|
||||
@ -124,12 +114,12 @@ const store = createStore({
|
||||
state.endDate = date;
|
||||
},
|
||||
setPersonsPickedIds(state, ids) {
|
||||
console.log('persons ids', ids);
|
||||
|
||||
state.personsPicked = state.personsReachables
|
||||
.filter(p => ids.includes(p.id))
|
||||
},
|
||||
addErrors(state, { errors, cancel_posting }) {
|
||||
console.log('add errors', errors);
|
||||
|
||||
state.errors = errors;
|
||||
if (cancel_posting) {
|
||||
state.isPostingWork = false;
|
||||
@ -138,8 +128,6 @@ const store = createStore({
|
||||
},
|
||||
actions: {
|
||||
pickSocialIssue({ commit }, socialIssueId) {
|
||||
console.log('pick social issue');
|
||||
|
||||
commit('setIsLoadingSocialActions', true);
|
||||
commit('setSocialAction', null);
|
||||
commit('setSocialActionsReachables', []);
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
<ul class="record_actions">
|
||||
<li v-if="!hasHouseholdAddress && !isHouseholdForceAddress">
|
||||
<button class="btn" @click="markNoAddress">
|
||||
<button class="btn btn-misc" @click="markNoAddress">
|
||||
{{ $t('household_members_editor.household_address.mark_no_address') }}
|
||||
</button>
|
||||
</li>
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
|
||||
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n';
|
||||
import { ontheflyMessages } from 'ChillMainAssets/vuejs/OnTheFly/i18n';
|
||||
import { addressMessages } from 'ChillMainAssets/vuejs/Address/i18n';
|
||||
|
||||
const appMessages = {
|
||||
fr: {
|
||||
@ -84,7 +85,7 @@ const appMessages = {
|
||||
}
|
||||
};
|
||||
|
||||
Object.assign(appMessages.fr, personMessages.fr);
|
||||
Object.assign(appMessages.fr, personMessages.fr, addressMessages.fr, ontheflyMessages.fr);
|
||||
|
||||
export {
|
||||
appMessages
|
||||
|
@ -9,6 +9,7 @@ const visMessages = {
|
||||
both: 'neutre, non binaire',
|
||||
woman: 'féminin',
|
||||
man: 'masculin',
|
||||
undefined: "genre non précisé",
|
||||
years: 'ans',
|
||||
click_to_expand: 'cliquez pour étendre',
|
||||
add_relationship_link: "Créer un lien de filiation",
|
||||
|
@ -153,7 +153,7 @@ const getGender = (gender) => {
|
||||
case 'man':
|
||||
return visMessages.fr.visgraph.man
|
||||
default:
|
||||
throw 'gender undefined'
|
||||
return visMessages.fr.visgraph.undefined
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,6 @@ const personMessages = {
|
||||
neuter: "Neutre, non binaire",
|
||||
undefined: "Non renseigné"
|
||||
}
|
||||
|
||||
},
|
||||
error_only_one_person: "Une seule personne peut être sélectionnée !"
|
||||
}
|
||||
|
@ -0,0 +1,92 @@
|
||||
{% extends '@ChillPerson/AccompanyingCourse/layout.html.twig' %}
|
||||
|
||||
{% block title %}
|
||||
{{ 'Accompanying Course Comment list'|trans }}
|
||||
{% endblock %}
|
||||
|
||||
{% macro show_comment(comment, options) %}
|
||||
<div class="item-bloc">
|
||||
<div class="item-row">
|
||||
<div>
|
||||
{% if options.pinned is defined %}
|
||||
<i class="fa fa-flag fa-fw fa-lg" title="{{ 'pinned'|trans }}"></i>
|
||||
{% endif %}
|
||||
<a id="comment{{ comment.id }}" href="{{ '#comment' ~ comment.id }}" class="fa fa-pencil-square-o fa-fw"></a>
|
||||
{{ 'by'|trans }}<b>{{ comment.creator }}</b>{{ ', ' ~ 'on'|trans ~ ' ' ~ comment.createdAt|format_date('long') }}<br>
|
||||
<i>{{ 'Last updated on'|trans ~ ' ' ~ comment.updatedAt|format_datetime('long', 'short') }}</i>
|
||||
</div>
|
||||
<ul class="record_actions">
|
||||
{% if options.pinned is not defined %}
|
||||
<li>
|
||||
<button class="btn btn-sm btn-misc" type="button">
|
||||
<i class="fa fa-flag fa-fw"></i>
|
||||
Épingler
|
||||
</button>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a class="btn btn-sm btn-edit" title="{{ 'Edit'|trans }}" href="{{ path('chill_person_accompanying_period_comment_list', {
|
||||
'accompanying_period_id': comment.accompanyingPeriod.id,
|
||||
'edit': comment.id
|
||||
}) ~ '#comment' ~ comment.id }}"></a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-sm btn-delete" title="{{ 'Delete'|trans }}" href=""></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="item-row separator">
|
||||
<blockquote class="chill-user-quote col">{{ comment.content|chill_markdown_to_html }}</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro form_comment(type, form) %}
|
||||
{% if type == 'edit' %}
|
||||
<div class="item-bloc">
|
||||
<div class="item-row row">
|
||||
{% endif %}
|
||||
{{ form_start(form) }}
|
||||
{{ form_errors(form) }}
|
||||
{{ form_widget(form.content) }}
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
{% if type == 'new' %}
|
||||
<button class="btn btn-create" type="submit">{{ 'Post a new comment'|trans }}</button>
|
||||
{% elseif type == 'edit' %}
|
||||
<button class="btn btn-save" type="submit">{{ 'Save'|trans }}</button>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(form) }}
|
||||
{% if type == 'edit' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block content %}
|
||||
<div class="accompanyingcourse-comment-list">
|
||||
<h1>{{ block('title') }}</h1>
|
||||
<div class="flex-table">
|
||||
{% if accompanyingCourse.pinnedComment %}
|
||||
{% if commentEditId == accompanyingCourse.pinnedComment.id %}
|
||||
{{ _self.form_comment('edit', edit_form) }}
|
||||
{% else %}
|
||||
{{ _self.show_comment(accompanyingCourse.pinnedComment, {'pinned': 'true'}) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% for c in accompanyingCourse.comments %}
|
||||
{% if commentEditId == c.id %}
|
||||
{{ _self.form_comment('edit', edit_form) }}
|
||||
{% else %}
|
||||
{{ _self.show_comment(c) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="new-comment my-5">
|
||||
<h2 class="chill-blue">{{ 'Write a new comment'|trans }}</h2>
|
||||
{{ _self.form_comment('new', form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -78,6 +78,25 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if accompanyingCourse.pinnedComment is not empty %}
|
||||
<div class="col col-sm-6 col-lg-4 comment mb-4">
|
||||
<h4 class="item-key">{{ 'Pinned comment'|trans }}</h4>
|
||||
<blockquote class="chill-user-quote">
|
||||
{{ accompanyingCourse.pinnedComment.content }}
|
||||
<div class="metadata">
|
||||
{{ 'Last updated by'| trans }}
|
||||
<span class="user">
|
||||
{{ accompanyingCourse.pinnedComment.updatedBy|chill_entity_render_box }}
|
||||
</span>
|
||||
{{ 'on'|trans ~ ' ' }}
|
||||
<span class="date">
|
||||
{{ accompanyingCourse.pinnedComment.updatedAt|format_datetime("medium", "short") }}
|
||||
</span>
|
||||
</div>
|
||||
</blockquote>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if accompanyingCourse.scopes is not empty %}
|
||||
<div class="col col-sm-6 col-lg-4 scopes mb-4">
|
||||
<h4 class="item-key">{{ 'Scopes'|trans }}</h4>
|
||||
|
@ -65,11 +65,12 @@
|
||||
</div>
|
||||
<div class="wl-col list">
|
||||
{% for p in w.persons %}
|
||||
<span class="wl-item badge-person">
|
||||
{{ p|chill_entity_render_box({
|
||||
'render': 'raw',
|
||||
'addAltNames': false
|
||||
}) }}
|
||||
<span class="wl-item">
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: 'person', id: p.id },
|
||||
buttonText: p|chill_entity_render_string
|
||||
} %}
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@ -82,11 +83,12 @@
|
||||
<h3>{{ 'Thirdparty handling'|trans }}</h3>
|
||||
</div>
|
||||
<div class="wl-col list">
|
||||
<span class="wl-item badge-thirdparty">
|
||||
{{ w.handlingThierParty|chill_entity_render_box({
|
||||
'render': 'raw',
|
||||
'addAltNames': false
|
||||
}) }}
|
||||
<span class="wl-item">
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: 'thirdparty', id: w.handlingThierParty.id },
|
||||
buttonText: w.handlingThierParty|chill_entity_render_string
|
||||
} %}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -153,7 +155,6 @@
|
||||
</div>
|
||||
|
||||
<div class="item-row column">
|
||||
{# SEULEMENT SI DÉTAILLÉ
|
||||
{% if w.results|length > 0 %}
|
||||
<div class="objective_results without-objectives">
|
||||
<div class="objective">
|
||||
@ -192,7 +193,6 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
#}
|
||||
</div>
|
||||
|
||||
<div class="item-row separator">
|
||||
|
@ -43,7 +43,39 @@
|
||||
</ul>
|
||||
|
||||
<ul class="small_in_title evaluations mb-3">
|
||||
{% for e in w.accompanyingPeriodWorkEvaluations %}
|
||||
A{% for g in w.goals %}
|
||||
<li class="with-objectives">
|
||||
<span class="item-key">{{ 'accompanying_course_work.goal'|trans ~ ' : ' }}</span>
|
||||
{{ g.goal.title|localize_translatable_string }}
|
||||
{% if g.results|length > 0 %}
|
||||
<span class="item-key">{{ 'accompanying_course_work.results'|trans }}</span>
|
||||
<ul>
|
||||
{% for r in g.results %}
|
||||
<li>
|
||||
{{ r.title|localize_translatable_string }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
B{% if w.results|length > 0 %}
|
||||
<li class="without-objectives">
|
||||
<span class="item-key">{{ 'accompanying_course_work.goal'|trans }}</span>
|
||||
<p class="chill-no-data-statement">{{ 'accompanying_course_work.results without objective'|trans }}</p>
|
||||
{% if w.results %}
|
||||
<span class="item-key">{{ 'accompanying_course_work.results'|trans }}</span>
|
||||
<ul>
|
||||
{% for r in w.results %}
|
||||
<li>
|
||||
{{ r.title|localize_translatable_string }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endif %}
|
||||
C{% for e in w.accompanyingPeriodWorkEvaluations %}
|
||||
<li>
|
||||
<span class="item-key">{{ 'accompanying_course_work.social_evaluation'|trans ~ ' : ' }}</span>
|
||||
{{ e.evaluation.title|localize_translatable_string }}
|
||||
@ -55,7 +87,7 @@
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if e.endDate %}
|
||||
<li>
|
||||
<li>
|
||||
<span class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
|
||||
<b>{{ e.endDate|format_date('short') }}</b>
|
||||
</li>
|
||||
|
@ -66,10 +66,22 @@
|
||||
<div class="wl-col title"><h3>{{ 'Requestor'|trans({'gender': null }) }}</h3></div>
|
||||
<div class="wl-col list">
|
||||
{% if accompanying_period.requestorPerson is not null %}
|
||||
<span class="wl-item badge-person">{{ accompanying_period.requestorPerson|chill_entity_render_string }}</span>
|
||||
<span class="wl-item">
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: 'person', id: accompanying_period.requestorPerson.id },
|
||||
buttonText: accompanying_period.requestorPerson|chill_entity_render_string
|
||||
} %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if accompanying_period.requestorThirdParty is not null %}
|
||||
<span class="wl-item badge-thirdparty">{{ accompanying_period.requestorThirdParty|chill_entity_render_string }}</span>
|
||||
<span class="wl-item">
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: 'thirdparty', id: accompanying_period.requestorThirdParty.id },
|
||||
buttonText: accompanying_period.requestorThirdParty|chill_entity_render_string
|
||||
} %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@ -80,13 +92,12 @@
|
||||
<div class="wl-col title"><h3>{{ 'Participants'|trans }}</h3></div>
|
||||
<div class="wl-col list">
|
||||
{% for p in accompanying_period.getCurrentParticipations %}
|
||||
<span class="wl-item badge-person">
|
||||
<a href="{{ path('chill_person_accompanying_period_list', { person_id: p.person.id }) }}">
|
||||
{{ p.person|chill_entity_render_string }}
|
||||
</a>
|
||||
{# or in renderbox mode
|
||||
{{ p.person|chill_entity_render_box({'render': 'label', 'addAltNames': false, 'addLink': true, 'hLevel': 5 }) }}
|
||||
#}
|
||||
<span class="wl-item">
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: 'person', id: p.person.id },
|
||||
buttonText: p.person|chill_entity_render_string
|
||||
} %}
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
@ -133,7 +133,7 @@
|
||||
{% macro customButtons(member, household) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_members_editor', {'persons': [ member.person.id ], 'allow_leave_without_household': true } ) }}"
|
||||
class="btn btn-sm btn-unlink" title="{{ 'household.person.leave'|trans }}"></a>
|
||||
class="btn btn-sm btn-misc" title="{{ 'household.person.leave'|trans }}"><i class="fa fa-scissors"></i></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_members_editor', {'persons': [ member.person.id ], 'household': household.id} ) }}"
|
||||
@ -146,7 +146,7 @@
|
||||
{% for m in members %}
|
||||
{% include '@ChillPerson/Household/_render_member.html.twig' with {
|
||||
'member': m,
|
||||
'customButtons': { 'after': _self.customButtons(m, household) }
|
||||
'customButtons': { 'before': _self.customButtons(m, household) }
|
||||
} %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
@ -4,176 +4,163 @@
|
||||
|
||||
{% block title 'household.Household history for person'|trans %}
|
||||
|
||||
{% macro bloc_content(p) %}
|
||||
<div class="item-row">
|
||||
<div class="wrap-header">
|
||||
<div class="wh-row">
|
||||
<div class="wh-col">
|
||||
<h3>
|
||||
<i class="fa fa-home"></i>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_summary',{ 'household_id': p.household.id }) }}">
|
||||
{{ 'household.Household number'|trans({'household_num': p.household.id }) }}
|
||||
</a>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="wh-col">
|
||||
Depuis le {{ p.startDate|format_date('long') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="wh-row">
|
||||
<div class="wh-col"></div>
|
||||
{% if p.endDate %}
|
||||
<div class="wh-col">
|
||||
Jusqu'au {{ p.endDate|format_date('long') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-row separator">
|
||||
<div class="wrap-list">
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
<h3>En tant que</h3>
|
||||
</div>
|
||||
<div class="wl-col list">
|
||||
<p class="item">{{ p.position.label|localize_translatable_string }}
|
||||
{% if p.holder %}
|
||||
<span class="holder">{{ 'household.holder'|trans }}</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
<h3>{{ 'household.Members at same time'|trans }}</h3>
|
||||
</div>
|
||||
<div class="wl-col list">
|
||||
{% set simultaneous = p.household.getMembersDuringMembership(p) %}
|
||||
{% if simultaneous|length == 0 %}
|
||||
<p class="chill-no-data-statement">
|
||||
{{ 'household.Any simultaneous members'|trans }}
|
||||
</p>
|
||||
{% else %}
|
||||
{% for m in simultaneous -%}
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: 'person', id: m.person.id },
|
||||
buttonText: m.person|chill_entity_render_string
|
||||
} %}
|
||||
{%- endfor -%}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% block personcontent %}
|
||||
<div class="person-household">
|
||||
<h1>{{ 'household.Household history'|trans }}</h1>
|
||||
|
||||
<h1>{{ 'household.Household history'|trans }}</h1>
|
||||
<h2>{{ 'household.Household shared'|trans }}</h2>
|
||||
<div class="household_shared">
|
||||
<h2 class="chill-blue">{{ 'household.Household shared'|trans }}</h2>
|
||||
{% set memberships = person.getHouseholdParticipationsShareHousehold() %}
|
||||
|
||||
{% set memberships = person.getHouseholdParticipationsShareHousehold() %}
|
||||
{% if memberships|length == 0 %}
|
||||
<p class="chill-no-data-statement">{{ 'household.Never in any household'|trans }}</p>
|
||||
|
||||
{% if memberships|length == 0 %}
|
||||
<p class="chill-no-data-statement">{{ 'household.Never in any household'|trans }}</p>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a class="btn btn-misc" href="{{chill_path_add_return_path('chill_person_household_members_editor', { 'persons': [ person.id ]}) }}">
|
||||
<i class="fa fa-sign-in fa-fw"></i>
|
||||
{{ 'household.Join'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% else %}
|
||||
<div class="flex-table">
|
||||
{% for p in memberships %}
|
||||
<div class="item-bloc">
|
||||
|
||||
{{ _self.bloc_content(p) }}
|
||||
|
||||
<div class="item-row separator">
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_summary',{ 'household_id': p.household.id }) }}"
|
||||
class="btn btn-show" title="{{ 'Show'|trans }}"></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_member_edit', { id: p.id }) }}"
|
||||
class="btn btn-edit" title="{{ 'Edit'|trans }}"></a>
|
||||
</li>
|
||||
{% if p.isCurrent() %}
|
||||
<li>
|
||||
<a class="btn btn-misc" href="{{ chill_path_add_return_path( 'chill_person_household_members_editor', { 'persons': [ person.id ], 'allow_leave_without_household': true }) }}">
|
||||
<i class="fa fa-scissors"></i>
|
||||
{{ 'household.Leave'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if not person.isSharingHousehold() %}
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a class="btn btn-misc" href="{{chill_path_add_return_path('chill_person_household_members_editor', { 'persons': [ person.id ]}) }}">
|
||||
<i class="fa fa-sign-out"></i>
|
||||
<a class="btn btn-misc" href="{{ chill_path_add_return_path('chill_person_household_members_editor', { 'persons': [ person.id ]}) }}">
|
||||
<i class="fa fa-sign-in fa-fw"></i>
|
||||
{{ 'household.Join'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% else %}
|
||||
|
||||
<div class="household">
|
||||
<div class="household__address">
|
||||
|
||||
{% if not person.isSharingHousehold() %}
|
||||
<div class="row">
|
||||
<div class="household__address--date"></div>
|
||||
<div class="household__address--content">
|
||||
<div class="cell">
|
||||
<a class="btn btn-misc" href="{{ chill_path_add_return_path('chill_person_household_members_editor', { 'persons': [ person.id ]}) }}">
|
||||
<i class="fa fa-sign-out"></i>
|
||||
{{ 'household.Join'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% for p in memberships %}
|
||||
<div class="row">
|
||||
<div class="household__address--date">
|
||||
<div class="cell">
|
||||
<div class="pill">
|
||||
{{ p.startDate|format_date('long') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="household__address--content">
|
||||
<div class="cell">
|
||||
<i class="dot"></i>
|
||||
<div>
|
||||
<div>
|
||||
<p>
|
||||
<i class="fa fa-home"></i>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_summary',{ 'household_id': p.household.id }) }}">
|
||||
{{ 'household.Household number'|trans({'household_num': p.household.id }) }}
|
||||
</a>
|
||||
</p>
|
||||
<p>{{ p.position.label|localize_translatable_string }} {% if p.holder %}<span class="badge bg-primary">{{ 'household.holder'|trans }}</span>{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{% set simultaneous = p.household.getMembersDuringMembership(p) %}
|
||||
{% if simultaneous|length == 0 %}
|
||||
<p class="chill-no-data-statement">
|
||||
{{ 'household.Any simultaneous members'|trans }}
|
||||
</p>
|
||||
{% else %}
|
||||
{{ 'household.Members at same time'|trans }}:
|
||||
{% for p in simultaneous -%}
|
||||
{{- p.person|chill_entity_render_box({'addLink': true }) -}}
|
||||
{%- if p.holder %} <span class="badge bg-primary">{{'household.holder'|trans }}</span> {% endif %}
|
||||
{%- if not loop.last %}, {% endif -%}
|
||||
{%- endfor -%}
|
||||
{% endif %}
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_member_edit', { id: p.id }) }}"
|
||||
class="btn btn-edit"></a>
|
||||
</li>
|
||||
{% if p.isCurrent() %}
|
||||
<li>
|
||||
<a class="btn btn-misc" href="{{ chill_path_add_return_path( 'chill_person_household_members_editor', { 'persons': [ person.id ], 'allow_leave_without_household': true }) }}">
|
||||
<i class="fa fa-sign-out"></i>
|
||||
{{ 'household.Leave'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h2>{{ 'household.Household not shared'|trans }}</h2>
|
||||
{% endif %}
|
||||
|
||||
{% set memberships = person.getHouseholdParticipationsNotShareHousehold() %}
|
||||
</div>
|
||||
<div class="household_not_shared">
|
||||
{% set memberships = person.getHouseholdParticipationsNotShareHousehold() %}
|
||||
{% if memberships|length > 0 %}
|
||||
|
||||
{% if memberships|length == 0 %}
|
||||
<p class="chill-no-data-statement">{{ 'household.Never in any household'|trans }}</p>
|
||||
{% else %}
|
||||
<table class="table table-bordered border-dark">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'household.from'|trans }}</th>
|
||||
<th>{{ 'household.to'|trans }}</th>
|
||||
<th>{{ 'household.Household'|trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for p in memberships %}
|
||||
<tr>
|
||||
<td>{{ p.startDate|format_date('long') }}</td>
|
||||
<td>
|
||||
{% if p.endDate is not empty %}
|
||||
{{ p.endDate|format_date('long') }}
|
||||
{% else %}
|
||||
{{ 'household.Membership currently running'|trans }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
<p>
|
||||
<i class="fa fa-home"></i>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_summary', { 'household_id': p.household.id }) }}">
|
||||
{{ 'household.Household number'|trans({'household_num': p.household.id }) }}
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
{{ p.position.label|localize_translatable_string }}
|
||||
{% if p.holder %}
|
||||
<span class="badge bg-primary">{{ 'household.holder'|trans }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{% set simultaneous = p.household.getMembersDuringMembership(p) %}
|
||||
{% if simultaneous|length == 0 %}
|
||||
<p class="chill-no-data-statement">
|
||||
{{ 'household.Any simultaneous members'|trans }}
|
||||
</p>
|
||||
{% else %}
|
||||
{{ 'household.Members at same time'|trans }}:
|
||||
{% for p in simultaneous -%}
|
||||
{{- p.person|chill_entity_render_box({'addLink': true }) -}}
|
||||
{%- if p.holder %} <span class="badge bg-primary">{{'household.holder'|trans }}</span> {% endif %}
|
||||
{%- if not loop.last %}, {% endif -%}
|
||||
{%- endfor -%}
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_member_edit', { id: p.id }) }}"
|
||||
class="btn btn-edit">
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
<h2 class="chill-blue">{{ 'household.Household not shared'|trans }}</h2>
|
||||
|
||||
<div class="flex-table">
|
||||
{% for p in memberships %}
|
||||
<div class="item-bloc">
|
||||
|
||||
{{ _self.bloc_content(p) }}
|
||||
|
||||
<div class="item-row separator">
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_member_edit', { id: p.id }) }}"
|
||||
class="btn btn-edit" title="{{ 'Edit'|trans }}"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -192,7 +192,7 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
/** @var Evaluation $eval */
|
||||
$eval = $this->getOrCreateEntity($this->evaluationRepository, 'title', ['fr' => $evaluationTitle]);
|
||||
$eval->setTitle(['fr' => $evaluationTitle]);
|
||||
$eval->setSocialAction($socialAction);
|
||||
$eval->addSocialAction($socialAction);
|
||||
|
||||
$this->entityManager->persist($eval);
|
||||
|
||||
@ -212,7 +212,7 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
$socialAction->addGoal($goal);
|
||||
$goal->addSocialAction($socialAction);
|
||||
|
||||
//$this->entityManager->persist($socialAction);
|
||||
$this->entityManager->persist($socialAction);
|
||||
$this->entityManager->persist($goal);
|
||||
|
||||
return $goal;
|
||||
@ -239,7 +239,7 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
}
|
||||
|
||||
$this->entityManager->persist($result);
|
||||
//$this->entityManager->persist($socialAction);
|
||||
$this->entityManager->persist($socialAction);
|
||||
|
||||
return $result;
|
||||
}
|
||||
@ -253,6 +253,8 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
?string $socialActionTitle,
|
||||
?string $socialActionChildTitle,
|
||||
SocialIssue $socialIssue,
|
||||
float $orderingParent,
|
||||
float $orderingChild,
|
||||
?SocialAction $previousSocialAction,
|
||||
?SocialAction $previousSocialActionChild
|
||||
): array {
|
||||
@ -271,7 +273,8 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
];
|
||||
$parentIsSame = true;
|
||||
} else {
|
||||
$return['socialAction'] = $parent = (new SocialAction())->setTitle(['fr' => $socialActionTitle]);
|
||||
$return['socialAction'] = $parent = (new SocialAction())->setTitle(['fr' => $socialActionTitle])
|
||||
->setOrdering($orderingParent);
|
||||
$parent->setIssue($socialIssue);
|
||||
$this->entityManager->persist($parent);
|
||||
$parentIsSame = false;
|
||||
@ -284,7 +287,7 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
} else {
|
||||
$return['socialActionChild'] = $child = (new SocialAction())->setTitle(['fr' => $socialActionChildTitle]);
|
||||
$parent->addChild($child);
|
||||
$child->setIssue($socialIssue);
|
||||
$child->setIssue($socialIssue)->setOrdering($orderingChild);
|
||||
$this->entityManager->persist($child);
|
||||
}
|
||||
|
||||
@ -299,6 +302,8 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
private function handleSocialIssue(
|
||||
?string $socialIssueTitle,
|
||||
?string $socialIssueChildTitle,
|
||||
float $orderingParent,
|
||||
float $orderingChild,
|
||||
?SocialIssue $previousSocialIssue,
|
||||
?SocialIssue $previousSocialIssueChild
|
||||
): array {
|
||||
@ -310,7 +315,8 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
];
|
||||
$parentIsSame = true;
|
||||
} elseif (null !== $socialIssueTitle) {
|
||||
$return['socialIssue'] = $parent = (new SocialIssue())->setTitle(['fr' => $socialIssueTitle]);
|
||||
$return['socialIssue'] = $parent = (new SocialIssue())->setTitle(['fr' => $socialIssueTitle])
|
||||
->setOrdering($orderingParent);
|
||||
$this->entityManager->persist($parent);
|
||||
$parentIsSame = false;
|
||||
} else {
|
||||
@ -323,7 +329,8 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
if ($parentIsSame && null !== $previousSocialIssueChild && ($previousSocialIssueChild->getTitle()['fr'] === $socialIssueChildTitle)) {
|
||||
$return['socialIssueChild'] = $previousSocialIssueChild;
|
||||
} elseif (null !== $socialIssueChildTitle) {
|
||||
$return['socialIssueChild'] = $child = (new SocialIssue())->setTitle(['fr' => $socialIssueChildTitle]);
|
||||
$return['socialIssueChild'] = $child = (new SocialIssue())->setTitle(['fr' => $socialIssueChildTitle])
|
||||
->setOrdering($orderingChild);
|
||||
$parent->addChild($child);
|
||||
$this->entityManager->persist($child);
|
||||
} else {
|
||||
@ -353,10 +360,14 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
*/
|
||||
private function import1(int $key, array $row, array $previousRow): array
|
||||
{
|
||||
$baseOrdering = $key * 10.0;
|
||||
|
||||
$socialIssues = $this
|
||||
->handleSocialIssue(
|
||||
$row[0],
|
||||
$row[1],
|
||||
$key + 1.0,
|
||||
$key + 3.0,
|
||||
$previousRow['socialIssues']['socialIssue'] ?? null,
|
||||
$previousRow['socialIssues']['socialIssueChild'] ?? null
|
||||
);
|
||||
@ -372,6 +383,8 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
$row[2],
|
||||
$row[3],
|
||||
$socialIssue,
|
||||
$key + 5.0,
|
||||
$key + 7.0,
|
||||
$previousRow['socialActions']['socialAction'] ?? null,
|
||||
$previousRow['socialActions']['socialActionChild'] ?? null
|
||||
);
|
||||
@ -380,8 +393,8 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
|
||||
|
||||
if (null !== $socialAction) {
|
||||
$goal = $this->handleGoal($row[4], $socialAction);
|
||||
$result = $this->handleResult($row[5], $socialActions['socialAction'], $goal);
|
||||
$eval = $this->handleEvaluation($row[6], $socialActions['socialAction']);
|
||||
$result = $this->handleResult($row[5], $socialAction, $goal);
|
||||
$eval = $this->handleEvaluation($row[6], $socialAction);
|
||||
}
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
@ -60,32 +60,6 @@ final class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
|
||||
$this->assertFalse($period->isClosingAfterOpening());
|
||||
}
|
||||
|
||||
public function testInitialComment()
|
||||
{
|
||||
$period = new AccompanyingPeriod(new DateTime());
|
||||
$comment = new Comment();
|
||||
$replacingComment = new Comment();
|
||||
|
||||
$period->setInitialComment(null);
|
||||
$this->assertNull($period->getInitialComment());
|
||||
|
||||
$period->setInitialComment($comment);
|
||||
$this->assertSame($period->getInitialComment(), $comment);
|
||||
$this->assertSame($period, $comment->getAccompanyingPeriod());
|
||||
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
|
||||
|
||||
$period->setInitialComment($replacingComment);
|
||||
$this->assertSame($period->getInitialComment(), $replacingComment);
|
||||
$this->assertSame($period, $replacingComment->getAccompanyingPeriod());
|
||||
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
|
||||
$this->assertNull($comment->getAccompanyingPeriod());
|
||||
|
||||
$period->setInitialComment(null);
|
||||
$this->assertNull($period->getInitialComment());
|
||||
$this->assertNull($replacingComment->getAccompanyingPeriod());
|
||||
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
|
||||
}
|
||||
|
||||
public function testIsClosed()
|
||||
{
|
||||
$period = new AccompanyingPeriod(new DateTime());
|
||||
@ -145,6 +119,32 @@ final class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
|
||||
$this->assertEquals(1, $period->getParticipationsContainsPerson($person4)->count());
|
||||
}
|
||||
|
||||
public function testPinnedComment()
|
||||
{
|
||||
$period = new AccompanyingPeriod(new DateTime());
|
||||
$comment = new Comment();
|
||||
$replacingComment = new Comment();
|
||||
|
||||
$period->setPinnedComment(null);
|
||||
$this->assertNull($period->getPinnedComment());
|
||||
|
||||
$period->setPinnedComment($comment);
|
||||
$this->assertSame($period->getPinnedComment(), $comment);
|
||||
$this->assertSame($period, $comment->getAccompanyingPeriod());
|
||||
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
|
||||
|
||||
$period->setPinnedComment($replacingComment);
|
||||
$this->assertSame($period->getPinnedComment(), $replacingComment);
|
||||
$this->assertSame($period, $replacingComment->getAccompanyingPeriod());
|
||||
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
|
||||
$this->assertNull($comment->getAccompanyingPeriod());
|
||||
|
||||
$period->setPinnedComment(null);
|
||||
$this->assertNull($period->getPinnedComment());
|
||||
$this->assertNull($replacingComment->getAccompanyingPeriod());
|
||||
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
|
||||
}
|
||||
|
||||
public function testRequestor()
|
||||
{
|
||||
$period = new AccompanyingPeriod(new DateTime());
|
||||
|
@ -554,7 +554,7 @@ paths:
|
||||
value:
|
||||
type: accompanying_period
|
||||
id: 2668,
|
||||
initialComment:
|
||||
pinnedComment:
|
||||
type: accompanying_period_comment
|
||||
content: >
|
||||
This is my an initial comment.
|
||||
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20211213150253 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period DROP CONSTRAINT FK_E260A868B0804E90');
|
||||
$this->addSql('DROP INDEX IDX_E260A868B0804E90');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period RENAME COLUMN pinnedcomment_id TO initialcomment_id');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT fk_e260a8683111d50b FOREIGN KEY (initialcomment_id) REFERENCES chill_person_accompanying_period_comment (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX idx_e260a8683111d50b ON chill_person_accompanying_period (initialcomment_id)');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'rename initialComment attribute to pinnedComment';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period DROP CONSTRAINT fk_e260a8683111d50b');
|
||||
$this->addSql('DROP INDEX idx_e260a8683111d50b');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period RENAME COLUMN initialcomment_id TO pinnedcomment_id');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT FK_E260A868B0804E90 FOREIGN KEY (pinnedcomment_id) REFERENCES chill_person_accompanying_period_comment (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX IDX_E260A868B0804E90 ON chill_person_accompanying_period (pinnedcomment_id)');
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* change model: an evaluation may be linked with multiple social actions.
|
||||
*/
|
||||
final class Version20211213203147 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP TABLE chill_person_social_work_evaluation_action');
|
||||
$this->addSql('ALTER TABLE chill_person_social_work_evaluation ADD socialaction_id INT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE chill_person_social_work_evaluation ADD CONSTRAINT fk_2e23f3febf32a3da FOREIGN KEY (socialaction_id) REFERENCES chill_person_social_action (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX idx_2e23f3febf32a3da ON chill_person_social_work_evaluation (socialaction_id)');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'an evaluation may be linked with multiple social actions';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE TABLE chill_person_social_work_evaluation_action (evaluation_id INT NOT NULL, socialaction_id INT NOT NULL, PRIMARY KEY(evaluation_id, socialaction_id))');
|
||||
$this->addSql('CREATE INDEX IDX_DF34CCFB456C5646 ON chill_person_social_work_evaluation_action (evaluation_id)');
|
||||
$this->addSql('CREATE INDEX IDX_DF34CCFB3DC32179 ON chill_person_social_work_evaluation_action (socialaction_id)');
|
||||
$this->addSql('ALTER TABLE chill_person_social_work_evaluation_action ADD CONSTRAINT FK_DF34CCFB456C5646 FOREIGN KEY (evaluation_id) REFERENCES chill_person_social_work_evaluation (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE chill_person_social_work_evaluation_action ADD CONSTRAINT FK_DF34CCFB3DC32179 FOREIGN KEY (socialaction_id) REFERENCES chill_person_social_action (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
|
||||
$this->addSql('INSERT INTO chill_person_social_work_evaluation_action (evaluation_id, socialaction_id) ' .
|
||||
'SELECT id, socialaction_ID FROM chill_person_social_work_evaluation');
|
||||
|
||||
$this->addSql('ALTER TABLE chill_person_social_work_evaluation DROP CONSTRAINT fk_2e23f3febf32a3da');
|
||||
$this->addSql('DROP INDEX idx_2e23f3febf32a3da');
|
||||
$this->addSql('ALTER TABLE chill_person_social_work_evaluation DROP socialaction_id');
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20211213213755 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_social_action DROP ordering');
|
||||
$this->addSql('ALTER TABLE chill_person_social_issue DROP ordering');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add ordering to social issue and social actions';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_social_action ADD ordering DOUBLE PRECISION DEFAULT \'0\' NOT NULL');
|
||||
$this->addSql('ALTER TABLE chill_person_social_issue ADD ordering DOUBLE PRECISION DEFAULT \'0\' NOT NULL');
|
||||
}
|
||||
}
|
@ -408,6 +408,14 @@ Associate at least one member with an household, and set an address to this hous
|
||||
Locate by: Localiser auprès de
|
||||
fix it: Compléter
|
||||
|
||||
# Accompanying Course comments
|
||||
Accompanying Course Comment: Commentaire
|
||||
Accompanying Course Comment list: Commentaires du parcours
|
||||
pinned: épinglé
|
||||
Post a new comment: Poster un nouveau commentaire
|
||||
Write a new comment: Écrire un nouveau commentaire
|
||||
Edit a comment: Modifier le commentaire
|
||||
|
||||
# Household
|
||||
Household: Ménage
|
||||
Summary: Résumé
|
||||
|
@ -219,10 +219,9 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
||||
private ?string $telephone = null;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
* @ORM\Column(name="types", type="json", nullable=true)
|
||||
*/
|
||||
private $types;
|
||||
private ?array $thirdPartyTypes = [];
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="updated_at", type="datetime_immutable", nullable=true)
|
||||
@ -303,18 +302,18 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addType(?string $type): self
|
||||
public function addThirdPartyTypes(?string $type): self
|
||||
{
|
||||
if (null === $type) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (!in_array($type, $this->types ?? [], true)) {
|
||||
$this->types[] = $type;
|
||||
if (!in_array($type, $this->thirdPartyTypes ?? [], true)) {
|
||||
$this->thirdPartyTypes[] = $type;
|
||||
}
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$child->addType($type);
|
||||
$child->addThirdPartyTypes($type);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@ -329,7 +328,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
||||
}
|
||||
|
||||
if (is_string($typeAndCategory)) {
|
||||
$this->addType($typeAndCategory);
|
||||
$this->addThirdPartyTypes($typeAndCategory);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -473,16 +472,16 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getTypes()
|
||||
public function getThirdPartyTypes()
|
||||
{
|
||||
return $this->types;
|
||||
return $this->thirdPartyTypes ?? [];
|
||||
}
|
||||
|
||||
public function getTypesAndCategories(): array
|
||||
{
|
||||
return array_merge(
|
||||
$this->getCategories()->toArray(),
|
||||
$this->getTypes() ?? []
|
||||
$this->getThirdPartyTypes() ?? []
|
||||
);
|
||||
}
|
||||
|
||||
@ -574,18 +573,18 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeType(?string $type): self
|
||||
public function removeThirdPartyTypes(?string $type): self
|
||||
{
|
||||
if (null === $type) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (in_array($type, $this->types ?? [], true)) {
|
||||
$this->types = array_filter($this->types, fn ($e) => !in_array($e, $this->types, true));
|
||||
if (in_array($type, $this->thirdPartyTypes ?? [], true)) {
|
||||
$this->thirdPartyTypes = array_filter($this->thirdPartyTypes, fn ($e) => !in_array($e, $this->thirdPartyTypes, true));
|
||||
}
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$child->removeType($type);
|
||||
$child->removeThirdPartyTypes($type);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@ -600,7 +599,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
||||
}
|
||||
|
||||
if (is_string($typeAndCategory)) {
|
||||
$this->removeType($typeAndCategory);
|
||||
$this->removeThirdPartyTypes($typeAndCategory);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -799,13 +798,13 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
||||
*
|
||||
* @return ThirdParty
|
||||
*/
|
||||
public function setTypes(?array $type = null)
|
||||
public function setThirdPartyTypes(?array $type = [])
|
||||
{
|
||||
// remove all keys from the input data
|
||||
$this->types = array_values($type);
|
||||
$this->thirdPartyTypes = array_values($type);
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$child->setTypes($type);
|
||||
$child->setThirdPartyTypes($type);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@ -814,7 +813,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
||||
public function setTypesAndCategories(array $typesAndCategories): self
|
||||
{
|
||||
$types = array_filter($typesAndCategories, static fn ($item) => !$item instanceof ThirdPartyCategory);
|
||||
$this->setTypes($types);
|
||||
$this->setThirdPartyTypes($types);
|
||||
|
||||
// handle categories
|
||||
foreach ($typesAndCategories as $t) {
|
||||
|
@ -134,15 +134,6 @@ class ThirdPartyType extends AbstractType
|
||||
// Institutional ThirdParty (parent)
|
||||
} else {
|
||||
$builder
|
||||
->add('address', PickAddressType::class, [
|
||||
'label' => 'Address',
|
||||
])
|
||||
->add('address2', PickAddressType::class, [
|
||||
'label' => 'Address',
|
||||
'use_valid_from' => true,
|
||||
'use_valid_to' => true,
|
||||
'mapped' => false,
|
||||
])
|
||||
->add('nameCompany', TextType::class, [
|
||||
'label' => 'thirdparty.NameCompany',
|
||||
'required' => false,
|
||||
@ -170,6 +161,9 @@ class ThirdPartyType extends AbstractType
|
||||
|
||||
if (ThirdParty::KIND_CHILD !== $options['kind']) {
|
||||
$builder
|
||||
->add('address', PickAddressType::class, [
|
||||
'label' => 'Address',
|
||||
])
|
||||
->add('typesAndCategories', PickThirdPartyTypeCategoryType::class, [
|
||||
'label' => 'thirdparty.Categories',
|
||||
])
|
||||
|
@ -26,17 +26,19 @@
|
||||
<div class="form-check">
|
||||
<input class="form-check-input mt-0" type="radio" v-model="kind" value="company" id="tpartyKindInstitution">
|
||||
<label for="tpartyKindInstitution" class="required">
|
||||
<span class="badge rounded-pill bg-thirdparty-company" style="padding-top: 0;">
|
||||
{{ $t('tparty.company')}}
|
||||
</span>
|
||||
<badge-entity
|
||||
:entity="{ type: 'thirdparty', kind: 'company' }"
|
||||
:options="{ displayLong: true }">
|
||||
</badge-entity>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input mt-0" type="radio" v-model="kind" value="contact" id="tpartyKindContact">
|
||||
<label for="tpartyKindContact" class="required">
|
||||
<span class="badge rounded-pill bg-thirdparty-contact" style="padding-top: 0;">
|
||||
{{ $t('tparty.contact')}}
|
||||
</span>
|
||||
<badge-entity
|
||||
:entity="{ type: 'thirdparty', kind: 'contact' }"
|
||||
:options="{ displayLong: true }">
|
||||
</badge-entity>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -97,26 +99,16 @@
|
||||
import ThirdPartyRenderBox from '../Entity/ThirdPartyRenderBox.vue';
|
||||
import AddAddress from 'ChillMainAssets/vuejs/Address/components/AddAddress';
|
||||
import { getThirdparty } from '../../_api/OnTheFly';
|
||||
|
||||
const i18n = {
|
||||
messages: {
|
||||
fr: {
|
||||
tparty: {
|
||||
contact: "Personne physique",
|
||||
company: "Personne morale"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||
|
||||
export default {
|
||||
name: "OnTheFlyThirdParty",
|
||||
props: ['id', 'type', 'action'],
|
||||
components: {
|
||||
ThirdPartyRenderBox,
|
||||
AddAddress
|
||||
AddAddress,
|
||||
BadgeEntity
|
||||
},
|
||||
i18n,
|
||||
data() {
|
||||
return {
|
||||
//context: {}, <--
|
||||
|
@ -28,7 +28,9 @@
|
||||
{{ form_widget(form.activeChildren) }}
|
||||
{% endif %}
|
||||
|
||||
{{ form_row(form.address) }}
|
||||
{% if form.address is defined %}
|
||||
{{ form_row(form.address) }}
|
||||
{% endif %}
|
||||
|
||||
{{ form_row(form.comment) }}
|
||||
|
||||
|
@ -62,7 +62,3 @@
|
||||
{% endblock %}
|
||||
{% endembed %}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('page_3party_3party_index') }}
|
||||
{% endblock %}
|
||||
|
@ -12,7 +12,7 @@
|
||||
{% block crud_content_header %}
|
||||
<h1>
|
||||
{{ 'Update third party %name%'|trans({ '%name%': thirdParty.name }) }}
|
||||
<span class="badge bg-{{ thirdParty.active ? 'success' : 'danger' }}"
|
||||
<span class="badge bg-{{ thirdParty.active ? 'success' : 'danger' }} float-end"
|
||||
title="{{ (thirdParty.active ? 'shown to users' : 'not shown to users')|trans }}">
|
||||
{{ (thirdParty.active ? 'Active' : 'Inactive')|trans }}
|
||||
</span>
|
||||
|
@ -35,8 +35,8 @@ final class ThirdPartyTest extends TestCase
|
||||
$this->assertTrue($tp->getCategories()->contains($cat2));
|
||||
$this->assertCount(2, $tp->getCategories());
|
||||
|
||||
$this->assertCount(1, $tp->getTypes());
|
||||
$this->assertContains('type', $tp->getTypes());
|
||||
$this->assertCount(1, $tp->getThirdPartyTypes());
|
||||
$this->assertContains('type', $tp->getThirdPartyTypes());
|
||||
|
||||
$this->assertCount(3, $tp->getTypesAndCategories());
|
||||
$this->assertContains($cat1, $tp->getTypesAndCategories());
|
||||
@ -54,8 +54,8 @@ final class ThirdPartyTest extends TestCase
|
||||
$this->assertFalse($tp->getCategories()->contains($cat2));
|
||||
$this->assertCount(1, $tp->getCategories());
|
||||
|
||||
$this->assertCount(0, $tp->getTypes());
|
||||
$this->assertNotContains('type', $tp->getTypes());
|
||||
$this->assertCount(0, $tp->getThirdPartyTypes());
|
||||
$this->assertNotContains('type', $tp->getThirdPartyTypes());
|
||||
|
||||
$this->assertCount(1, $tp->getTypesAndCategories());
|
||||
$this->assertContains($cat1, $tp->getTypesAndCategories());
|
||||
@ -77,9 +77,9 @@ final class ThirdPartyTest extends TestCase
|
||||
$this->assertTrue($tp->getCategories()->contains($cat2));
|
||||
$this->assertCount(2, $tp->getCategories());
|
||||
|
||||
$this->assertCount(2, $tp->getTypes());
|
||||
$this->assertContains('type1', $tp->getTypes());
|
||||
$this->assertContains('type2', $tp->getTypes());
|
||||
$this->assertCount(2, $tp->getThirdPartyTypes());
|
||||
$this->assertContains('type1', $tp->getThirdPartyTypes());
|
||||
$this->assertContains('type2', $tp->getThirdPartyTypes());
|
||||
|
||||
$this->assertCount(4, $tp->getTypesAndCategories());
|
||||
$this->assertContains($cat1, $tp->getTypesAndCategories());
|
||||
@ -93,9 +93,9 @@ final class ThirdPartyTest extends TestCase
|
||||
$this->assertFalse($tp->getCategories()->contains($cat2));
|
||||
$this->assertCount(1, $tp->getCategories());
|
||||
|
||||
$this->assertCount(1, $tp->getTypes());
|
||||
$this->assertContains('type1', $tp->getTypes());
|
||||
$this->assertNotContains('type2', $tp->getTypes());
|
||||
$this->assertCount(1, $tp->getThirdPartyTypes());
|
||||
$this->assertContains('type1', $tp->getThirdPartyTypes());
|
||||
$this->assertNotContains('type2', $tp->getThirdPartyTypes());
|
||||
|
||||
$this->assertCount(2, $tp->getTypesAndCategories());
|
||||
$this->assertContains($cat1, $tp->getTypesAndCategories());
|
||||
|
@ -0,0 +1,54 @@
|
||||
<?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\ThirdPartyBundle\Test\Serializer\Normalizer;
|
||||
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
final class ThirdPartyJsonDenormalizerTest extends KernelTestCase
|
||||
{
|
||||
private DenormalizerInterface $normalizer;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
self::bootKernel();
|
||||
|
||||
$this->normalizer = self::$container->get(DenormalizerInterface::class);
|
||||
}
|
||||
|
||||
public function testDenormalizeContact()
|
||||
{
|
||||
$str = <<<'JSON'
|
||||
{
|
||||
"type": "thirdparty",
|
||||
"name": "badaboum",
|
||||
"email": "badaboum@email.com",
|
||||
"telephone": "+32486540660",
|
||||
"kind": "contact"
|
||||
}
|
||||
JSON;
|
||||
|
||||
$actual = $this->normalizer->denormalize(json_decode($str, true), ThirdParty::class, 'json', [
|
||||
'groups' => ['write'],
|
||||
]);
|
||||
|
||||
$this->assertInstanceOf(ThirdParty::class, $actual);
|
||||
$this->assertEquals('badaboum', $actual->getName());
|
||||
$this->assertEquals('badaboum@email.com', $actual->getEmail());
|
||||
$this->assertEquals(ThirdParty::KIND_CONTACT, $actual->getKind());
|
||||
}
|
||||
}
|
@ -44,8 +44,6 @@ final class ThirdpartyDocGenNormalizerTest extends KernelTestCase
|
||||
|
||||
$actual = $this->normalizer->normalize($thirdparty, 'docgen', ['groups' => ['docgen:read']]);
|
||||
|
||||
var_dump($actual);
|
||||
|
||||
$this->assertIsArray($actual);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user