Merge remote-tracking branch 'origin/master' into issue442_toggle_emergency

This commit is contained in:
2022-03-01 14:52:56 +01:00
233 changed files with 4800 additions and 1961 deletions

View File

@@ -72,7 +72,7 @@ section.chill-entity {
}
}
p {
display: inline-block;
// display: inline-block;
margin: 0 0 0 1.5em;
text-indent: -1.5em;

View File

@@ -50,7 +50,7 @@ var handleAdd = function(button) {
empty_explain = collection.querySelector('li[data-collection-empty-explain]'),
entry = document.createElement('li'),
event = new CustomEvent('collection-add-entry', { detail: { collection: collection, entry: entry } }),
counter = collection.childNodes.length,
counter = collection.childNodes.length + parseInt(Math.random() * 1000000)
content
;
content = prototype.replace(new RegExp('__name__', 'g'), counter);

View File

@@ -1,10 +1,15 @@
.confidential{
display: flex;
position: relative;
}
.toggle{
margin-left: 30px;
margin-top: 5px;
cursor: pointer;
position: absolute;
bottom: 0px;
right: 10px;
z-index: 5;
}
.blur {
-webkit-filter: blur(5px);

View File

@@ -3,7 +3,7 @@ import {ShowHide} from 'ChillMainAssets/lib/show_hide/show_hide.js';
window.addEventListener('DOMContentLoaded', function() {
let
divTransitions = document.querySelector('#transitions'),
futureDestUsersContainer = document.querySelector('#futureDestUsers')
futureDestUsersContainer = document.querySelector('#futureDests')
;
if (null !== divTransitions) {
@@ -67,24 +67,4 @@ window.addEventListener('DOMContentLoaded', function() {
});
}
// validate form
let form = document.querySelector('form[name="workflow_step"]');
if (form === null) {
console.error('form to validate not found');
}
form.addEventListener('submit', function (event) {
const datas = new FormData(event.target);
if (datas.has('workflow_step[future_dest_users]')) {
const dests = JSON.parse(datas.get('workflow_step[future_dest_users]'));
if (dests === null || (dests instanceof Array && dests.length === 0)) {
event.preventDefault();
console.log('no users!');
window.alert('Indiquez un utilisateur pour traiter la prochaine étape.');
}
}
});
});

View File

@@ -260,8 +260,7 @@ export default {
editPane: false,
datePane: false,
loading: false,
success: false,
dirty: false
success: false
},
errors: [],
defaultz: {
@@ -537,17 +536,19 @@ export default {
checkErrors() {
this.errors = [];
if (this.flag.dirty) {
if (this.entity.selected.country === null) {
this.errors.push("Un pays doit être sélectionné.");
}
if (this.entity.selected.country === null) {
this.errors.push("Un pays doit être sélectionné.");
}
if (this.entity.selected.city === null) {
this.errors.push("Une ville doit être sélectionnée.");
} else {
if (Object.keys(this.entity.selected.city).length === 0) {
this.errors.push("Une ville doit être sélectionnée.");
}
if (!this.entity.selected.isNoAddress) {
if (this.entity.selected.address.street === null || this.entity.selected.address.streetNumber === null) {
this.errors.push("Une adresse doit être sélectionnée.");
}
}
if (!this.entity.selected.isNoAddress) {
if (this.entity.selected.address.street === null || this.entity.selected.address.street === '' || this.entity.selected.address.streetNumber === null || this.entity.selected.address.streetNumber === '') {
this.errors.push("Une adresse doit être sélectionnée.");
}
}
},
@@ -567,7 +568,7 @@ export default {
this.entity.selected.country = this.context.edit ? this.entity.address.country : {};
this.entity.selected.postcode = this.context.edit ? this.entity.address.postcode : {};
this.entity.selected.city = {};
this.entity.selected.city = this.context.edit ? this.entity.address.postcode : {};
this.entity.selected.address = {};
this.entity.selected.address.street = this.context.edit ? this.entity.address.street: null;
@@ -583,6 +584,8 @@ export default {
this.entity.selected.writeNew.address = this.context.edit && this.entity.address.addressReference === null && this.entity.address.street.length > 0
this.entity.selected.writeNew.postcode = false // NB: this used to be this.context.edit, but think it was erroneous;
console.log('!! just set writeNew.postcode to', this.entity.selected.writeNew.postcode);
this.checkErrors();
},
/*

View File

@@ -111,11 +111,9 @@ export default {
this.entity.selected.address.streetNumber = value.streetNumber;
this.entity.selected.writeNew.address = false;
this.updateMapCenter(value.point);
this.flag.dirty = true;
this.checkErrors();
},
remove() {
this.flag.dirty = true;
this.entity.selected.address = {};
this.checkErrors();
},
@@ -158,7 +156,6 @@ export default {
this.entity.selected.address.street = addr.street;
this.entity.selected.address.streetNumber = addr.number;
this.entity.selected.writeNew.address = true;
this.flag.dirty = true;
this.checkErrors();
}
},

View File

@@ -125,11 +125,9 @@ export default {
if (value.center) {
this.updateMapCenter(value.center);
}
this.flag.dirty = true;
this.checkErrors();
},
remove() {
this.flag.dirty = true;
this.entity.selected.city = {};
this.checkErrors();
},

View File

@@ -51,7 +51,6 @@ export default {
init() {
if (this.value !== undefined) {
this.selectCountry(this.value);
this.flag.dirty = false;
}
},
selectCountryByCode(countryCode) {
@@ -67,7 +66,6 @@ export default {
this.checkErrors();
},
remove() {
this.flag.dirty = true;
this.entity.selected.country = null;
this.checkErrors();
},

View File

@@ -157,6 +157,7 @@ export default {
set(value) {
console.log('isNoAddress value', value);
this.entity.selected.isNoAddress = value;
this.checkErrors();
},
get() {
return this.entity.selected.isNoAddress;

View File

@@ -1,7 +1,7 @@
<template>
<h2>{{ $t('main_title') }}</h2>
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link"
@@ -23,7 +23,6 @@
:class="{'active': activeTab === 'MyAccompanyingCourses'}"
@click="selectTab('MyAccompanyingCourses')">
{{ $t('my_accompanying_courses.tab') }}
<tab-counter :count="state.accompanyingCourses.count"></tab-counter>
</a>
</li>
<li class="nav-item">
@@ -51,11 +50,19 @@
<tab-counter :count="state.tasks.alert.count"></tab-counter>
</a>
</li>
<li class="nav-item">
<a class="nav-link"
:class="{'active': activeTab === 'MyWorkflows'}"
@click="selectTab('MyWorkflows')">
{{ $t('my_workflows.tab') }}
<tab-counter :count="state.workflows.count"></tab-counter>
</a>
</li>
<li class="nav-item loading ms-auto py-2" v-if="loading">
<i class="fa fa-circle-o-notch fa-spin fa-lg text-chill-gray" :title="$t('loading')"></i>
</li>
</ul>
<div class="my-4">
<my-customs
v-if="activeTab === 'MyCustoms'">
@@ -75,6 +82,9 @@
<my-notifications
v-else-if="activeTab === 'MyNotifications'">
</my-notifications>
<my-workflows
v-else-if="activeTab === 'MyWorkflows'">
</my-workflows>
</div>
</template>
@@ -85,6 +95,7 @@ import MyEvaluations from './MyEvaluations';
import MyTasks from './MyTasks';
import MyAccompanyingCourses from './MyAccompanyingCourses';
import MyNotifications from './MyNotifications';
import MyWorkflows from './MyWorkflows.vue';
import TabCounter from './TabCounter';
import { mapState } from "vuex";
@@ -95,6 +106,7 @@ export default {
MyWorks,
MyEvaluations,
MyTasks,
MyWorkflows,
MyAccompanyingCourses,
MyNotifications,
TabCounter,
@@ -126,6 +138,7 @@ export default {
'MyWorks',
'MyEvaluations',
'MyTasks',
'MyWorkflows',
]) {
this.$store.dispatch('getByTab', { tab: m, param: "countOnly=1" });
}

View File

@@ -66,6 +66,8 @@ export default {
return appMessages.fr.the_activity;
case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod':
return appMessages.fr.the_course;
case 'Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow':
return appMessages.fr.the_workflow;
default:
throw 'notification type unknown';
}
@@ -76,6 +78,8 @@ export default {
return `/fr/activity/${n.relatedEntityId}/show`
case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod':
return `/fr/parcours/${n.relatedEntityId}`
case 'Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow':
return `/fr/main/workflow/${n.relatedEntityId}/show`
default:
throw 'notification type unknown';
}

View File

@@ -0,0 +1,88 @@
<template>
<div class="alert alert-light">{{ $t('my_workflows.description') }}</div>
<span v-if="noResults" class="chill-no-data-statement">{{ $t('no_data') }}</span>
<tab-table v-else>
<template v-slot:thead>
<th scope="col">{{ $t('Object_workflow') }}</th>
<th scope="col">{{ $t('Step') }}</th>
<th scope="col">{{ $t('concerned_users') }}</th>
<th scope="col"></th>
</template>
<template v-slot:tbody>
<tr v-for="(w, i) in workflows.results" :key="`workflow-${i}`">
<td>{{ w.title }}</td>
<td>
<div class="workflow">
<div class="breadcrumb">
<i class="fa fa-circle me-1 text-chill-yellow mx-2"></i>
<span class="mx-2">{{ getStep(w) }}</span>
</div>
</div>
</td>
<td v-if="w.datas.persons !== null">
<span v-for="p in w.datas.persons" class="me-1" :key="p.id">
<on-the-fly
:type="p.type"
:id="p.id"
:buttonText="p.textAge"
:displayBadge="'true' === 'true'"
action="show">
</on-the-fly>
</span>
</td>
<td>
<a class="btn btn-sm btn-show" :href="getUrl(w)">
{{ $t('show_entity', { entity: $t('the_workflow') }) }}
</a>
</td>
</tr>
</template>
</tab-table>
</template>
<script>
import { mapState, mapGetters } from "vuex";
import TabTable from "./TabTable";
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly';
export default {
name: "MyWorkflows",
components: {
TabTable,
OnTheFly
},
computed: {
...mapState([
'workflows',
]),
...mapGetters([
'isWorkflowsLoaded',
]),
noResults() {
if (!this.isWorkflowsLoaded) {
return false;
} else {
return this.workflows.count === 0;
}
},
},
methods: {
getUrl(w) {
return `/fr/main/workflow/${w.id}/show`;
},
getStep(w) {
const lastStep = w.steps.length - 1
return w.steps[lastStep].currentStep.text;
}
},
}
</script>
<style scoped>
span.outdated {
font-weight: bold;
color: var(--bs-warning);
}
</style>

View File

@@ -22,6 +22,10 @@ const appMessages = {
tab: "Mes notifications",
description: "Liste des notifications reçues et non lues.",
},
my_workflows: {
tab: "Mes workflows",
description: "Liste des workflows en attente d'une action."
},
opening_date: "Date d'ouverture",
social_issues: "Problématiques sociales",
concerned_persons: "Usagers concernés",
@@ -33,12 +37,16 @@ const appMessages = {
From: "Expéditeur",
Subject: "Objet",
Entity: "Associé à",
Step: "Étape",
concerned_users: "Usagers concernés",
Object_workflow: "Objet du workflow",
show_entity: "Voir {entity}",
the_activity: "l'échange",
the_course: "le parcours",
the_action: "l'action",
the_evaluation: "l'évaluation",
the_task: "la tâche",
the_workflow: "le workflow",
StartDate: "Date d'ouverture",
SocialAction: "Action d'accompagnement",
no_data: "Aucun résultats",
@@ -61,4 +69,4 @@ Object.assign(appMessages.fr);
export {
appMessages
};
};

View File

@@ -1,12 +1,6 @@
import 'es6-promise/auto';
import { createStore } from 'vuex';
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
import MyCustoms from "../MyCustoms";
import MyWorks from "../MyWorks";
import MyEvaluations from "../MyEvaluations";
import MyTasks from "../MyTasks";
import MyAccompanyingCourses from "../MyAccompanyingCourses";
import MyNotifications from "../MyNotifications";
const debug = process.env.NODE_ENV !== 'production';
@@ -27,6 +21,7 @@ const store = createStore({
},
accompanyingCourses: {},
notifications: {},
workflows: {},
errorMsg: [],
loading: false
},
@@ -49,6 +44,9 @@ const store = createStore({
isNotificationsLoaded(state) {
return !isEmpty(state.notifications);
},
isWorkflowsLoaded(state) {
return !isEmpty(state.workflows);
},
counter(state) {
return {
works: state.works.count,
@@ -57,6 +55,7 @@ const store = createStore({
tasksAlert: state.tasks.alert.count,
accompanyingCourses: state.accompanyingCourses.count,
notifications: state.notifications.count,
workflows: state.workflows.count
}
}
},
@@ -85,6 +84,9 @@ const store = createStore({
//console.log('addNotifications', notifications);
state.notifications = notifications;
},
addWorkflows(state, workflows) {
state.workflows = workflows;
},
setLoading(state, bool) {
state.loading = bool;
},
@@ -180,14 +182,30 @@ const store = createStore({
const url = `/api/1.0/main/notification/my/unread${'?'+ param}`;
makeFetch('GET', url)
.then((response) => {
console.log('notifications', response)
commit('addNotifications', response);
commit('setLoading', false);
})
.catch((error) => {
commit('catchError', error);
throw error;
})
;
});
}
break;
case 'MyWorkflows':
if (!getters.isWorflowsLoaded) {
commit('setLoading', true);
const url = '/api/1.0/main/workflow/my';
makeFetch('GET', url)
.then((response) => {
console.log('workflows', response)
commit('addWorkflows', response);
commit('setLoading', false);
})
.catch((error) => {
commit('catchError', error);
throw error;
});
}
break;
default:

View File

@@ -1,6 +1,6 @@
<template>
<ul class="nav nav-tabs">
<li class="nav-item">
<li v-if="allowedTypes.includes('person')" class="nav-item">
<a class="nav-link" :class="{ active: isActive('person') }">
<label for="person">
<input type="radio" name="person" id="person" v-model="radioType" value="person">
@@ -8,7 +8,7 @@
</label>
</a>
</li>
<li class="nav-item">
<li v-if="allowedTypes.includes('thirdparty')" class="nav-item">
<a class="nav-link" :class="{ active: isActive('thirdparty') }">
<label for="thirdparty">
<input type="radio" name="thirdparty" id="thirdparty" v-model="radioType" value="thirdparty">
@@ -21,14 +21,16 @@
<div class="my-4">
<on-the-fly-person
v-if="type === 'person'"
v-bind:action="action"
:action="action"
:query="query"
ref="castPerson"
>
</on-the-fly-person>
<on-the-fly-thirdparty
v-if="type === 'thirdparty'"
v-bind:action="action"
:action="action"
:query="query"
ref="castThirdparty"
>
</on-the-fly-thirdparty>
@@ -38,18 +40,17 @@
<script>
import OnTheFlyPerson from 'ChillPersonAssets/vuejs/_components/OnTheFly/Person.vue';
import OnTheFlyThirdparty from 'ChillThirdPartyAssets/vuejs/_components/OnTheFly/ThirdParty.vue';
import { postPerson } from "ChillPersonAssets/vuejs/_api/OnTheFly";
export default {
name: "OnTheFlyCreate",
props: ['action'],
props: ['action', 'allowedTypes', 'query'],
components: {
OnTheFlyPerson,
OnTheFlyThirdparty
},
data() {
return {
type: 'person' //by default
type: null
}
},
computed: {
@@ -61,7 +62,10 @@ export default {
get() {
return this.type;
}
}
},
},
mounted() {
this.type = (this.allowedTypes.length === 1 && this.allowedTypes.includes('thirdparty')) ? 'thirdparty' : 'person'
},
methods: {
isActive(tab) {
@@ -73,8 +77,7 @@ export default {
return this.$refs.castPerson.$data.person;
case 'thirdparty':
let data = this.$refs.castThirdparty.$data.thirdparty;
data.name = data.text;
if (data.address !== undefined) {
if (data.address !== undefined && data.address !== null) {
data.address = { id: data.address.address_id }
} else {
data.address = null;

View File

@@ -1,11 +1,11 @@
<template>
<a v-if="isDisplayBadge" @click="openModal">
<span class="chill-entity" :class="badgeType">
{{ buttonText }}<span v-if="isDead"> ()</span>
</span>
</a>
<a v-else class="btn btn-sm" target="_blank"
<a v-if="isDisplayBadge" @click="openModal">
<span class="chill-entity" :class="badgeType">
{{ buttonText }}<span v-if="isDead"> ()</span>
</span>
</a>
<a v-else class="btn btn-sm" target="_blank"
:class="classAction"
:title="$t(titleAction)"
@click="openModal">
@@ -18,7 +18,8 @@
@close="modal.showModal = false">
<template v-slot:header>
<h3 class="modal-title">{{ $t(titleModal) }}</h3>
<h3 v-if="parent" class="modal-title">{{ $t(titleModal, {q: parent.text}) }}</h3>
<h3 v-else class="modal-title">{{ $t(titleModal) }}</h3>
</template>
<template v-slot:body v-if="type === 'person'">
@@ -29,10 +30,10 @@
ref="castPerson">
</on-the-fly-person>
<div v-if="hasResourceComment">
<h3>{{ $t('onthefly.resource_comment_title') }}</h3>
<blockquote class="chill-user-quote">
{{ parent.comment }}
</blockquote>
<h3>{{ $t('onthefly.resource_comment_title') }}</h3>
<blockquote class="chill-user-quote">
{{ parent.comment }}
</blockquote>
</div>
</template>
@@ -44,16 +45,27 @@
ref="castThirdparty">
</on-the-fly-thirdparty>
<div v-if="hasResourceComment">
<h3>{{ $t('onthefly.resource_comment_title') }}</h3>
<blockquote class="chill-user-quote">
{{ parent.comment }}
</blockquote>
<h3>{{ $t('onthefly.resource_comment_title') }}</h3>
<blockquote class="chill-user-quote">
{{ parent.comment }}
</blockquote>
</div>
</template>
<template v-slot:body v-else-if="parent">
<on-the-fly-thirdparty
:parent="parent"
:action="action"
type="thirdparty"
ref="castThirdparty">
</on-the-fly-thirdparty>
</template>
<template v-slot:body v-else>
<on-the-fly-create
:action="action"
:allowedTypes="allowedTypes"
:query="query"
ref="castNew">
</on-the-fly-create>
</template>
@@ -81,6 +93,7 @@ import Modal from 'ChillMainAssets/vuejs/_components/Modal.vue';
import OnTheFlyCreate from './Create.vue';
import OnTheFlyPerson from 'ChillPersonAssets/vuejs/_components/OnTheFly/Person.vue';
import OnTheFlyThirdparty from 'ChillThirdPartyAssets/vuejs/_components/OnTheFly/ThirdParty.vue';
import { postThirdparty } from "ChillThirdPartyAssets/vuejs/_api/OnTheFly";
export default {
name: 'OnTheFly',
@@ -90,7 +103,7 @@ export default {
OnTheFlyThirdparty,
OnTheFlyCreate
},
props: ['type', 'id', 'action', 'buttonText', 'displayBadge', 'isDead', 'parent'],
props: ['type', 'id', 'action', 'buttonText', 'displayBadge', 'isDead', 'parent', 'allowedTypes', 'query'],
emits: ['saveFormOnTheFly'],
data() {
return {
@@ -102,12 +115,11 @@ export default {
},
computed: {
hasResourceComment() {
//console.log('hasResourceComment', this.parent);
return (typeof this.parent !== 'undefined' && this.parent !== null)
&& this.action === 'show'
&& this.parent.type === 'accompanying_period_resource'
&& (this.parent.comment !== null && this.parent.comment !== '')
;
return (typeof this.parent !== 'undefined' && this.parent !== null)
&& this.action === 'show'
&& this.parent.type === 'accompanying_period_resource'
&& (this.parent.comment !== null && this.parent.comment !== '')
;
},
classAction() {
switch (this.action) {
@@ -117,6 +129,8 @@ export default {
return 'btn-update';
case 'create':
return 'btn-create';
case 'addContact':
return 'btn-tpchild';
}
},
titleAction() {
@@ -127,8 +141,17 @@ export default {
return 'action.edit';
case 'create':
return 'action.create';
case 'addContact':
return 'action.addContact';
}
},
titleCreate() {
return this.allowedTypes.every(t => t === 'person')
? 'onthefly.create.title.person'
: this.allowedTypes.every(t => t === 'thirdparty')
? 'onthefly.create.title.thirdparty'
: 'onthefly.create.title.default'
},
titleModal() {
switch (this.action) {
case 'show':
@@ -136,7 +159,9 @@ export default {
case 'edit':
return 'onthefly.edit.' + this.type;
case 'create':
return 'onthefly.create.title';
return this.titleCreate;
case 'addContact':
return 'onthefly.addContact.title';
}
},
titleMessage() {
@@ -170,8 +195,8 @@ export default {
this.modal.showModal = false;
},
openModal() {
//console.log('## OPEN ON THE FLY MODAL');
//console.log('## type:', this.type, ', action:', this.action);
// console.log('## OPEN ON THE FLY MODAL');
// console.log('## type:', this.type, ', action:', this.action);
this.modal.showModal = true;
this.$nextTick(function() {
//this.$refs.search.focus();
@@ -181,7 +206,7 @@ export default {
this.$data.action = action;
},
saveAction() {
console.log('saveAction button: create/edit action with', this.type);
// console.log('saveAction button: create/edit action with', this.type);
let
type = this.type,
data = {} ;
@@ -193,17 +218,28 @@ export default {
case 'thirdparty':
data = this.$refs.castThirdparty.$data.thirdparty;
/* never executed ? */
break;
default:
if (typeof this.type === 'undefined') { // action=create
type = this.$refs.castNew.radioType;
data = this.$refs.castNew.castDataByType();
if (typeof this.type === 'undefined') { // action=create or addContact
console.log('will rewrite data');
if (this.action === 'addContact') {
type = 'thirdparty'
data = this.$refs.castThirdparty.$data.thirdparty;
console.log('data original', data);
data.parent = {type: "thirdparty", id: this.parent.id};
} else {
type = this.$refs.castNew.radioType;
data = this.$refs.castNew.castDataByType();
console.log(data)
}
} else {
throw 'error with object type';
}
}
console.log('type', type);
console.log('data', data);
// pass datas to parent
this.$emit('saveFormOnTheFly', { type: type, data: data });
},
@@ -223,4 +259,8 @@ export default {
a {
cursor: pointer;
}
/* .btn-add-contact {
background-color: pink;
} */
</style>

View File

@@ -9,15 +9,25 @@ const ontheflyMessages = {
},
edit: {
person: "Modifier un usager",
thirdparty: "Modifier un tiers"
thirdparty: "Modifier un tiers",
},
create: {
button: "Créer \"{q}\"",
title: "Création d'un nouvel usager ou d'un tiers professionnel",
title: {
default: "Création d'un nouvel usager ou d'un tiers professionnel",
person: "Création d'un nouvel usager",
thirdparty: "Création d'un nouveau tiers professionnel",
},
person: "un nouvel usager",
thirdparty: "un nouveau tiers professionnel"
},
resource_comment_title: "Un commentaire est associé à cet interlocuteur"
addContact: {
title: "Créer un contact pour {q}"
},
resource_comment_title: "Un commentaire est associé à cet interlocuteur",
addContact: {
title: "Créer un contact pour {q}"
}
}
}
}

View File

@@ -1,6 +1,6 @@
<template>
<div :class="classes">
<div class="confidential-content" :class="{ 'blur': isBlurred }">
<div class="confidential">
<div :class="{ 'blur': isBlurred }">
<slot name="confidential-content"></slot>
</div>
<div>
@@ -29,18 +29,5 @@ export default {
<style scoped lang='scss'>
.confidential{
align-items: center;
display: flex;
}
.toggle{
margin-top: 28px;
cursor: pointer;
display: block;
float: right;
margin-right: 20px;
}
.blur {
-webkit-filter: blur(5px);
-moz-filter: blur(5px);
filter: blur(5px);
}
</style>

View File

@@ -27,7 +27,6 @@
</p>
</div>
</template>
</confidential>
</div>
@@ -94,6 +93,7 @@ export default {
return this.isMultiline === true ? "multiline" : "";
},
isConfidential() {
console.log(this.address.confidential)
return this.address.confidential;
}
}

View File

@@ -5,7 +5,7 @@
<div>
<div class="item-row col">
<h2>Workflow</h2>
<h2>{{ w.title }}</h2>
<div class="flex-grow-1 ms-3 h3">
<div class="visually-hidden">
{{ w.relatedEntityClass }}

View File

@@ -12,6 +12,8 @@
:relatedEntityClass="this.relatedEntityClass"
:relatedEntityId="this.relatedEntityId"
:workflowsAvailables="workflowsAvailables"
:preventDefaultMoveToGenerate="this.$props.preventDefaultMoveToGenerate"
:goToGenerateWorkflowPayload="this.goToGenerateWorkflowPayload"
@go-to-generate-workflow="goToGenerateWorkflow"
></pick-workflow>
@@ -36,6 +38,7 @@
:relatedEntityId="this.relatedEntityId"
:workflowsAvailables="workflowsAvailables"
:preventDefaultMoveToGenerate="this.$props.preventDefaultMoveToGenerate"
:goToGenerateWorkflowPayload="this.goToGenerateWorkflowPayload"
@go-to-generate-workflow="this.goToGenerateWorkflow"
></pick-workflow>
</template>
@@ -83,6 +86,10 @@ export default {
required: false,
default: false,
},
goToGenerateWorkflowPayload: {
required: false,
default: {}
},
},
data() {
return {
@@ -105,7 +112,7 @@ export default {
this.modal.showModal = true;
},
goToGenerateWorkflow(data) {
console.log('go to generate workflow intercepted');
console.log('go to generate workflow intercepted', data);
this.$emit('goToGenerateWorkflow', data);
}
},

View File

@@ -37,6 +37,10 @@ export default {
required: false,
default: false,
},
goToGenerateWorkflowPayload: {
required: false,
default: {}
},
},
emits: ['goToGenerateWorkflow'],
methods: {
@@ -51,7 +55,7 @@ export default {
window.location.assign(this.makeLink(workflowName));
}
this.$emit('goToGenerateWorkflow', {event, workflowName, link: this.makeLink(workflowName)});
this.$emit('goToGenerateWorkflow', {event, workflowName, link: this.makeLink(workflowName), payload: this.goToGenerateWorkflowPayload});
}
}
}

View File

@@ -46,7 +46,8 @@ const messages = {
person: "Quitter la page et ouvrir la fiche de l'usager",
thirdparty: "Quitter la page et voir le tiers",
},
refresh: 'Rafraîchir'
refresh: 'Rafraîchir',
addContact: 'Ajouter un contact'
},
nav: {
next: "Suivant",

View File

@@ -3,6 +3,8 @@
{% if transition_form is not null %}
{{ form_start(transition_form) }}
{{ form_errors(transition_form) }}
{% set step = entity_workflow.currentStepChained %}
{% set labels = workflow_metadata(entity_workflow, 'label', step.currentStep) %}
{% set label = labels is null ? step.currentStep : labels|localize_translatable_string %}
@@ -60,8 +62,10 @@
{{ form_row(transition_form.freezeAfter) }}
{% endif %}
<div id="futureDestUsers">
<div id="futureDests">
{{ form_row(transition_form.future_dest_users) }}
{{ form_row(transition_form.future_dest_emails) }}
</div>
<p>{{ form_label(transition_form.comment) }}</p>
@@ -82,13 +86,23 @@
<p>{{ 'workflow.This workflow is finalized'|trans }}</p>
{% else %}
<p>{{ 'workflow.You are not allowed to apply a transition on this workflow'|trans }}</p>
<p>{{ 'workflow.Only those users are allowed'|trans }}:</p>
{% if entity_workflow.currentStep.destUser|length > 0 %}
<p><b>{{ 'workflow.Only those users are allowed'|trans }}&nbsp;:</b></p>
<ul>
{% for u in entity_workflow.currentStep.destUser -%}
<li>{{ u|chill_entity_render_box }}</li>
{%- endfor %}
</ul>
{% endif %}
<ul>
{% for u in entity_workflow.currentStep.destUser -%}
<li>{{ u|chill_entity_render_box }}</li>
{%- endfor %}
</ul>
{% if entity_workflow.currentStep.destUserByAccessKey|length > 0 %}
<p><b>{{ 'workflow.Those users are also granted to apply a transition by using an access key'|trans }}&nbsp;:</b></p>
<ul>
{% for u in entity_workflow.currentStep.destUserByAccessKey %}
<li>{{ u|chill_entity_render_box }}</li>
{% endfor %}
</ul>
{% endif %}
{% endif %}
</div>

View File

@@ -7,7 +7,7 @@
<div data-list-workflows="1"
data-workflows="{{ entity_workflows_json|json_encode|e('html_attr') }}"
data-allow-create="{{ acl }}"
data-related-entity-class="{{ blank_workflow.relatedEntityClass }}"
data-related-entity-id="{{ blank_workflow.relatedEntityId }}"
data-workflows-availables="{{ workflows_availables|json_encode()|e('html_attr') }}"
data-related-entity-class="{{ relatedEntityClass }}"
data-related-entity-id="{{ relatedEntityId }}"
data-workflows-availables="{{ workflows_available|json_encode()|e('html_attr') }}"
></div>

View File

@@ -69,15 +69,26 @@
</blockquote>
</div>
{% endif %}
{% if loop.last and step.destUser|length > 0 %}
{% if loop.last and step.allDestUser|length > 0 %}
<div class="item-row separator">
<div>
<p><b>{{ 'workflow.Users allowed to apply transition'|trans }}&nbsp;: </b></p>
<ul>
{% for u in step.destUser %}
<li>{{ u|chill_entity_render_box }}</li>
{% endfor %}
</ul>
{% if step.destUser|length > 0 %}
<p><b>{{ 'workflow.Users allowed to apply transition'|trans }}&nbsp;: </b></p>
<ul>
{% for u in step.destUser %}
<li>{{ u|chill_entity_render_box }}</li>
{% endfor %}
</ul>
{% endif %}
{% if step.destUserByAccessKey|length > 0 %}
<p><b>{{ 'workflow.Those users are also granted to apply a transition by using an access key'|trans }}&nbsp;:</b></p>
<ul>
{% for u in step.destUserByAccessKey %}
<li>{{ u|chill_entity_render_box }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endif %}

View File

@@ -0,0 +1,29 @@
{% extends '@ChillMain/layout.html.twig' %}
{% block title 'workflow.Delete workflow ?'|trans %}
{% block display_content %}
<h2>
{{ handler.entityTitle(entityWorkflow) }}
</h2>
{% include handler.template(entityWorkflow) with handler.templateData(entityWorkflow)|merge({
'display_action': false
}) %}
{% endblock %}
{% block content %}
<div class="container chill-md-10">
{{ include('@ChillMain/Util/confirmation_template.html.twig',
{
'title' : 'workflow.Delete workflow ?'|trans,
'confirm_question' : 'workflow.Are you sure you want to delete this workflow ?'|trans,
'display_content' : block('display_content'),
'cancel_route' : 'chill_main_workflow_show',
'cancel_parameters' : {'id' : entityWorkflow.id},
'form' : delete_form
} ) }}
</div>
{% endblock %}

View File

@@ -21,10 +21,12 @@
{{ encore_entry_link_tags('mod_wopi_link') }}
{% endblock %}
{% import '@ChillMain/Workflow/macro_breadcrumb.html.twig' as macro %}
{% block content %}
<div class="col-10 workflow">
<h1 class="mb-5">{{ block('title') }}</h1>
{# handler_template:
- src/Bundle/ChillPersonBundle/Resources/views/Workflow/_evaluation.html.twig
- src/Bundle/ChillPersonBundle/Resources/views/Workflow/_accompanying_period_work.html.twig
@@ -32,11 +34,26 @@
#}
<section class="step my-4">
<div class="mb-5">
{% include handler_template_title with handler_template_data|merge({'breadcrumb': true }) %}
<h2>{{ handler.entityTitle(entity_workflow) }}</h2>
{{ macro.breadcrumb({'entity_workflow': entity_workflow}) }}
</div>
{% include handler_template with handler_template_data|merge({'display_action': true }) %}
{% if is_granted('CHILL_MAIN_WORKFLOW_DELETE', entity_workflow) %}
<ul class="record_actions">
<li>
<a class="btn btn-delete"
href="{{ chill_path_add_return_path('chill_main_workflow_delete', {'id': entity_workflow.id}) }}"
>
{{ 'workflow.Delete workflow'|trans }}
</a>
</li>
</ul>
{% endif %}
</section>
<section class="step my-4">{% include '@ChillMain/Workflow/_follow.html.twig' %}</section>
<section class="step my-4">{% include '@ChillMain/Workflow/_decision.html.twig' %}</section>{#
<section class="step my-4">{% include '@ChillMain/Workflow/_comment.html.twig' %}</section> #}

View File

@@ -8,9 +8,10 @@
{% block content %}
<div class="col-10 workflow">
<h1 class="mb-5">{{ block('title') }}</h1>
<ul class="nav nav-pills justify-content-center">
<li class="nav-item">
<a href="{{ path('chill_main_workflow_list_subscribed') }}"
@@ -24,8 +25,24 @@
{{ 'workflow.dest'|trans }}
</a>
</li>
<li class="nav-item">
<a href="{{ path('chill_main_workflow_list_previous_without_reaction') }}"
class="nav-link {% if step == 'previous_without_reaction' %}active{% endif %}">
{{ 'workflow.Previous dest without reaction'|trans }}
</a>
</li>
<li class="nav-item">
<a href="{{ path('chill_main_workflow_list_previous_transitionned') }}"
class="nav-link {% if step == 'previous_transitionned' %}active{% endif %}">
{{ 'workflow.Previous transitionned'|trans }}
</a>
</li>
</ul>
{% if help is defined %}
<p style="margin-top: 2rem;">{{ help|trans }}</p>
{% endif %}
{% if workflows|length == 0 %}
<p class="chill-no-data-statement">{{ 'workflow.No workflow'|trans }}</p>
{% else %}
@@ -36,26 +53,24 @@
<button type="button" class="accordion-button collapsed"
data-bs-toggle="collapse" data-bs-target="#flush-collapse-{{ l.entity_workflow.id }}"
aria-expanded="false" aria-controls="flush-collapse-{{ l.entity_workflow.id }}">
<div class="item-row col">
<h2>
{{ 'workflow_'|trans }}
{{ l.handler.entityTitle(l.entity_workflow) }}
</h2>
{% include l.handler.templateTitle(l.entity_workflow) with l.handler.templateTitleData(l.entity_workflow)|merge({
'description': true,
'add_classes': 'ms-3 h3'
}) %}
</div>
</button>
{{ macro.breadcrumb(l) }}
<div>
{{ macro.breadcrumb(l) }}
</div>
</div>
<div id="flush-collapse-{{ l.entity_workflow.id }}"
class="accordion-collapse collapse"
aria-labelledby="flush-heading-{{ l.entity_workflow.id }}"
data-bs-parent="#workflow-fold">
<div class="item-row flex-column">
{% include l.handler.template(l.entity_workflow) with l.handler.templateData(l.entity_workflow)|merge({
'display_action': false
@@ -78,6 +93,13 @@
</div>
<div class="item-col">
<ul class="record_actions">
{% if is_granted('CHILL_MAIN_WORKFLOW_DELETE', l.entity_workflow) %}
<li>
<a class="btn btn-delete"
href="{{ chill_path_add_return_path('chill_main_workflow_delete', {'id': l.entity_workflow.id}) }}"
></a>
</li>
{% endif %}
<li>
<a href="{{ path('chill_main_workflow_show', {'id': l.entity_workflow.id}) }}"
class="btn btn-show">
@@ -87,7 +109,7 @@
</ul>
</div>
</div>
</div>
</div>
{% endfor %}

View File

@@ -0,0 +1,15 @@
Madame, Monsieur,
Un suivi "{{ workflow.text }}" a atteint une nouvelle étape: {{ workflow.text }}.
Titre du workflow: "{{ entityTitle }}".
Vous êtes invité·e à valider cette étape. Pour obtenir un accès, vous pouvez cliquer sur le lien suivant:
{{ absolute_url(path('chill_main_workflow_grant_access_by_key', {'id': entity_workflow.currentStep.id, 'accessKey': entity_workflow.currentStep.accessKey})) }}
Dès que vous aurez cliqué une fois sur le lien, vous serez autorisé à valider cette étape.
Notez que vous devez disposer d'un compte utilisateur valide dans Chill.
Cordialement,

View File

@@ -0,0 +1 @@
Un suivi {{ workflow.text }} demande votre attention: {{ entityTitle }}