mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-23 08:03:49 +00:00
Merge remote-tracking branch 'origin/master' into issue469_budget
This commit is contained in:
@@ -33,61 +33,74 @@ div.banner {
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
div.contact {
|
||||
display: flex;
|
||||
align-content: center;
|
||||
& > * {
|
||||
margin-right: 1em;
|
||||
}
|
||||
}
|
||||
.household-link {
|
||||
border: 1px solid white;
|
||||
padding: .05rem .3rem;
|
||||
border-radius: 5px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: white;
|
||||
color: $chill-person-context
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.person-view {
|
||||
figure.person-details {
|
||||
h2 {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.3em;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
dl {
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
dt {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: 600;
|
||||
}
|
||||
dd {
|
||||
margin-left: 0;
|
||||
}
|
||||
/*
|
||||
a.sc-button { background-color: $black; padding-top: 0.2em; padding-bottom: 0.2em; }
|
||||
*/
|
||||
}
|
||||
/* custom fields on the home page */
|
||||
div.custom-fields {
|
||||
figure.person-details {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
div.cf_title_box:nth-child(4n+1) h2 {
|
||||
@extend .chill-red !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+2) h2 {
|
||||
@extend .chill-green !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+3) h2 {
|
||||
@extend .chill-orange !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+4) h2 {
|
||||
@extend .chill-blue !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(2n+1) {
|
||||
width: 50%;
|
||||
margin-right: 40px;
|
||||
}
|
||||
div.cf_title_box:nth-child(2n+2) {
|
||||
width: calc(50% - 40px);
|
||||
}
|
||||
}
|
||||
}
|
||||
figure.person-details {
|
||||
h2 {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.3em;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
dl {
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
dt {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: 600;
|
||||
}
|
||||
dd {
|
||||
margin-left: 0;
|
||||
}
|
||||
/*
|
||||
a.sc-button { background-color: $black; padding-top: 0.2em; padding-bottom: 0.2em; }
|
||||
*/
|
||||
}
|
||||
/* custom fields on the home page */
|
||||
div.custom-fields {
|
||||
figure.person-details {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
div.cf_title_box:nth-child(4n+1) h2 {
|
||||
@extend .chill-red !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+2) h2 {
|
||||
@extend .chill-green !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+3) h2 {
|
||||
@extend .chill-orange !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(4n+4) h2 {
|
||||
@extend .chill-blue !optional;
|
||||
}
|
||||
div.cf_title_box:nth-child(2n+1) {
|
||||
width: 50%;
|
||||
margin-right: 40px;
|
||||
}
|
||||
div.cf_title_box:nth-child(2n+2) {
|
||||
width: calc(50% - 40px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -19,22 +19,21 @@ import {fetchResults} from 'ChillMainAssets/lib/api/apiMethods.js';
|
||||
*/
|
||||
|
||||
document.querySelectorAll('[data-set-referrer-app]').forEach(function (el) {
|
||||
let
|
||||
periodId = Number.parseInt(el.dataset.setReferrerAccompanyingPeriodId);
|
||||
|
||||
const periodId = Number.parseInt(el.dataset.setReferrerAccompanyingPeriodId);
|
||||
const jobId = Number.parseInt(el.dataset.setReferrerJobId);
|
||||
const url = `/api/1.0/person/accompanying-course/${periodId}/referrers-suggested.json`;
|
||||
|
||||
fetchResults(url).then(suggested => {
|
||||
|
||||
const filteredSuggested = suggested.filter((s) => s.user_job ? s.user_job.id === jobId : false);
|
||||
const app = createApp({
|
||||
components: {
|
||||
SetReferrer,
|
||||
},
|
||||
template:
|
||||
'<set-referrer :suggested="suggested" :periodId="periodId" @referrerSet="onReferrerSet"></set-referrer>',
|
||||
'<set-referrer :suggested="filteredSuggested" :periodId="periodId" @referrerSet="onReferrerSet"></set-referrer>',
|
||||
data() {
|
||||
return {
|
||||
periodId, suggested, original: suggested,
|
||||
periodId, filteredSuggested, original: filteredSuggested,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -56,7 +55,7 @@ document.querySelectorAll('[data-set-referrer-app]').forEach(function (el) {
|
||||
label.textContent = ref.text;
|
||||
label.classList.remove('chill-no-data-statement');
|
||||
|
||||
this.suggested = this.original.filter(user => user.id !== ref.id);
|
||||
this.filteredSuggested = this.original.filter(user => user.id !== ref.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -14,24 +14,27 @@
|
||||
|
||||
<ckeditor
|
||||
name="content"
|
||||
v-bind:placeholder="$t('comment.content')"
|
||||
:placeholder="$t('comment.content')"
|
||||
:editor="editor"
|
||||
v-model="content"
|
||||
tag-name="textarea">
|
||||
</ckeditor>
|
||||
|
||||
<div v-if="pinnedComment" class="metadata">
|
||||
{{ $t('comment.created_by', [
|
||||
pinnedComment.creator.text,
|
||||
$d(pinnedComment.createdAt.datetime, 'long')
|
||||
]) }}
|
||||
<div class="sub-comment">
|
||||
<div v-if="pinnedComment !== null && typeof pinnedComment.creator !== 'undefined'" class="metadata">
|
||||
{{ $t('comment.created_by', [
|
||||
pinnedComment.creator.text,
|
||||
$d(pinnedComment.updatedAt.datetime, 'long')
|
||||
])
|
||||
}}
|
||||
</div>
|
||||
<div class="loading">
|
||||
<i v-if="loading" class="fa fa-circle-o-notch fa-spin" :title="$t('loading')"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button type="submit" class="btn btn-save">{{ $t('action.save') }}</button>
|
||||
</li>
|
||||
<li v-if="pinnedComment !== null">
|
||||
<a class="btn btn-delete"
|
||||
@click="removeComment">
|
||||
@@ -50,6 +53,7 @@
|
||||
<script>
|
||||
import CKEditor from '@ckeditor/ckeditor5-vue';
|
||||
import ClassicEditor from "ChillMainAssets/module/ckeditor5";
|
||||
import { mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "Comment",
|
||||
@@ -59,22 +63,58 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
editor: ClassicEditor,
|
||||
formdata: {
|
||||
type: "accompanying_period_comment",
|
||||
content: ''
|
||||
}
|
||||
loading: false,
|
||||
lastRecordedContent: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pinnedComment() {
|
||||
return this.$store.state.accompanyingCourse.pinnedComment;
|
||||
},
|
||||
...mapState({
|
||||
pinnedComment: state => state.accompanyingCourse.pinnedComment,
|
||||
}),
|
||||
content: {
|
||||
set(value) {
|
||||
this.formdata.content = value;
|
||||
console.log('new comment value', value);
|
||||
console.log('previous value', this.lastRecordedContent);
|
||||
this.lastRecordedContent = value;
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('performing test on ', value);
|
||||
if (this.lastRecordedContent === value) {
|
||||
this.loading = true;
|
||||
if (value !== '') {
|
||||
this.$store.dispatch('updatePinnedComment', value)
|
||||
.then(() => {
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
} else {
|
||||
this.$toast.open({message: 'An error occurred'})
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (this.$store.state.accompanyingCourse.pinnedComment !== null) {
|
||||
this.$store.dispatch('removePinnedComment', {id: this.pinnedComment.id})
|
||||
.then(() => {
|
||||
this.loading = false;
|
||||
this.lastRecoredContent = null;
|
||||
})
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
} else {
|
||||
this.$toast.open({message: 'An error occurred'})
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
},
|
||||
get() {
|
||||
return (this.pinnedComment)? this.pinnedComment.content : {};
|
||||
get() {
|
||||
return this.pinnedComment ? this.pinnedComment.content : '';
|
||||
}
|
||||
},
|
||||
errors() {
|
||||
@@ -82,18 +122,11 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitform() {
|
||||
this.$store.dispatch('postFirstComment', this.formdata)
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
} else {
|
||||
this.$toast.open({message: 'An error occurred'})
|
||||
}
|
||||
});
|
||||
onContentChange() {
|
||||
let lastRecordedContent = this.formData.content;
|
||||
},
|
||||
removeComment() {
|
||||
this.$store.dispatch('postFirstComment', {})
|
||||
this.$store.dispatch('removePinnedComment', {id: this.pinnedComment.id})
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
@@ -104,15 +137,18 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* TODO
|
||||
* - [x] delete button in ul record_actions, but not in form
|
||||
* - [ ] display updatedAt => pinnedComment fetch PATCH content changes MUST NOT change object id !!
|
||||
*/
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
div.ck-editor.ck-reset {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
div.sub-comment {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
div.loading {
|
||||
margin-right: 6px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -59,14 +59,6 @@
|
||||
ref="addAddress">
|
||||
</add-address>
|
||||
</li>
|
||||
<li v-if="isPersonLocation">
|
||||
<button
|
||||
class="btn btn-remove"
|
||||
@click="removeAddress"
|
||||
:title="$t('courselocation.remove_button')">
|
||||
{{ $t('action.remove') }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -180,22 +172,6 @@ export default {
|
||||
}
|
||||
this.$store.commit('setAddressContext', context);
|
||||
},
|
||||
removeAddress() {
|
||||
let payload = {
|
||||
target: this.context.target.name,
|
||||
targetId: this.context.target.id,
|
||||
locationStatusTo: 'none'
|
||||
};
|
||||
//console.log('remove address');
|
||||
this.$store.dispatch('updateLocation', payload)
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
} else {
|
||||
this.$toast.open({message: 'An error occurred'})
|
||||
}
|
||||
});
|
||||
},
|
||||
displayErrors() {
|
||||
return this.$refs.addAddress.errorMsg;
|
||||
},
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<input type="checkbox" v-model="requestorIsAnonymous" class="me-2" />
|
||||
{{ $t('requestor.is_anonymous') }}
|
||||
</label>
|
||||
<confidential :positionBtn="false" v-if="accompanyingCourse.requestor.type === 'thirdparty'">
|
||||
<confidential v-if="accompanyingCourse.requestor.type === 'thirdparty'">
|
||||
<template v-slot:confidential-content>
|
||||
<third-party-render-box
|
||||
:thirdparty="accompanyingCourse.requestor"
|
||||
@@ -33,7 +33,7 @@
|
||||
</template>
|
||||
</confidential>
|
||||
|
||||
<confidential :positionBtnFar="false" v-else-if="accompanyingCourse.requestor.type === 'person'">
|
||||
<confidential v-else-if="accompanyingCourse.requestor.type === 'person'">
|
||||
<template v-slot:confidential-content>
|
||||
<person-render-box render="bloc"
|
||||
:person="accompanyingCourse.requestor"
|
||||
@@ -339,5 +339,6 @@ div.flex-table {
|
||||
|
||||
.confidential {
|
||||
display: block;
|
||||
margin-right: 0px !important;
|
||||
}
|
||||
</style>
|
||||
|
@@ -170,7 +170,9 @@ export default {
|
||||
console.log('data', payload.data)
|
||||
body.name = payload.data.name;
|
||||
body.email = payload.data.email;
|
||||
body.telephone = payload.data.phonenumber;
|
||||
body.telephone = payload.data.telephone;
|
||||
body.civility = payload.data.civility;
|
||||
body.profession = payload.data.profession;
|
||||
body.address = payload.data.address ? { id: payload.data.address.address_id } : null;
|
||||
|
||||
makeFetch('PATCH', `/api/1.0/thirdparty/thirdparty/${payload.data.id}.json`, body)
|
||||
|
@@ -122,7 +122,7 @@ const appMessages = {
|
||||
title: "Observations",
|
||||
label: "Ajout d'une note",
|
||||
content: "Rédigez une première note…",
|
||||
created_by: "créé par {0}, le {1}"
|
||||
created_by: "créé par {0}, mis à jour le {1}"
|
||||
},
|
||||
confirm: {
|
||||
title: "Confirmation",
|
||||
|
@@ -42,7 +42,11 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
|
||||
referrersSuggested: [],
|
||||
// all the users available
|
||||
users: [],
|
||||
permissions: {}
|
||||
permissions: {},
|
||||
// controller for updating comment
|
||||
updateCommentAbortController: null,
|
||||
// waiting response for inserting first comment
|
||||
postFirstPinnedCommentResponse: null,
|
||||
},
|
||||
getters: {
|
||||
isParticipationValid(state) {
|
||||
@@ -203,9 +207,35 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
|
||||
//console.log('### mutation: toggleConfidential');
|
||||
state.accompanyingCourse.confidential = value;
|
||||
},
|
||||
postFirstComment(state, comment) {
|
||||
//console.log('### mutation: postFirstComment', comment);
|
||||
state.accompanyingCourse.pinnedComment = comment;
|
||||
setPinnedComment(state, content) {
|
||||
if (null === state.accompanyingCourse.pinnedComment) {
|
||||
state.accompanyingCourse.pinnedComment = {
|
||||
id: -1,
|
||||
content,
|
||||
type: "accompanying_period_comment",
|
||||
};
|
||||
} else {
|
||||
state.accompanyingCourse.pinnedComment.content = content;
|
||||
}
|
||||
},
|
||||
setPinnedCommentDetails(state, value) {
|
||||
state.accompanyingCourse.pinnedComment.id = value.id;
|
||||
if (typeof value.creator !== 'undefined') {
|
||||
state.accompanyingCourse.pinnedComment.creator = value.creator;
|
||||
state.accompanyingCourse.pinnedComment.updatedBy = value.updatedBy;
|
||||
state.accompanyingCourse.pinnedComment.updatedAt = value.updatedAt;
|
||||
state.accompanyingCourse.pinnedComment.createdAt = value.createdAt;
|
||||
|
||||
}
|
||||
},
|
||||
removePinnedComment(state, value) {
|
||||
state.accompanyingCourse.pinnedComment = null;
|
||||
},
|
||||
setPinCommentAbortController(state, value) {
|
||||
state.updateCommentAbortController = value;
|
||||
},
|
||||
setPostFirstPinnedCommentResponse(state, value) {
|
||||
state.postFirstPinnedCommentResponse = value;
|
||||
},
|
||||
updateSocialIssues(state, value) {
|
||||
console.log('updateSocialIssues', value);
|
||||
@@ -337,6 +367,87 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Add/remove pinnedComment
|
||||
*/
|
||||
removePinnedComment({ commit }, payload) {
|
||||
const body = {type: "accompanying_period_comment", id: payload.id};
|
||||
const url = `/api/1.0/person/accompanying-course/${id}/comment.json`;
|
||||
|
||||
return makeFetch('DELETE', url, body)
|
||||
.then((response) => {
|
||||
commit('removePinnedComment');
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* internal method to insert a new comment
|
||||
*
|
||||
* @param commit
|
||||
* @param dispatch
|
||||
* @param content
|
||||
* @returns {*}
|
||||
*/
|
||||
addPinnedComment({ commit, dispatch }, content) {
|
||||
const url = `/api/1.0/person/accompanying-course/${id}/comment.json`;
|
||||
|
||||
return makeFetch('POST', url, {type: "accompanying_period_comment", content})
|
||||
.then((response) => {
|
||||
commit('setPinnedCommentDetails', response);
|
||||
return dispatch('patchFirstComment', response);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
updatePinnedComment({ commit, state, dispatch }, content) {
|
||||
commit('setPinnedComment', content);
|
||||
if (state.accompanyingCourse.pinnedComment.id === -1 && state.postFirstPinnedCommentResponse === null) {
|
||||
let r = dispatch('addPinnedComment', content).then(() => {
|
||||
commit('setPostFirstPinnedCommentResponse', null);
|
||||
});
|
||||
commit('setPostFirstPinnedCommentResponse', r);
|
||||
} else {
|
||||
(state.postFirstPinnedCommentResponse === null ? Promise.resolve() : state.postFirstPinnedCommentResponse).then(() => {
|
||||
dispatch('updateExistingPinnedComment', content);
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* internal method to patch an existing comment
|
||||
*
|
||||
* @param commit
|
||||
* @param state
|
||||
* @param comment
|
||||
* @returns {*}
|
||||
*/
|
||||
updateExistingPinnedComment({ commit, state }, content) {
|
||||
const payload = {type: "accompanying_period_comment", content, id: state.accompanyingCourse.pinnedComment.id};
|
||||
const url = `/api/1.0/person/accompanying-period/comment/${payload.id}.json`;
|
||||
|
||||
if (state.updateCommentAbortController !== null) {
|
||||
state.updateCommentAbortController.abort();
|
||||
commit('setPinCommentAbortController', null);
|
||||
}
|
||||
|
||||
let controller = new AbortController();
|
||||
commit('setPinCommentAbortController', controller);
|
||||
|
||||
return makeFetch('PATCH', url, payload, { signal: controller.signal })
|
||||
.then((response) => {
|
||||
commit('setPinCommentAbortController', null);
|
||||
commit('setPinnedCommentDetails', response);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
commit('setPinCommentAbortController', null);
|
||||
throw error;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Add/remove/display anonymous requestor
|
||||
*/
|
||||
@@ -606,18 +717,20 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
|
||||
|
||||
return Promise.all(promises);
|
||||
},
|
||||
postFirstComment({ commit }, payload) {
|
||||
const url = `/api/1.0/person/accompanying-course/${id}.json`
|
||||
const body = { type: "accompanying_period", pinnedComment: payload }
|
||||
|
||||
patchFirstComment({ commit }, payload) {
|
||||
const url = `/api/1.0/person/accompanying-course/${id}.json`;
|
||||
const body = {
|
||||
type: "accompanying_period",
|
||||
pinnedComment: {
|
||||
type: "accompanying_period_comment",
|
||||
id: payload.id
|
||||
}
|
||||
};
|
||||
return makeFetch('PATCH', url, body)
|
||||
.then((response) => {
|
||||
commit('postFirstComment', response.pinnedComment);
|
||||
})
|
||||
.catch((error) => {
|
||||
commit('catchError', error);
|
||||
throw error;
|
||||
})
|
||||
});
|
||||
},
|
||||
updateSocialIssues({ state, commit, dispatch }, { payload, body, method }) {
|
||||
const url = `/api/1.0/person/accompanying-course/${id}/socialissue.json`;
|
||||
|
@@ -127,7 +127,7 @@
|
||||
</div>
|
||||
<ul class="record_actions" v-if="evaluationsForAction.length > 0">
|
||||
<li>
|
||||
<button :title="$t('add_an_evaluation')" class="btn btn-create" @click="toggleAddEvaluation"></button>
|
||||
<button :title="$t('add_an_evaluation')" class="btn btn-create" @click="toggleAddEvaluation">{{ $t('add_an_evaluation') }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else>
|
||||
@@ -151,6 +151,37 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="referrers" class="action-row">
|
||||
<h3>{{ $t('referrers') }}</h3>
|
||||
|
||||
<div v-if="!hasReferrers">
|
||||
<p class="chill-no-data-statement">{{ $t('no_referrers') }}</p>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<ul class="list-suggest remove-items inline">
|
||||
<li v-for="u in referrers" :key="u.id" :title="$t('remove_referrer')" @click="removeReferrer(u)">
|
||||
<span>
|
||||
{{ u.text }}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<ul class="record_actions">
|
||||
<li class="add-persons">
|
||||
<add-persons
|
||||
ref="referrerPicker"
|
||||
:key="referrerPicker.key"
|
||||
:buttonTitle="$t('add_referrers')"
|
||||
:modalTitle="$t('choose_referrers')"
|
||||
:options="referrerPicker.options"
|
||||
@addNewPersons="addReferrers">
|
||||
</add-persons>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="handlingThirdParty" class="action-row">
|
||||
<h3>{{ $t('handling_thirdparty') }}</h3>
|
||||
|
||||
@@ -289,7 +320,6 @@ import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vu
|
||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
||||
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
|
||||
|
||||
|
||||
const i18n = {
|
||||
messages: {
|
||||
fr: {
|
||||
@@ -319,9 +349,13 @@ const i18n = {
|
||||
add_thirdparties: "Ajouter des tiers",
|
||||
choose_thirdparties: "Choisir des tiers",
|
||||
fix_these_errors: "Veuillez corriger les erreurs suivantes :",
|
||||
available_evaluations_text: "Évaluations disponibles pour ajout :",
|
||||
available_evaluations_text: "Documents disponibles pour ajout :",
|
||||
no_evaluations_available: "Aucune évaluation disponible",
|
||||
no_goals_available: "Aucun objectif disponible",
|
||||
referrers: "Agents traitants",
|
||||
no_referrers: "Aucun agent traitant",
|
||||
choose_referrers: "Choisir des agents traitants",
|
||||
remove_referrer: "Enlever l'agent"
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -370,6 +404,17 @@ export default {
|
||||
}
|
||||
},
|
||||
},
|
||||
referrerPicker: {
|
||||
key: 'referrer',
|
||||
options: {
|
||||
type: ['user'],
|
||||
priority: null,
|
||||
uniq: false,
|
||||
button: {
|
||||
display: false
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -381,6 +426,7 @@ export default {
|
||||
'personsReachables',
|
||||
'handlingThirdParty',
|
||||
'thirdParties',
|
||||
'referrers',
|
||||
'isPosting',
|
||||
'errors',
|
||||
'templatesAvailablesForAction',
|
||||
@@ -389,6 +435,7 @@ export default {
|
||||
'hasResultsForAction',
|
||||
'hasHandlingThirdParty',
|
||||
'hasThirdParties',
|
||||
'hasReferrers'
|
||||
]),
|
||||
startDate: {
|
||||
get() {
|
||||
@@ -465,6 +512,14 @@ export default {
|
||||
removeThirdParty(t) {
|
||||
this.$store.commit('removeThirdParty', t);
|
||||
},
|
||||
addReferrers({selected, modal}) {
|
||||
this.$store.commit('addReferrers', selected.map(r => r.result));
|
||||
this.$refs.referrerPicker.resetSearch();
|
||||
modal.showModal = false;
|
||||
},
|
||||
removeReferrer(u) {
|
||||
this.$store.commit('removeReferrer', u);
|
||||
},
|
||||
goToGenerateWorkflow({link}) {
|
||||
console.log('save before leave to generate workflow')
|
||||
const callback = (data) => {
|
||||
@@ -521,6 +576,7 @@ div#workEditor {
|
||||
"objectives objectives"
|
||||
"evaluations evaluations"
|
||||
"persons persons"
|
||||
"referrers referrers"
|
||||
"handling handling"
|
||||
"tparties tparties"
|
||||
"errors errors";
|
||||
@@ -543,6 +599,8 @@ div#workEditor {
|
||||
grid-area: handling; }
|
||||
#thirdParties {
|
||||
grid-area: tparties; }
|
||||
#referrers {
|
||||
grid-area: referrers; }
|
||||
#errors {
|
||||
grid-area: errors; }
|
||||
|
||||
@@ -657,5 +715,4 @@ div#workEditor {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
@@ -5,6 +5,11 @@
|
||||
<span>{{ evaluation.evaluation.title.fr }}</span>
|
||||
</div>
|
||||
|
||||
<div class="item-url mt-3 mb-4" v-if="evaluation.evaluation.url">
|
||||
<i class="fa fa-link fa-lg"></i>
|
||||
<a :href="evaluation.evaluation.url" target="_blank">{{ evaluation.evaluation.url }}</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<form-evaluation ref="FormEvaluation" :key="evaluation.key" :evaluation="evaluation"></form-evaluation>
|
||||
|
||||
@@ -21,8 +26,8 @@
|
||||
></list-workflow-modal>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-delete" @click="modal.showModal = true" :title="$t('action.delete')"></a>
|
||||
<li v-if="canDelete">
|
||||
<a class="btn btn-delete" @click="modal.showModal = true" :title="$t('action.delete')">{{ $t('delete_evaluation')}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -67,7 +72,8 @@ const i18n = {
|
||||
sure: "Êtes-vous sûr?",
|
||||
sure_description: "Cette évaluation sera supprimée de cette action d'accompagnement",
|
||||
ok: "Supprimer"
|
||||
}
|
||||
},
|
||||
delete_evaluation: "Supprimer l'évaluation",
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -93,6 +99,19 @@ export default {
|
||||
pickedEvaluations() {
|
||||
return this.$store.state.evaluationsPicked;
|
||||
},
|
||||
canDelete() {
|
||||
if (this.evaluation.workflows.length > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let doc of this.evaluation.documents) {
|
||||
if (doc.workflows.length > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
removeEvaluation(e) {
|
||||
@@ -128,4 +147,11 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
div.item-url {
|
||||
i {
|
||||
color: unset!important;
|
||||
margin-left: 1rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -65,16 +65,17 @@
|
||||
<h5>{{ $t('Documents') }} :</h5>
|
||||
|
||||
<div class="flex-table">
|
||||
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.key">
|
||||
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.id">
|
||||
<div class="item-row">
|
||||
<div class="input-group input-group-lg mb-3">
|
||||
<div>
|
||||
<input
|
||||
class="form-control form-control-lg"
|
||||
class="form-control"
|
||||
style="font-weight: bold;"
|
||||
type="text"
|
||||
:value="d.title"
|
||||
:id="d.id"
|
||||
:data-key="i"
|
||||
@input="onInputDocumentTitle"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -84,6 +85,8 @@
|
||||
<p v-if="d.createdBy" class="createdBy">Créé par {{ d.createdBy.text }}<br/>
|
||||
Le {{ $d(ISOToDatetime(d.createdAt.datetime), 'long') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-row">
|
||||
<div class="item-col">
|
||||
<ul class="record_actions" >
|
||||
<li v-if="d.workflows_availables.length > 0">
|
||||
@@ -99,9 +102,26 @@
|
||||
></list-workflow-modal>
|
||||
</li>
|
||||
<li>
|
||||
<a :href="buildEditLink(d.storedObject)" class="btn btn-wopilink"></a>
|
||||
<add-async-upload
|
||||
:buttonTitle="$t('replace')"
|
||||
:options="asyncUploadOptions"
|
||||
:btnClasses="{'btn': true, 'btn-edit': true}"
|
||||
@addDocument="(arg) => replaceDocument(d, arg)"
|
||||
>
|
||||
</add-async-upload>
|
||||
</li>
|
||||
<li>
|
||||
<add-async-upload-downloader
|
||||
:buttonTitle="$t('download')"
|
||||
:storedObject="d.storedObject"
|
||||
>
|
||||
</add-async-upload-downloader>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<a :href="buildEditLink(d.storedObject)" class="btn btn-wopilink"></a>
|
||||
</li>
|
||||
<li v-if="d.workflows.length === 0">
|
||||
<a class="btn btn-delete" @click="removeDocument(d)">
|
||||
</a>
|
||||
</li>
|
||||
@@ -152,6 +172,7 @@ import { mapGetters, mapState } from 'vuex';
|
||||
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
|
||||
import {buildLink} from 'ChillDocGeneratorAssets/lib/document-generator';
|
||||
import AddAsyncUpload from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUpload.vue';
|
||||
import AddAsyncUploadDownloader from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUploadDownloader.vue';
|
||||
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue';
|
||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
||||
|
||||
@@ -176,7 +197,9 @@ const i18n = {
|
||||
document_upload: "Téléverser un document",
|
||||
document_title: "Titre du document",
|
||||
template_title: "Nom du template",
|
||||
browse: "Ajouter un document"
|
||||
browse: "Ajouter un document",
|
||||
replace: "Remplacer",
|
||||
download: "Télécharger le fichier existant"
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -188,6 +211,7 @@ export default {
|
||||
ckeditor: CKEditor.component,
|
||||
PickTemplate,
|
||||
AddAsyncUpload,
|
||||
AddAsyncUploadDownloader,
|
||||
ListWorkflowModal,
|
||||
},
|
||||
i18n,
|
||||
@@ -274,8 +298,9 @@ export default {
|
||||
},
|
||||
onInputDocumentTitle(event) {
|
||||
const id = Number(event.target.id);
|
||||
const key = Number(event.target.dataset.key) + 1;
|
||||
const title = event.target.value;
|
||||
this.$store.commit('updateDocumentTitle', {id: id, evaluationKey: this.evaluation.key, title: title});
|
||||
this.$store.commit('updateDocumentTitle', {id: id, key: key, evaluationKey: this.evaluation.key, title: title});
|
||||
},
|
||||
addDocument(storedObject) {
|
||||
let document = {
|
||||
@@ -285,6 +310,14 @@ export default {
|
||||
};
|
||||
this.$store.commit('addDocument', {key: this.evaluation.key, document: document});
|
||||
},
|
||||
replaceDocument(oldDocument, storedObject) {
|
||||
let document = {
|
||||
type: 'accompanying_period_work_evaluation_document',
|
||||
storedObject: storedObject,
|
||||
title: oldDocument.title
|
||||
};
|
||||
this.$store.commit('replaceDocument', {key: this.evaluation.key, document: document, oldDocument: oldDocument});
|
||||
},
|
||||
removeDocument(document) {
|
||||
if (window.confirm("Êtes-vous sûr·e de vouloir supprimer le document qui a pour titre \"" + document.title +"\" ?")) {
|
||||
this.$store.commit('removeDocument', {key: this.evaluation.key, document: document});
|
||||
|
@@ -31,6 +31,7 @@ const store = createStore({
|
||||
.map(p => p.person),
|
||||
handlingThirdParty: window.accompanyingCourseWork.handlingThierParty,
|
||||
thirdParties: window.accompanyingCourseWork.thirdParties,
|
||||
referrers: window.accompanyingCourseWork.referrers,
|
||||
isPosting: false,
|
||||
errors: [],
|
||||
},
|
||||
@@ -54,6 +55,9 @@ const store = createStore({
|
||||
hasHandlingThirdParty(state) {
|
||||
return state.handlingThirdParty !== null;
|
||||
},
|
||||
hasReferrers(state) {
|
||||
return state.referrers.length > 0;
|
||||
},
|
||||
hasThirdParties(state) {
|
||||
return state.thirdParties.length > 0;
|
||||
},
|
||||
@@ -82,6 +86,7 @@ const store = createStore({
|
||||
},
|
||||
results: state.resultsPicked.map(r => ({id: r.id, type: r.type})),
|
||||
thirdParties: state.thirdParties.map(t => ({id: t.id, type: t.type})),
|
||||
referrers: state.referrers.map(t => ({id: t.id, type: t.type})),
|
||||
goals: state.goalsPicked.map(g => {
|
||||
let o = {
|
||||
type: g.type,
|
||||
@@ -131,9 +136,9 @@ const store = createStore({
|
||||
endDate: e.endDate !== null ? ISOToDatetime(e.endDate.datetime) : null,
|
||||
maxDate: e.maxDate !== null ? ISOToDatetime(e.maxDate.datetime) : null,
|
||||
warningInterval: e.warningInterval !== null ? intervalISOToDays(e.warningInterval) : null,
|
||||
documents: e.documents.map((d, dindex) => {
|
||||
documents: e.documents.map((d, docIndex) => {
|
||||
return Object.assign(d, {
|
||||
key: index
|
||||
key: docIndex
|
||||
});
|
||||
}),
|
||||
});
|
||||
@@ -213,13 +218,26 @@ const store = createStore({
|
||||
}));
|
||||
},
|
||||
removeDocument(state, {key, document}) {
|
||||
let evaluations = state.evaluationsPicked.find(e => e.key === key);
|
||||
|
||||
if (evaluations === undefined) {
|
||||
let evaluation = state.evaluationsPicked.find(e => e.key === key);
|
||||
if (evaluation === undefined) {
|
||||
return;
|
||||
}
|
||||
evaluation.documents = evaluation.documents.filter(d => d.key !== document.key);
|
||||
},
|
||||
replaceDocument(state, payload) {
|
||||
let evaluation = state.evaluationsPicked.find(e => e.key === payload.key);
|
||||
if (evaluation === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
evaluations.documents = evaluations.documents.filter(d => d.key !== document.key);
|
||||
let newDocument = Object.assign(
|
||||
payload.document, {
|
||||
key: evaluation.documents.length + 1,
|
||||
workflows_availables: state.work.workflows_availables_evaluation_documents,
|
||||
workflows: [],
|
||||
}
|
||||
);
|
||||
evaluation.documents = evaluation.documents.map(d => d.id === payload.oldDocument.id ? newDocument : d);
|
||||
},
|
||||
addEvaluation(state, evaluation) {
|
||||
let e = {
|
||||
@@ -302,6 +320,18 @@ const store = createStore({
|
||||
state.thirdParties = state.thirdParties
|
||||
.filter(t => t.id !== thirdParty.id);
|
||||
},
|
||||
addReferrers(state, referrers) {
|
||||
let ids = state.referrers.map(t => t.id);
|
||||
let unexistings = referrers.filter(t => !ids.includes(t.id));
|
||||
|
||||
for (let i in unexistings) {
|
||||
state.referrers.push(unexistings[i]);
|
||||
}
|
||||
},
|
||||
removeReferrer(state, user) {
|
||||
state.referrers = state.referrers
|
||||
.filter(u => u.id !== user.id);
|
||||
},
|
||||
setErrors(state, errors) {
|
||||
state.errors = errors;
|
||||
},
|
||||
@@ -309,13 +339,17 @@ const store = createStore({
|
||||
state.isPosting = st;
|
||||
},
|
||||
updateDocumentTitle(state, payload) {
|
||||
state.evaluationsPicked.find(e => e.key === payload.evaluationKey)
|
||||
if (payload.id === 0) {
|
||||
state.evaluationsPicked.find(e => e.key === payload.evaluationKey)
|
||||
.documents.find(d => d.key === payload.key).title = payload.title;
|
||||
} else {
|
||||
state.evaluationsPicked.find(e => e.key === payload.evaluationKey)
|
||||
.documents.find(d => d.id === payload.id).title = payload.title;
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
updateThirdParty({ commit }, payload) {
|
||||
console.log(payload);
|
||||
commit('updateThirdParty', payload);
|
||||
},
|
||||
getReachablesGoalsForAction({ getters, commit, dispatch }) {
|
||||
@@ -408,6 +442,9 @@ const store = createStore({
|
||||
removeDocument({commit}, payload) {
|
||||
commit('removeDocument', payload);
|
||||
},
|
||||
replaceDocument({commit}, payload) {
|
||||
commit('replaceDocument', payload);
|
||||
},
|
||||
submit({ getters, state, commit }, callback) {
|
||||
let
|
||||
payload = getters.buildPayload,
|
||||
|
@@ -113,7 +113,18 @@
|
||||
</template>
|
||||
</modal>
|
||||
</teleport>
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
<add-persons
|
||||
buttonTitle="visgraph.add_person"
|
||||
modalTitle="visgraph.add_person"
|
||||
v-bind:key="addPersons.key"
|
||||
v-bind:options="addPersons.options"
|
||||
@addNewPersons="addNewPersons"
|
||||
ref="addPersons">
|
||||
</add-persons>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -124,12 +135,14 @@ import VueMultiselect from 'vue-multiselect'
|
||||
import { getRelationsList, postRelationship, patchRelationship, deleteRelationship } from "./api"
|
||||
import { splitId, getAge } from "./vis-network"
|
||||
import { visMessages } from "./i18n";
|
||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
components: {
|
||||
Modal,
|
||||
VueMultiselect
|
||||
VueMultiselect,
|
||||
AddPersons
|
||||
},
|
||||
props: ['household_id'],
|
||||
data() {
|
||||
@@ -159,6 +172,14 @@ export default {
|
||||
},
|
||||
canvas: null,
|
||||
link: null,
|
||||
addPersons: {
|
||||
key: 'filiation',
|
||||
options: {
|
||||
type: ['person'],
|
||||
priority: null,
|
||||
uniq: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -235,12 +256,28 @@ export default {
|
||||
this.initGraph()
|
||||
this.listenOnGraph()
|
||||
this.getRelationsList()
|
||||
console.log(this.persons);
|
||||
|
||||
this.canvas = document.getElementById('visgraph').querySelector('canvas')
|
||||
this.link = document.getElementById('exportCanvasBtn')
|
||||
},
|
||||
methods: {
|
||||
|
||||
addNewPersons({ selected, modal }) {
|
||||
// console.log('@@@ CLICK button addNewPersons', selected);
|
||||
selected.forEach(function(item) {
|
||||
this.$store.dispatch('addMorePerson', item.result)
|
||||
.catch(({name, violations}) => {
|
||||
if (name === 'ValidationException' || name === 'AccessException') {
|
||||
violations.forEach((violation) => this.$toast.open({message: violation}));
|
||||
} else {
|
||||
this.$toast.open({message: violations})
|
||||
}
|
||||
});
|
||||
}, this
|
||||
);
|
||||
this.$refs.addPersons.resetSearch(); // to cast child method
|
||||
modal.showModal = false;
|
||||
},
|
||||
initGraph() {
|
||||
this.container = document.getElementById('visgraph')
|
||||
// Instanciate vis objects in separate window variables, see vis-network.js
|
||||
|
@@ -1,5 +1,11 @@
|
||||
const visMessages = {
|
||||
fr: {
|
||||
add_persons: {
|
||||
title: "Ajouter des usagers",
|
||||
suggested_counter: "Pas de résultats | 1 résultat | {count} résultats",
|
||||
selected_counter: " 1 sélectionné | {count} sélectionnés",
|
||||
search_some_persons: "Rechercher des personnes..",
|
||||
},
|
||||
visgraph: {
|
||||
Course: 'Parcours',
|
||||
Household: 'Ménage',
|
||||
@@ -21,12 +27,48 @@ const visMessages = {
|
||||
between: "entre",
|
||||
and: "et",
|
||||
add_link: "Créer un lien de filiation",
|
||||
add_person: "Ajouter une personne",
|
||||
create_link_help: "Pour créer un lien de filiation, cliquez d'abord sur un usager, puis sur un second ; précisez ensuite la nature du lien dans le formulaire d'édition.",
|
||||
refresh: "Rafraîchir",
|
||||
screenshot: "Prendre une photo",
|
||||
choose_relation: "Choisissez le lien de parenté",
|
||||
relationship_household: "Filiation du ménage",
|
||||
},
|
||||
item: {
|
||||
type_person: "Usager",
|
||||
type_user: "TMS",
|
||||
type_thirdparty: "Tiers professionnel",
|
||||
type_household: "Ménage"
|
||||
},
|
||||
person: {
|
||||
firstname: "Prénom",
|
||||
lastname: "Nom",
|
||||
born: (ctx) => {
|
||||
if (ctx.gender === 'man') {
|
||||
return 'Né le';
|
||||
} else if (ctx.gender === 'woman') {
|
||||
return 'Née le';
|
||||
} else {
|
||||
return 'Né·e le';
|
||||
}
|
||||
},
|
||||
center_id: "Identifiant du centre",
|
||||
center_type: "Type de centre",
|
||||
center_name: "Territoire", // vendée
|
||||
phonenumber: "Téléphone",
|
||||
mobilenumber: "Mobile",
|
||||
altnames: "Autres noms",
|
||||
email: "Courriel",
|
||||
gender: {
|
||||
title: "Genre",
|
||||
placeholder: "Choisissez le genre de l'usager",
|
||||
woman: "Féminin",
|
||||
man: "Masculin",
|
||||
neuter: "Neutre, non binaire",
|
||||
undefined: "Non renseigné"
|
||||
}
|
||||
},
|
||||
error_only_one_person: "Une seule personne peut être sélectionnée !",
|
||||
edit: 'Éditer',
|
||||
del: 'Supprimer',
|
||||
back: 'Revenir en arrière',
|
||||
|
@@ -117,10 +117,27 @@ const store = createStore({
|
||||
return group
|
||||
},
|
||||
|
||||
getPersonById: (state) => (person_id) => {
|
||||
return state.persons.find(p => p._id === person_id);
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
mutations: {
|
||||
addPerson(state, [person, options]) {
|
||||
if (!'_id' in person) {
|
||||
person._id = person.id
|
||||
person.id = `person_${person.id}`
|
||||
}
|
||||
|
||||
let existing = state.persons.find(p => p._id === person._id);
|
||||
|
||||
if (typeof existing !== 'undefined') {
|
||||
if (!options.folded && person.folded) {
|
||||
// unfold
|
||||
}
|
||||
return;
|
||||
}
|
||||
let age = getAge(person)
|
||||
age = (age === '')? '' : ' - ' + age
|
||||
|
||||
@@ -232,6 +249,9 @@ const store = createStore({
|
||||
|
||||
//// unfold
|
||||
unfoldPerson(state, person) {
|
||||
if (!person.folded) {
|
||||
return;
|
||||
}
|
||||
//console.log('unfoldPerson', person)
|
||||
person.label = person._label
|
||||
delete person._label
|
||||
@@ -261,6 +281,31 @@ const store = createStore({
|
||||
dispatch('fetchInfoForPerson', person)
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a person manually
|
||||
*
|
||||
* @param commit
|
||||
* @param dispatch
|
||||
* @param person
|
||||
*/
|
||||
addMorePerson({ commit, dispatch, getters }, person) {
|
||||
let nodeId = `person_${person.id}`;
|
||||
if (getters.isPersonLoaded(person.id)) {
|
||||
if (getters.isExcludedNode(nodeId)) {
|
||||
commit('removeExcludedNode', nodeId);
|
||||
let p = getters.getPersonById(person.id);
|
||||
if (typeof p !== 'undefined') {
|
||||
commit('unfoldPerson', p);
|
||||
} else {
|
||||
throw 'a person loaded was not found';
|
||||
}
|
||||
commit('updateHack');
|
||||
}
|
||||
} else {
|
||||
return dispatch('addPerson', person);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 2) Fetch infos for this person (hub)
|
||||
* @param object
|
||||
@@ -287,7 +332,7 @@ const store = createStore({
|
||||
//console.log(' isHouseholdLoading ?', getters.isHouseholdLoading(person.current_household_id))
|
||||
if (! getters.isHouseholdLoading(person.current_household_id)) {
|
||||
commit('markHouseholdLoading', person.current_household_id)
|
||||
getHouseholdByPerson(person)
|
||||
return getHouseholdByPerson(person)
|
||||
.then(household => new Promise(resolve => {
|
||||
commit('addHousehold', household)
|
||||
// DISABLED: in init or expand loop, layer is uncheck when added
|
||||
@@ -295,7 +340,7 @@ const store = createStore({
|
||||
//commit('updateHack')
|
||||
dispatch('addLinkFromPersonsToHousehold', household)
|
||||
commit('updateHack')
|
||||
resolve()
|
||||
resolve();
|
||||
})
|
||||
).catch( () => {
|
||||
commit('unmarkHouseholdLoading', person.current_household_id)
|
||||
@@ -335,7 +380,7 @@ const store = createStore({
|
||||
* @param person
|
||||
*/
|
||||
fetchCoursesByPerson({ commit, dispatch }, person) {
|
||||
getCoursesByPerson(person)
|
||||
return getCoursesByPerson(person)
|
||||
.then(courses => new Promise(resolve => {
|
||||
dispatch('addCourses', courses)
|
||||
resolve()
|
||||
@@ -383,6 +428,8 @@ const store = createStore({
|
||||
dispatch('addMissingPerson', [p.person, course])
|
||||
}
|
||||
})
|
||||
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@@ -164,14 +164,8 @@ const getGender = (gender) => {
|
||||
* @returns {string|null}
|
||||
*/
|
||||
const getAge = (person) => {
|
||||
if (person.birthdate) {
|
||||
let birthdate = new Date(person.birthdate.datetime)
|
||||
if (person.deathdate) {
|
||||
let deathdate = new Date(person.deathdate.datetime)
|
||||
return (deathdate.getFullYear() - birthdate.getFullYear()) + visMessages.fr.visgraph.years
|
||||
}
|
||||
let now = new Date()
|
||||
return (now.getFullYear() - birthdate.getFullYear()) + visMessages.fr.visgraph.years
|
||||
if (person.age) {
|
||||
return person.age + ' ' + visMessages.fr.visgraph.years;
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<ul class="list-suggest add-items" v-if="suggested.length > 0">
|
||||
<li v-for="r in suggested" @click="setReferrer(r)"><span>{{ r.text }}</span></li>
|
||||
<li v-for="(r, i) in suggested" @click="setReferrer(r)" :key="i"><span>{{ r.text }}</span></li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {makeFetch} from 'ChillMainAssets/lib/api/apiMethods.js';
|
||||
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods.js';
|
||||
|
||||
export default {
|
||||
name: "SetReferrer",
|
||||
|
@@ -87,10 +87,14 @@ export default {
|
||||
currentMembers() {
|
||||
let members = this.household.members.filter(m => this.household.current_members_id.includes(m.id))
|
||||
.sort((a, b) => {
|
||||
if (a.position.ordering < b.position.ordering) {
|
||||
|
||||
const orderA = a.position ? a.position.ordering : 0;
|
||||
const orderB = b.position ? b.position.ordering : 0;
|
||||
|
||||
if (orderA < orderB) {
|
||||
return -1;
|
||||
}
|
||||
if (a.position.ordering > b.position.ordering) {
|
||||
if (orderA > orderB) {
|
||||
return 1;
|
||||
}
|
||||
if (a.holder && !b.holder) {
|
||||
|
@@ -28,11 +28,14 @@
|
||||
{% if w.createdBy %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title">
|
||||
<h3>{{ 'Referrer'|trans }}</h3>
|
||||
<h3>{{ 'Referrers'|trans }}</h3>
|
||||
</div>
|
||||
<div class="wl-col list">
|
||||
<p class="wl-item">
|
||||
{{ w.createdBy|chill_entity_render_box }}
|
||||
{% for u in w.referrers %}
|
||||
{{ u|chill_entity_render_box }}
|
||||
{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -130,11 +133,13 @@
|
||||
href="{{ chill_path_add_return_path('chill_person_accompanying_period_work_edit', { 'id': w.id }) }}"
|
||||
></a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-delete" title="{{ 'Delete'|trans }}"
|
||||
href="{{ path('chill_person_accompanying_period_work_delete', { 'id': w.id } ) }}"
|
||||
></a>
|
||||
</li>
|
||||
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_DELETE', w) %}
|
||||
<li>
|
||||
<a class="btn btn-delete" title="{{ 'Delete'|trans }}"
|
||||
href="{{ path('chill_person_accompanying_period_work_delete', { 'id': w.id } ) }}"
|
||||
></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@@ -117,12 +117,15 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="item-row separator">
|
||||
<div class="item-col item-meta">
|
||||
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) %}
|
||||
{% if notif_counter.total > 0 %}
|
||||
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) %}
|
||||
{% if notif_counter.total > 0 %}
|
||||
<div class="item-col item-meta">
|
||||
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if itemMeta is defined %}
|
||||
{{ itemMeta }}
|
||||
{% endif %}
|
||||
<div class="item-col">
|
||||
{% if recordAction is defined %}
|
||||
<ul class="record_actions">
|
||||
|
@@ -0,0 +1,82 @@
|
||||
{% extends 'ChillMainBundle::layout.html.twig' %}
|
||||
|
||||
{% block title 'period_by_user_list.Period by user'|trans %}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags('mod_set_referrer') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('mod_set_referrer') }}
|
||||
{% endblock %}
|
||||
|
||||
{% macro period_meta(period) %}
|
||||
{% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE', period) %}
|
||||
<div class="item-col item-meta">
|
||||
{% set job_id = null %}
|
||||
{% if period.job is defined %}
|
||||
{% set job_id = period.job.id %}
|
||||
{% endif %}
|
||||
<span
|
||||
data-set-referrer-app="data-set-referrer-app"
|
||||
data-set-referrer-accompanying-period-id="{{ period.id }}"
|
||||
data-set-referrer-job-id="{{ job_id }}"
|
||||
></span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro period_actions(period) %}
|
||||
{% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', period) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_accompanying_course_index', {'accompanying_period_id': period.id}) }}" class="btn btn-show"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% import _self as m %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col-10">
|
||||
<h1>{{ block('title') }}</h1>
|
||||
|
||||
{{ form_start(form) }}
|
||||
<div class="row filter-box">
|
||||
<div class="col-md-6">
|
||||
{{ form_label(form.user ) }}
|
||||
{{ form_widget(form.user, {'attr': {'class': 'select2'}}) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button type="submit" class="btn btn-save change-icon">
|
||||
<i class="fa fa-filter"></i> Filtrer
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{{ form_end(form) }}
|
||||
|
||||
{% if form.user.vars.value is empty %}
|
||||
<p class="chill-no-data-statement">{{ 'period_by_user_list.Pick a user'|trans }}</p>
|
||||
{% elseif periods|length == 0 and form.user.vars.value is not empty %}
|
||||
<p class="chill-no-data-statement">{{ 'period_by_user_list.Any course or no authorization to see them'|trans }}</p>
|
||||
|
||||
{% else %}
|
||||
<p><span class="badge rounded-pill bg-primary">{{ paginator.totalItems }}</span> parcours à réassigner (calculé ce jour à {{ null|format_time('medium') }})</p>
|
||||
|
||||
<div class="flex-table">
|
||||
{% for period in periods %}
|
||||
{% include '@ChillPerson/AccompanyingPeriod/_list_item.html.twig' with {'period': period,
|
||||
'recordAction': m.period_actions(period), 'itemMeta': m.period_meta(period) } %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{{ chill_pagination(paginator) }}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@@ -167,6 +167,18 @@
|
||||
<span class="chill-no-data-statement">{{ 'No data given'|trans }}</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if person.email is not empty %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-envelope-o"></i><a href="{{ 'mailto:' ~ person.email }}">
|
||||
{{ person.email }}
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-envelope-o"></i>
|
||||
<span class="chill-no-data-statement">{{ 'No data given'|trans }}</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if options['addCenter'] and person|chill_resolve_center|length > 0 %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-long-arrow-right"></i>
|
||||
|
@@ -46,13 +46,13 @@
|
||||
{{ 'Household summary'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{#
|
||||
{# TODO: add ACL to check if user is allowed to edit household? #}
|
||||
<li>
|
||||
<a href="{{ path ('chill_person_household_accompanying_course_new', {'household_id' : [ household.id ] } ) }}" class="btn btn-create">
|
||||
{{ 'Create an accompanying period'|trans }}
|
||||
<a class="btn btn-create"
|
||||
href="{{ path ('chill_household_accompanying_course_new', {'household_id' : household.id } ) }}" role="button">
|
||||
{{ 'Create an accompanying period'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
#}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
@@ -0,0 +1,26 @@
|
||||
{% extends '@ChillPerson/Household/layout.html.twig' %}
|
||||
|
||||
{% block title 'household_composition.create'|trans %}
|
||||
|
||||
{% block block_post_menu %}
|
||||
<div class="post-menu"></div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ 'household_composition.Create'|trans }}</h1>
|
||||
|
||||
<div>
|
||||
{{ form_start(form) }}
|
||||
|
||||
{{ form_widget(form) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button type="submit" class="btn btn-create">{{ 'Save'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@@ -15,7 +15,7 @@
|
||||
{% else %}
|
||||
<div class="flex-table">
|
||||
{% for c in compositions %}
|
||||
{% if c.id != editId %}
|
||||
{# {% if c.id != editId %} #}
|
||||
<div class="item-bloc">
|
||||
<div class="item-row">
|
||||
<div class="item-col">
|
||||
@@ -42,7 +42,7 @@
|
||||
<div class="item-row">
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('chill_person_household_composition_index', {'id': c.household.id, 'edit': c.id}) }}" class="btn btn-edit"></a>
|
||||
<a href="{{ path('chill_person_household_composition_new', {'id': c.household.id, 'edit': c.id}) }}" class="btn btn-edit"></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_composition_delete', {'composition_id': c.id,
|
||||
@@ -54,45 +54,17 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ form_start(form) }}
|
||||
|
||||
{{ form_widget(form) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li class="cancel" style="margin-right: auto;">
|
||||
<a class="btn btn-cancel" href="{{ path('chill_person_household_composition_index', {'id': c.household.id}) }}">{{ 'Cancel'|trans }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<button type="submit" class="btn btn-create">{{ 'Save'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(form) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="collapseForm" class="{% if not isPosted %}collapse{% endif %}">
|
||||
{{ form_start(form) }}
|
||||
|
||||
{{ form_widget(form) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button type="submit" class="btn btn-create">{{ 'Save'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
|
||||
{% if editId == -1 %}
|
||||
{% if is_granted('CHILL_PERSON_HOUSEHOLD_EDIT', household) %}
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
<button class="btn btn-primary btn-create change-icon" type="button" data-bs-toggle="collapse" data-bs-target="#collapseForm" aria-expanded="false" aria-controls="collapseForm">
|
||||
{{ 'Create'|trans }}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_household_composition_new', {'id': household.id,}) }}"
|
||||
class="btn btn-new"
|
||||
title="{{ 'Create'|trans }}">{{ 'Create'|trans }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@@ -58,6 +58,13 @@
|
||||
}) }}
|
||||
</span>
|
||||
{%- endif -%}
|
||||
{% if person.getCurrentHousehold is not null %}
|
||||
<span>
|
||||
<a class="household-link" href="{{ chill_path_add_return_path('chill_person_household_summary', { 'household_id' : person.getCurrentHousehold.id } ) }}">
|
||||
<i class="fa fa-home"></i>
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@@ -1,15 +1,25 @@
|
||||
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||
|
||||
{% set activeRouteKey = 'chill_person_resource_list' %}
|
||||
|
||||
{% block title %}{{ 'Person resources'|trans|capitalize ~ ' ' ~ person|chill_entity_render_string }}{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags('page_person_resource_showhide_input') }}
|
||||
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('page_person_resource_showhide_input') }}
|
||||
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block personcontent %}
|
||||
|
||||
<h1 style="margin-bottom: 2rem;">{{ 'Add a person resource'|trans }}</h1>
|
||||
|
||||
<div class="col-md col-xxl">
|
||||
<div id="collapseForm" class="{% if not form.vars.submitted %}collapse{% endif %}">
|
||||
<h3 style="margin-bottom: 2rem;">{{ 'Add a person resource'|trans }}</h3>
|
||||
{% include "@ChillPerson/PersonResource/form.html.twig" %}
|
||||
</div>
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
<button class="btn btn-primary btn-create change-icon" type="button" data-bs-toggle="collapse" data-bs-target="#collapseForm" aria-expanded="false" aria-controls="collapseForm">
|
||||
{{ 'Add a person resource'|trans }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@@ -85,8 +85,14 @@
|
||||
<p class="chill-no-data-statement">{{ 'There are no available resources'|trans }}</p>
|
||||
{% endif %}
|
||||
|
||||
<h1 style="margin-bottom: 2rem;">{{ 'Add a person resource'|trans }}</h1>
|
||||
|
||||
{% include "@ChillPerson/PersonResource/create.html.twig" %}
|
||||
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_person_resource_new', {'person_id': person.id,}) }}"
|
||||
class="btn btn-new"
|
||||
title="{{ 'Create'|trans }}">{{ 'Create'|trans }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
@@ -49,7 +49,12 @@
|
||||
<li>
|
||||
<i class="fa fa-li fa-home"></i>
|
||||
<span class="item-key">{{ "Address of"|trans}} </span>
|
||||
<span class="chill-entity entity-person badge-person">{{ a.hostPerson|chill_entity_render_box }}</span>
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: 'person', id: a.hostPerson.id },
|
||||
buttonText: a.hostPerson|chill_entity_render_string,
|
||||
isDead: a.hostPerson.deathdate is not null
|
||||
} %}
|
||||
</li>
|
||||
<li>
|
||||
{% set address_date = date(a.startDate|date("m/d/Y")) %}
|
||||
@@ -62,7 +67,12 @@
|
||||
<li>
|
||||
<i class="fa fa-li fa-home"></i>
|
||||
<span class="item-key">{{ "Address of"|trans}}</span>
|
||||
<span class="chill-entity entity-person badge-thirdparty">{{ a.hostThirdParty|chill_entity_render_box }}</span>
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: 'thirdparty', id: a.hostThirdParty.id },
|
||||
buttonText: a.hostThirdParty|chill_entity_render_string,
|
||||
isDead: false,
|
||||
} %}
|
||||
</li>
|
||||
<li>
|
||||
{% if a.hostThirdParty.address is not null %}
|
||||
|
@@ -1,5 +1,10 @@
|
||||
{%- import "@ChillDocStore/Macro/macro.html.twig" as m -%}
|
||||
|
||||
<div class="flex-table accompanying_course_work-list">
|
||||
<div class="item-bloc evaluation-item bg-chill-llight-gray">
|
||||
<div class="item-row mb-2">
|
||||
<h1>{{ doc.title }}</h1>
|
||||
</div>
|
||||
<div class="item-row mb-2">
|
||||
<h2 class="badge-title">
|
||||
<span class="title_label"></span>
|
||||
@@ -20,6 +25,24 @@
|
||||
</span>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="item-row mb-2">
|
||||
<div class="item-col" style="width: 17%;">
|
||||
<h4 class="title_label">
|
||||
{{ 'Participants'|trans }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="item-col list">
|
||||
{% for p in evaluation.accompanyingPeriodWork.persons %}
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
targetEntity: { name: 'person', id: p.id },
|
||||
action: 'show',
|
||||
displayBadge: true,
|
||||
buttonText: p|chill_entity_render_string,
|
||||
isDead: p.deathdate is not null
|
||||
} %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-row column">
|
||||
<table class="obj-res-eval my-3" style="font-size: 110% !important;">
|
||||
<thead>
|
||||
@@ -92,12 +115,19 @@
|
||||
</div>
|
||||
|
||||
{% if display_action is defined and display_action == true %}
|
||||
{# TODO add acl #}
|
||||
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', evaluation.accompanyingPeriodWork) %}
|
||||
<ul class="record_actions">
|
||||
<li>{{ m.download_button(doc.storedObject, doc.title) }}</li>
|
||||
{% if chill_document_is_editable(doc.storedObject) %}
|
||||
<li>
|
||||
{{ doc.storedObject|chill_document_edit_button }}
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a class="btn btn-show" href="{{ path('chill_person_accompanying_period_work_edit', {'id': evaluation.accompanyingPeriodWork.id}) }}">
|
||||
{{ 'Show'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
Reference in New Issue
Block a user