Compare commits

...

25 Commits

Author SHA1 Message Date
1667fd0403 partially debuged proximites 2025-06-03 17:02:37 +02:00
f6292d8ad1 better cartouch css 2025-06-03 16:20:53 +02:00
f35493ea90 better cartouch css 2025-06-03 16:08:37 +02:00
bab0204ed7 commented B Latour video on doleancer 2025-06-03 13:01:28 +02:00
a9e6fe2567 fixed recording entity when switching or closing entity 2025-06-03 13:01:02 +02:00
cc943c5776 fixed concernement field recording 2025-06-03 12:38:26 +02:00
b9f9551efa drag if not editable bug fix 2025-06-02 15:21:53 +02:00
b9b04f1634 fixed entities label bug on detail zoom 2025-06-02 10:54:04 +02:00
3e25f8c678 added commit hash as release name in sentry vitejs config 2025-05-05 10:54:26 +02:00
77640c9d16 bugfix concernementmapitem this.constraint 2025-05-05 10:43:45 +02:00
2837705a38 bugfix graphql-axios 2025-05-05 10:19:50 +02:00
01d3278a6a sentry vite plugin sourcemap fixed release.name, removed test error 2025-03-21 23:16:55 +01:00
2d9f83cfef added sentry test throw error 2025-03-21 23:00:44 +01:00
0e92cbb060 @sentry/vite-plugin & sourcemap bugfix 2025-03-21 22:45:52 +01:00
5d27c489a1 @sentry/vite-plugin & sourcemap bugfix 2025-03-21 22:44:12 +01:00
629dd738f5 added @sentry/vite-plugin & sourcemap 2025-03-21 22:40:20 +01:00
78480e4958 removed sentry captur message test 2025-03-20 22:26:53 +01:00
18a90fec0a sentry captur message test 2025-03-20 22:25:15 +01:00
c63740fe1c integrated sentry/glitchtip 2025-03-20 20:45:44 +01:00
424c251f26 cercle politique admin front fine tunning 2025-03-13 14:11:29 +01:00
86074b4bb0 cercle politique admin front fine tunning 2025-03-13 12:02:21 +01:00
076a0b4c67 cercle politique admin front completed 2025-03-12 16:22:22 +01:00
64d174dcfc cercle po: adresse de la decision ok 2025-02-26 19:17:01 +01:00
77ca3a85cf cercle po: mise en œuvre de la decision ok 2025-02-26 19:06:18 +01:00
a33104e402 cercle po: active steo is visualy focused 2025-02-26 16:48:30 +01:00
16 changed files with 1743 additions and 224 deletions

2
.gitignore vendored
View File

@ -14,6 +14,8 @@ dist-ssr
coverage coverage
*.local *.local
.env
/cypress/videos/ /cypress/videos/
/cypress/screenshots/ /cypress/screenshots/

979
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -13,9 +13,13 @@
"@material-design-icons/svg": "^0.14.2", "@material-design-icons/svg": "^0.14.2",
"@mdi/font": "^7.1.96", "@mdi/font": "^7.1.96",
"@mdi/js": "^7.2.96", "@mdi/js": "^7.2.96",
"@sentry/browser": "^9.7.0",
"@sentry/integrations": "^7.114.0",
"@sentry/vue": "^9.7.0",
"@tweenjs/tween.js": "^21.0.0", "@tweenjs/tween.js": "^21.0.0",
"@vojtechlanka/vue-simple-suggest": "^2.0.6", "@vojtechlanka/vue-simple-suggest": "^2.0.6",
"@vuepic/vue-datepicker": "^11.0.1", "@vuepic/vue-datepicker": "^11.0.1",
"dotenv": "^16.4.7",
"fabric": "^6.0.0-beta7", "fabric": "^6.0.0-beta7",
"granim": "^2.0.0", "granim": "^2.0.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
@ -35,6 +39,7 @@
"devDependencies": { "devDependencies": {
"@rollup/plugin-graphql": "^2.0.0", "@rollup/plugin-graphql": "^2.0.0",
"@rushstack/eslint-patch": "^1.1.4", "@rushstack/eslint-patch": "^1.1.4",
"@sentry/vite-plugin": "^3.2.2",
"@types/medium-editor": "^5.0.8", "@types/medium-editor": "^5.0.8",
"@vitejs/plugin-vue": "^4.4.0", "@vitejs/plugin-vue": "^4.4.0",
"@vue/eslint-config-prettier": "^8.0.0", "@vue/eslint-config-prettier": "^8.0.0",

View File

@ -21,8 +21,11 @@ export default {
} }
}, },
created () { created () {
this.loadContentTypeDefinition(); this.loadContentTypeDefinition()
this.loadConcernements() this.loadConcernements()
// setTimeout(()=>{
// throw new Error("sentry test error");
// })
}, },
mounted () { mounted () {
console.log('APP onMounted') console.log('APP onMounted')

View File

@ -21,8 +21,8 @@ MGQ.interceptors.response.use(
return Promise.resolve(response) return Promise.resolve(response)
}, },
error => { error => {
const { status } = error.response // const { status } = error.response
console.warn('error in graphql-axios', status) // console.warn('error in graphql-axios', status)
// if (status === 403) { // if (status === 403) {
// window.location = '/' // window.location = '/'
// } // }

View File

@ -224,7 +224,7 @@ div.loading{
box-sizing: border-box; box-sizing: border-box;
width:$cartouch_width_full; width:$cartouch_width_full;
height: 100%; height: 100%;
padding: 2rem 2rem 1rem; padding: 1rem 1rem 1rem;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
// //
@ -263,7 +263,7 @@ div.loading{
// layout // layout
>header{ >header{
flex: 0 0 auto; flex: 0 0 auto;
padding: 0 0 1em 0; // padding: 0 0 1em 0;
} }
>main{ >main{
flex: 1 1 auto; flex: 1 1 auto;
@ -305,7 +305,7 @@ div.loading{
// display: flex; // display: flex;
// flex-direction: column; // flex-direction: column;
// justify-content: flex-end; // justify-content: flex-end;
padding-bottom: 0.5em; // padding-bottom: 0.5em;
label, h3{ label, h3{
// height: 70px; // height: 70px;
box-sizing: border-box; box-sizing: border-box;
@ -325,22 +325,30 @@ div.loading{
font-weight: bold; font-weight: bold;
} }
} }
// span.menacemaintient{
// display: block; section.entite-params{
// font-weight: 100; padding:0.5em 0;
// font-size: 0.882em; display: flex;
// padding: 1em 0; flex-direction: row;
// } gap:0.5em;
align-items: center;
>section.editable{
// margin: 0.3em;
flex: 1 0 auto;
}
}
} }
div.concernement-cartouche-icons{ div.concernement-cartouche-icons{
margin-bottom: 1em;
h2{ h2{
font-weight: 400; font-weight: 500;
font-size: 1.512em; font-size: 1.512em;
// &.faded{ // &.faded{
// font-weight: 100; // font-weight: 100;
// } // }
padding-bottom: 0.5em; padding-bottom: 0.5em;
margin-top: 0;
overflow: hidden; overflow: hidden;
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
@ -379,13 +387,23 @@ div.loading{
transition: max-height 0.5s ease-in-out,padding 0.5s ease-in-out; transition: max-height 0.5s ease-in-out,padding 0.5s ease-in-out;
max-height: 100px; max-height: 100px;
overflow: hidden; overflow: hidden;
&.hidden{ // &.hidden{
max-height: 0; // max-height: 0;
padding-bottom: 0; // padding-bottom: 0;
// }
}
}
&.entity-opened{
>header{
div.concernement-cartouche-icons{
label{
max-height: 0;
padding-bottom: 0;
}
} }
} }
} }
>main{ >main{
overflow-y: auto; overflow-y: auto;
padding-top: $gradpad; padding-top: $gradpad;
@ -699,7 +717,7 @@ div.loading{
span.date{ span.date{
@include font_questions(); @include font_questions();
display: block; display: block;
padding: 0 0 1em 0; padding: 0 0 0.3em 0;
} }
ul, li{ ul, li{
padding:0; margin:0; padding:0; margin:0;
@ -1065,7 +1083,7 @@ div.dp__main{
border-radius: 5px; border-radius: 5px;
$p:0.3em; $p:0.3em;
padding:$p; padding:$p;
margin:0.5em 0 0 -$p; margin:0 0 0 -$p;
box-sizing: border-box; box-sizing: border-box;
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
box-shadow: 2px 2px 4px #bbb; box-shadow: 2px 2px 4px #bbb;
@ -1305,7 +1323,10 @@ div.add-cerclepo-btn,
div.add-groupinteret-btn, div.add-groupinteret-btn,
div.add-adressedoleance-btn, div.add-adressedoleance-btn,
div.add-receptiontraitement-btn, div.add-receptiontraitement-btn,
div.add-decision-btn{ div.add-decision-btn,
div.add-miseenoeuvre-btn,
div.add-adressedecision-btn,
div.add-receptionapplicationdecision-btn{
@include add-btn(); @include add-btn();
margin: 0 0 1em; margin: 0 0 1em;
height: 60px; height: 60px;

View File

@ -87,7 +87,8 @@ export default {
'detailsZoomValue', 'detailsZoomValue',
'reloadConcernements', 'reloadConcernements',
'reloadConcernementEntites', 'reloadConcernementEntites',
'concernements_loading_nb']), 'concernements_loading_nb',
'concernement_is_updating_nid']),
...mapState(CommonStore,['hover_elmt', ...mapState(CommonStore,['hover_elmt',
'map_item_ray', 'map_item_ray',
'cartouch_width', 'cartouch_width',
@ -382,6 +383,7 @@ export default {
console.log(`${this.id} watch concernement.doleances o, n`, o, n); console.log(`${this.id} watch concernement.doleances o, n`, o, n);
if (this.is_open && this.map_mode === "doleancer") { if (this.is_open && this.map_mode === "doleancer") {
this.setPaperDoleances(true); // true for update=true this.setPaperDoleances(true); // true for update=true
this.focusOpenedDoleanceStep();
} }
}, },
deep: true deep: true
@ -395,6 +397,13 @@ export default {
}, },
deep: true deep: true
}, },
'concernement.opened_doleance': {
handler (n, o) {
console.log(`${this.id} watch concernement.opened_doleance o, n`, o, n);
this.focusOpenedDoleanceStep();
},
deep: true
},
wait: { wait: {
handler (n, o){ handler (n, o){
// when we are reloading entites par exemple // when we are reloading entites par exemple
@ -1139,6 +1148,8 @@ export default {
opacity: 0 opacity: 0
}); });
g.addChild(g_label); g.addChild(g_label);
// when we are re-setting the entitie (e.g. arfter one entity moved) also check the detail zoom and apply correct dim
g_label.opacity = -2 + this.detailsZoomValue;
g_label.sendToBack(); g_label.sendToBack();
// for (let i = 0; i < this.entites.length; i++) { // for (let i = 0; i < this.entites.length; i++) {
for (let i = 0; i < this.concernement.revisions_byid[this.active_revision].entites.length; i++) { for (let i = 0; i < this.concernement.revisions_byid[this.active_revision].entites.length; i++) {
@ -1228,6 +1239,7 @@ export default {
label.addChild(label_bg); label.addChild(label_bg);
label_txt.insertAbove(label_bg); label_txt.insertAbove(label_bg);
label_click_zone.insertAbove(label_txt); label_click_zone.insertAbove(label_txt);
label.scale(this.scale);
// label.sendToBack(); // label.sendToBack();
g_label.addChild(label); g_label.addChild(label);
@ -1453,10 +1465,14 @@ export default {
}); // end of loop on proximite for each main entite }); // end of loop on proximite for each main entite
let activeEntites = this.getActiveEntites(allEntiteRefConcernementContourEntites); // WARNING allEntiteRefConcernementContourEntites does contains entities just display infos so WHY getActiveEntities() it CAN'T work
// let activeEntites = this.getActiveEntites(allEntiteRefConcernementContourEntites);
// console.log('activeEntites', activeEntites);
// general contour arround proximité // general contour arround proximité
// console.log('allEntiteRefConcernementContourEntites', allEntiteRefConcernementContourEntites); // console.log('allEntiteRefConcernementContourEntites', allEntiteRefConcernementContourEntites);
let genContoursEntite = this.getJarvisEnvelopeConvexeEntites(activeEntites); // let genContoursEntite = this.getJarvisEnvelopeConvexeEntites(activeEntites);
let genContoursEntite = this.getJarvisEnvelopeConvexeEntites(allEntiteRefConcernementContourEntites);
// console.log('genContoursEntite', genContoursEntite); // console.log('genContoursEntite', genContoursEntite);
let points = []; let points = [];
genContoursEntite.forEach(ent => { genContoursEntite.forEach(ent => {
@ -2209,8 +2225,9 @@ export default {
} else if(!this.doleance_transition) { } else if(!this.doleance_transition) {
this.concernement.doleances.forEach((d) => { this.concernement.doleances.forEach((d) => {
this.paper_main_object.children.doleances.children[`doleance_${d.id}`].visible = d.id === this.concernement.opened_doleance.id; this.paper_main_object.children.doleances.children[`doleance_${d.id}`].visible = d.id === this.concernement.opened_doleance.id;
}) })
} }
} }
} else { } else {
// this.paper_main_object.children.doleance_icon.visible = false; // this.paper_main_object.children.doleance_icon.visible = false;
@ -2238,20 +2255,62 @@ export default {
} }
}) })
} }
let labels_group = this.paper_main_object.children['entites'].children['entites_labels']; if (this.paper_main_object.children && this.paper_main_object.children['entites']) {
if (labels_group) { let labels_group = this.paper_main_object.children['entites'].children['entites_labels'];
labels_group.children.forEach((item) => { if (labels_group) {
if (this.opened_entite_id && item.item_id === parseInt(this.opened_entite_id) && item.item_type !== 'entite_hidden') { labels_group.children.forEach((item) => {
item.bringToFront(); if (this.opened_entite_id && item.item_id === parseInt(this.opened_entite_id) && item.item_type !== 'entite_hidden') {
item.children[0].strokeColor = "#01ffe2"; item.bringToFront();
}else{ item.children[0].strokeColor = "#01ffe2";
// item.children[0].strokeColor = "#fff"; }else{
} // item.children[0].strokeColor = "#fff";
}) }
})
}
} }
} }
},
focusOpenedDoleanceStep(){
console.log('focusOpenedDoleanceStep', this.concernement.opened_doleance);
if (this.concernement.has_doleance) {
if (this.map_mode === "doleancer") {
if (this.is_open) {
// focus on opened doleance step
if (this.concernement.opened_doleance.field) {
let paper_doleance = this.paper_main_object.children.doleances.children[`doleance_${this.concernement.opened_doleance.id}`];
// console.log('paper_doleance', paper_doleance);
paper_doleance.children.forEach((step) =>{
// console.log('step.item_type', step.item_type);
let active = false;
if (step.field === this.concernement.opened_doleance.field) {
if(typeof this.concernement.opened_doleance.field_index != 'undefined'){
// we have an index, let find if we have the right step here
if (this.concernement.opened_doleance.field_index === step.field_index) {
active = true;
}
}else{
// we do not have a field index, so it is a single step, so it is active no matter the index
active = true
}
}
if (active) {
// step.data.prevStrokeColor is for hover_elmt watch in MapConcernements.vue
step.data.prevStrokeColor = step.strokeColor = "#01ffe2";
step.bringToFront();
} else {
step.data.prevStrokeColor = step.strokeColor = "#fff";
}
});
}
}
}
}
}, },
initDoleanceTransition(from, to){ initDoleanceTransition(from, to){
if (!this.doleance_transition) { if (!this.doleance_transition) {
@ -2570,21 +2629,29 @@ export default {
if (group_to_hit) { if (group_to_hit) {
let result = group_to_hit.hitTest(event.point); let result = group_to_hit.hitTest(event.point);
console.log('click result', result); console.log('click result', result);
if (result) { if (result && result.item.item_id && (result.item.name != "label_click_zone" || this.detailsZoomValue > 2)) {
switch (this.map_mode) { switch (this.map_mode) {
case "terraindevie": case "terraindevie":
case "superposition": case "superposition":
case "action": case "action":
// we have clicked on an entite // we have clicked on an entite
this.$router.push({ // unfocus any active element to trigger recording if needed
name: 'concernement', document.activeElement.blur();
params: {cid: this.cid, eid: result.item.item_id}, // setInterval to let time for editable fields to focus out and record changes
query: { let interval = setInterval(() => {
mapitemid: this.id, if (!this.concernement_is_updating_nid) {
// superposition_id: this.mapitem.superposition_ids[0] clearInterval(interval);
}, this.$router.push({
hash: `#${this.map_mode}`, name: 'concernement',
}); params: {cid: this.cid, eid: result.item.item_id},
query: {
mapitemid: this.id,
// superposition_id: this.mapitem.superposition_ids[0]
},
hash: `#${this.map_mode}`,
});
}
}, 1)
break; break;
case "proximite": case "proximite":
switch (result.item.item_type) { switch (result.item.item_type) {
@ -2615,11 +2682,20 @@ export default {
} else { } else {
// otherwise we close the entite and come back to the concernement // otherwise we close the entite and come back to the concernement
this.$router.push({ // unfocus any active element to trigger recording if needed
name: 'concernement', document.activeElement.blur();
hash: `#${this.map_mode}`, // setInterval to let time for editable fields to focus out and record changes
params: {id: this.cid, mapitemid: this.id} let interval = setInterval(() => {
}); if (!this.concernement_is_updating_nid) {
clearInterval(interval);
this.$router.push({
name: 'concernement',
hash: `#${this.map_mode}`,
params: {id: this.cid, mapitemid: this.id}
});
}
}, 1)
// reset the mousehover // reset the mousehover
this.resetHoverElmt(); this.resetHoverElmt();
@ -2639,10 +2715,10 @@ export default {
}.bind(this); }.bind(this);
/* /*
* works i correlation with updateDetailsZoomScale() * works in correlation with updateDetailsZoomScale()
*/ */
this.paper_main_object.onMouseDrag = async function(event){ this.paper_main_object.onMouseDrag = async function(event){
if (this.is_open && this.map_mode === 'terraindevie' && this.concernement.can_update) { if (this.is_open && this.map_mode === 'terraindevie') { // && this.concernement.can_update
// console.log('paper concernement onMouseDrag', event, this); // console.log('paper concernement onMouseDrag', event, this);
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
@ -2701,7 +2777,7 @@ export default {
this.recordNewEntitePos(pid, af, mm, p) this.recordNewEntitePos(pid, af, mm, p)
.then((parag) => { .then((parag) => {
// then reload value // then reload value
// redrawing entites is handle by watch concernement.entites // redrawing entites is handled by watch concernement.entites
this.reloadConcernementEntites(this.concernement.id) this.reloadConcernementEntites(this.concernement.id)
.then(() => { .then(() => {
this.wait = false; this.wait = false;
@ -2974,7 +3050,9 @@ export default {
x: (this.canvas.width - this.cartouch_width) / 2, x: (this.canvas.width - this.cartouch_width) / 2,
y: this.canvas.height / 2 y: this.canvas.height / 2
}; };
this.constraint.pointA = this.pos; if (this.constraint) {
this.constraint.pointA = this.pos;
}
console.log('resetMapItemPosition', this.cartouch_width, this.pos); console.log('resetMapItemPosition', this.cartouch_width, this.pos);
Matter.Body.setPosition(this.body, this.pos); Matter.Body.setPosition(this.body, this.pos);
}, },

View File

@ -61,6 +61,7 @@ export default {
'concernements', 'concernements',
'concernementsByID', 'concernementsByID',
'opened_concernement', 'opened_concernement',
'concernement_is_updating_nid',
'opened_entite_id', 'opened_entite_id',
'opened_recit', 'opened_recit',
'allSuperpositions', 'allSuperpositions',
@ -122,11 +123,17 @@ export default {
this.paper.view.onClick = function(event) { this.paper.view.onClick = function(event) {
// console.log("view onClick", this, event.target); // console.log("view onClick", this, event.target);
if(event.target._id === "paper-view-0") { if(event.target._id === "paper-view-0") {
this.resetConcernementOpened(); // // unfocus any active element to trigger recording if needed
this.$router.push({ // document.activeElement.blur();
name: 'home', // // setTimeout to let time for editable fields to focus out and record changes
hash: `#${this.map_mode}` // setTimeout(() => {
}); // this.resetConcernementOpened();
// this.$router.push({
// name: 'home',
// hash: `#${this.map_mode}`
// });
// }, 1);
this.closeConcernement();
} }
}.bind(this); }.bind(this);
@ -1543,6 +1550,26 @@ export default {
}); });
wall_rects.addChildren(children); wall_rects.addChildren(children);
} }
},
closeConcernement(){
// unfocus any active element to trigger recording if needed
document.activeElement.blur();
// setTimeout to let time for editable fields to focus out and record changes
this.waitForUpdatingEnded();
},
waitForUpdatingEnded(){
setTimeout(() => {
if (!this.concernement_is_updating_nid) {
this.resetConcernementOpened();
this.$router.push({
name: 'home',
hash: `#${this.map_mode}`
});
} else {
this.waitForUpdatingEnded();
}
}, 1);
} }
}, },
beforeUpdate () { beforeUpdate () {

View File

@ -24,8 +24,8 @@ import { mdiStickerPlusOutline } from '@mdi/js';
import ContentEditable from '@components/editable/ContentEditable.vue'; import ContentEditable from '@components/editable/ContentEditable.vue';
import DateEditable from '@components/editable/DateEditable.vue'; import DateEditable from '@components/editable/DateEditable.vue';
import SelectEditable from '@components/editable/SelectEditable.vue';
// import CheckboxEditable from '@components/editable/CheckboxEditable.vue'; // import CheckboxEditable from '@components/editable/CheckboxEditable.vue';
// import SelectEditable from '@components/editable/SelectEditable.vue';
export default { export default {
@ -67,11 +67,17 @@ export default {
}, },
receptionettraitment() { receptionettraitment() {
return this.doleance.reception_traitement[this.opened_dol.field_index]; return this.doleance.reception_traitement[this.opened_dol.field_index];
},
miseenoeuvredecision() {
return this.doleance.mise_en_oeuvre_decision[this.opened_dol.field_index];
},
receptionsetapplications() {
return this.doleance.receptions_et_applications[this.opened_dol.field_index];
} }
}, },
created () { created () {
this.concernement = this.concernementsByID[this.cid]; this.concernement = this.concernementsByID[this.cid];
console.log(`Doleancer content created, id: ${this.cid}, doleances:`,this.concernement.doleances); console.log(`Doleancer content created, id: ${this.cid}, doleances:`,this.concernement.doleances, "opened_doleance" ,this.concernement.opened_doleance);
this.concernement.doleances.forEach((doleance, index) => { this.concernement.doleances.forEach((doleance, index) => {
if (doleance.id === this.concernement.opened_doleance.id) { if (doleance.id === this.concernement.opened_doleance.id) {
this.doleance = doleance; this.doleance = doleance;
@ -104,9 +110,11 @@ export default {
} else { } else {
this.concernement = this.concernementsByID[this.cid]; this.concernement = this.concernementsByID[this.cid];
console.log(`Doleancer content created, id: ${this.cid}, doleances:`,this.concernement.doleances); console.log(`Doleancer watched opened_concernement, id: ${this.cid}, doleances:`,this.concernement.doleances, "opened_doleance", this.concernement.opened_doleance);
this.concernement.doleances.forEach((doleance, index) => { this.concernement.doleances.forEach((doleance, index) => {
if (doleance.id === this.concernement.opened_doleance.id) { if (doleance.id === this.concernement.opened_doleance.id) {
console.log('yes');
this.doleance = doleance; this.doleance = doleance;
this.doleance_index = index; this.doleance_index = index;
} }
@ -200,31 +208,61 @@ export default {
addDecision(e){ addDecision(e){
this.setOpenedDoleanceField(this.cid, this.doleance.id, "decision"); this.setOpenedDoleanceField(this.cid, this.doleance.id, "decision");
}, },
// adresse de al decision
addAdresseDecision(e){
this.setOpenedDoleanceField(this.cid, this.doleance.id, "adresse_de_la_decision");
},
// reception et application decision
addReceptionApplicationDecision(e){
this.createCerclepoParagGeneric('reception_application_decision', 'field_receptions_et_applications', 'receptions_et_applications')
.then(()=>{
this.setOpenedDoleanceField(this.cid, this.doleance.id, "receptions_et_applications", this.doleance.receptions_et_applications.length-1);
});
},
// reussite / echec
addReussiteEchec(e){
this.setOpenedDoleanceField(this.cid, this.doleance.id, "probleme_initial_resolu");
},
// groupe interet // groupe interet
addgroupInteret(e){ addgroupInteret(e){
this.createCerclepoParagGeneric('groupes_interets', 'field_groupes', 'groupesinterets'); this.createCerclepoParagGeneric('groupes_interets', 'field_groupes', 'groupesinterets')
.then(()=>{
this.setOpenedDoleanceField(this.cid, this.doleance.id, "groupesinterets", this.doleance.groupesinterets.length-1);
});
}, },
addReceptionEtTraitement(e){ addReceptionEtTraitement(e){
this.createCerclepoParagGeneric('reception_et_traitement', 'field_receptions_et_traitements', 'reception_traitement'); this.createCerclepoParagGeneric('reception_et_traitement', 'field_receptions_et_traitements', 'reception_traitement')
.then(()=>{
this.setOpenedDoleanceField(this.cid, this.doleance.id, "reception_traitement", this.doleance.reception_traitement.length-1);
});
},
addMiseEnOeuvre(e){
this.createCerclepoParagGeneric('mise_en_oeuvre_decision', 'field_mise_en_oeuvre_decision', 'mise_en_oeuvre_decision')
.then(()=>{
this.setOpenedDoleanceField(this.cid, this.doleance.id, "mise_en_oeuvre_decision", this.doleance.mise_en_oeuvre_decision.length-1);
});
}, },
createCerclepoParagGeneric(type, prt_field_name, obj_name){ createCerclepoParagGeneric(type, prt_field_name, obj_name){
console.log('createCerclepoParagGeneric',type, prt_field_name, obj_name); console.log('createCerclepoParagGeneric',type, prt_field_name, obj_name);
this.reloading_concernements = true; return new Promise((resolve, reject) => {
// 1 create paragraphe this.reloading_concernements = true;
this.createParag(type, prt_field_name) // 1 create paragraphe
.then((parag) => { this.createParag(type, prt_field_name)
console.log('createParag then parag', parag); .then((parag) => {
// 3 record on concernement field_entites console.log('createParag then parag', parag);
this.recordCerclepoParagField(parag, obj_name, prt_field_name) // 3 record on concernement field_entites
.then((cercle_politique) => { this.recordCerclepoParagField(parag, obj_name, prt_field_name)
console.log('cercle_politique', cercle_politique); .then((cercle_politique) => {
// reload concernement doleances console.log('cercle_politique', cercle_politique);
this.reloadConcernementCerclePol(this.concernement.id) // reload concernement doleances
.then(() => { this.reloadConcernementCerclePol(this.concernement.id)
this.reloading_concernements = false; .then(() => {
}); this.reloading_concernements = false;
}) resolve();
}) });
})
})
});
}, },
createParag(type, prt_field_name){ createParag(type, prt_field_name){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -353,8 +391,8 @@ export default {
SvgIcon, SvgIcon,
ContentEditable, ContentEditable,
DateEditable, DateEditable,
SelectEditable
// CheckboxEditable, // CheckboxEditable,
// SelectEditable
} }
} }
@ -388,7 +426,8 @@ export default {
<section <section
v-if="opened_dol.field === 'leprobleme' || !opened_dol.field"> v-if="opened_dol.field === 'leprobleme' || !opened_dol.field">
<!-- <span class="date">{{ doleance.date_leprobleme.start }}</span> --> <!-- <span class="date">{{ doleance.date_leprobleme.start }}</span> -->
<DateEditable <h5>{{ ct_cercle_politique.field_le_probleme.label }}</h5>
<DateEditable
:value="doleance.date_leprobleme.start" :value="doleance.date_leprobleme.start"
class="leprobleme-date" class="leprobleme-date"
:contenteditable="opened_concernement.can_update" :contenteditable="opened_concernement.can_update"
@ -399,7 +438,6 @@ export default {
field: {field_name: 'field_date_leprobleme'} field: {field_name: 'field_date_leprobleme'}
}" }"
v-on:updated="reloadConcernementCerclePol(cid)"/> v-on:updated="reloadConcernementCerclePol(cid)"/>
<h5>{{ ct_cercle_politique.field_le_probleme.label }}</h5>
<ContentEditable <ContentEditable
tag="h4" tag="h4"
:value="doleance.leprobleme" :value="doleance.leprobleme"
@ -440,6 +478,7 @@ export default {
<section <section
v-if="opened_dol.field === 'groupesinterets'" v-if="opened_dol.field === 'groupesinterets'"
class="groupesinterets"> class="groupesinterets">
<h5>Construction de groupes d'intérets avec qui composer la doléance</h5>
<span class="date"> <span class="date">
<!-- {{ groupeinteret.date.start }} <!-- {{ groupeinteret.date.start }}
&#x2192; &#x2192;
@ -459,7 +498,6 @@ export default {
}" }"
v-on:updated="reloadConcernementCerclePol(cid)"/> v-on:updated="reloadConcernementCerclePol(cid)"/>
</span> </span>
<h5>Construction de groupes d'intérets avec qui composer la doléance</h5>
<section> <section>
<label for="groupe">{{ p_groupes_interets.field_groupe_interets.label }}</label> <label for="groupe">{{ p_groupes_interets.field_groupe_interets.label }}</label>
<!-- <p <!-- <p
@ -595,6 +633,7 @@ export default {
<section <section
v-if="opened_dol.field === 'reception_traitement'" v-if="opened_dol.field === 'reception_traitement'"
class="reception_traitement"> class="reception_traitement">
<h5>Reception et traitement de la doléance</h5>
<span class="date"> <span class="date">
<!-- {{ doleance.reception_traitement[opened_dol.field_index].date.start }} <!-- {{ doleance.reception_traitement[opened_dol.field_index].date.start }}
&#x2192; &#x2192;
@ -614,7 +653,6 @@ export default {
}" }"
v-on:updated="reloadConcernementCerclePol(cid)"/> v-on:updated="reloadConcernementCerclePol(cid)"/>
</span> </span>
<h5>Reception et traitement de la doléance</h5>
<label for="entite_recoit_doleance">{{ p_reception_et_traitement.field_entite_recoit_doleance.label }}</label> <label for="entite_recoit_doleance">{{ p_reception_et_traitement.field_entite_recoit_doleance.label }}</label>
<!-- <p <!-- <p
name="entite_recoit_doleance" name="entite_recoit_doleance"
@ -747,65 +785,232 @@ export default {
<section <section
v-if="opened_dol.field === 'mise_en_oeuvre_decision'" v-if="opened_dol.field === 'mise_en_oeuvre_decision'"
class="mise_en_oeuvre_decision"> class="mise_en_oeuvre_decision">
<span class="date">
{{ doleance.mise_en_oeuvre_decision[opened_dol.field_index].date.start }}
&#x2192;
{{ doleance.mise_en_oeuvre_decision[opened_dol.field_index].date.end }}
</span>
<h5>{{ ct_cercle_politique.field_mise_en_oeuvre_decision.label }}</h5> <h5>{{ ct_cercle_politique.field_mise_en_oeuvre_decision.label }}</h5>
<span class="date">
<!-- {{ doleance.mise_en_oeuvre_decision[opened_dol.field_index].date.start }}
&#x2192;
{{ doleance.mise_en_oeuvre_decision[opened_dol.field_index].date.end }} -->
<DateEditable
:value="miseenoeuvredecision.date.start"
:end_value="miseenoeuvredecision.date.end"
class="miseenoeuvredecision-date"
:contenteditable="opened_concernement.can_update"
mode="range"
:data="{
entitytype: 'paragraph',
bundle: 'mise_en_oeuvre_decision',
id: miseenoeuvredecision.id,
revision_id: miseenoeuvredecision.revision_id,
field: {field_name: 'field_date_miseeoeuvre_decision'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
</span>
<label for="entite_adresse_decision">{{ p_mise_en_oeuvre_decision.field_entite_adresse_decision.label }}</label> <label for="entite_adresse_decision">{{ p_mise_en_oeuvre_decision.field_entite_adresse_decision.label }}</label>
<p <!-- <p name="entite_adresse_decision" v-html="doleance.mise_en_oeuvre_decision[opened_dol.field_index].entite_adresse_decision" /> -->
<ContentEditable
tag="p"
name="entite_adresse_decision" name="entite_adresse_decision"
v-html="doleance.mise_en_oeuvre_decision[opened_dol.field_index].entite_adresse_decision" /> :value="miseenoeuvredecision.entite_adresse_decision"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'paragraph',
bundle: 'mise_en_oeuvre_decision',
id: miseenoeuvredecision.id,
revision_id: miseenoeuvredecision.revision_id,
field: {field_name: 'field_entite_adresse_decision', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
<label for="formule_decision">{{ p_mise_en_oeuvre_decision.field_formule_decision.label }}</label> <label for="formule_decision">{{ p_mise_en_oeuvre_decision.field_formule_decision.label }}</label>
<p <!-- <p name="formule_decision" v-html="doleance.mise_en_oeuvre_decision[opened_dol.field_index].formule_decision" /> -->
<ContentEditable
tag="p"
name="formule_decision" name="formule_decision"
v-html="doleance.mise_en_oeuvre_decision[opened_dol.field_index].formule_decision" /> :value="miseenoeuvredecision.formule_decision"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'paragraph',
bundle: 'mise_en_oeuvre_decision',
id: miseenoeuvredecision.id,
revision_id: miseenoeuvredecision.revision_id,
field: {field_name: 'field_formule_decision', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
<label for="entite_metenoeuvre_decisio">{{ p_mise_en_oeuvre_decision.field_entite_metenoeuvre_decisio.label }}</label> <label for="entite_metenoeuvre_decisio">{{ p_mise_en_oeuvre_decision.field_entite_metenoeuvre_decisio.label }}</label>
<p <!-- <p name="entite_metenoeuvre_decisio" v-html="doleance.mise_en_oeuvre_decision[opened_dol.field_index].entite_metenoeuvre_decisio" /> -->
<ContentEditable
tag="p"
name="entite_metenoeuvre_decisio" name="entite_metenoeuvre_decisio"
v-html="doleance.mise_en_oeuvre_decision[opened_dol.field_index].entite_metenoeuvre_decisio" /> :value="miseenoeuvredecision.entite_metenoeuvre_decisio"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'paragraph',
bundle: 'mise_en_oeuvre_decision',
id: miseenoeuvredecision.id,
revision_id: miseenoeuvredecision.revision_id,
field: {field_name: 'field_entite_metenoeuvre_decisio', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
</section> </section>
<section <section
v-if="opened_dol.field === 'adresse_de_la_decision'" v-if="opened_dol.field === 'adresse_de_la_decision'"
class="adresse_de_la_decision"> class="adresse_de_la_decision">
<span class="date">{{ doleance.date_adresse.start }}</span>
<h5>Adresse de la decision à appliquer</h5> <h5>Adresse de la decision à appliquer</h5>
<!-- <span class="date">{{ doleance.date_adresse.start }}</span> -->
<DateEditable
:value="doleance.date_adresse.start"
class="adressedecision-date"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'node',
bundle: 'cercle_politique',
id: doleance.id,
field: {field_name: 'field_date_adresse_decision'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
<label for="entite_adresse_application">{{ ct_cercle_politique.field_entite_adresse_application.label }}</label> <label for="entite_adresse_application">{{ ct_cercle_politique.field_entite_adresse_application.label }}</label>
<p name="entite_adresse_application" v-html="doleance.entite_adresse_application" /> <!-- <p name="entite_adresse_application" v-html="doleance.entite_adresse_application" /> -->
<ContentEditable
tag="p"
name="entite_adresse_application"
:value="doleance.entite_adresse_doleance"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'node',
bundle: 'cercle_politique',
id: doleance.id,
field: {field_name: 'field_entite_adresse_doleance', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
<label for="aqui_adresse_decision">{{ ct_cercle_politique.field_aqui_adresse_decision.label }}</label> <label for="aqui_adresse_decision">{{ ct_cercle_politique.field_aqui_adresse_decision.label }}</label>
<p name="aqui_adresse_decision" v-html="doleance.aqui_adresse_decision" /> <!-- <p name="aqui_adresse_decision" v-html="doleance.aqui_adresse_decision" /> -->
<ContentEditable
tag="p"
name="aqui_adresse_decision"
:value="doleance.aqui_adresse_decision"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'node',
bundle: 'cercle_politique',
id: doleance.id,
field: {field_name: 'field_aqui_adresse_decision', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
<label for="comment_formule_decision">{{ ct_cercle_politique.field_comment_formule_decision.label }}</label> <label for="comment_formule_decision">{{ ct_cercle_politique.field_comment_formule_decision.label }}</label>
<p name="comment_formule_decision" v-html="doleance.comment_formule_decision" /> <!-- <p name="comment_formule_decision" v-html="doleance.comment_formule_decision" /> -->
<ContentEditable
tag="p"
name="comment_formule_decision"
:value="doleance.comment_formule_decision"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'node',
bundle: 'cercle_politique',
id: doleance.id,
field: {field_name: 'field_comment_formule_decision', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
</section> </section>
<section <section
v-if="opened_dol.field === 'receptions_et_applications'" v-if="opened_dol.field === 'receptions_et_applications'"
class="receptions_et_applications"> class="receptions_et_applications">
<span class="date"> <h5>{{ ct_cercle_politique.field_receptions_et_applications.label }}</h5>
<!-- <span class="date">
{{ doleance.receptions_et_applications[opened_dol.field_index].date.start }} {{ doleance.receptions_et_applications[opened_dol.field_index].date.start }}
&#x2192; &#x2192;
{{ doleance.receptions_et_applications[opened_dol.field_index].date.end }} {{ doleance.receptions_et_applications[opened_dol.field_index].date.end }}
</span> </span> -->
<h5>{{ ct_cercle_politique.field_receptions_et_applications.label }}</h5> <DateEditable
:value="receptionsetapplications.date.start"
:end_value="receptionsetapplications.date.end"
class="receptionsetapplications-date"
:contenteditable="opened_concernement.can_update"
mode="range"
:data="{
entitytype: 'paragraph',
bundle: 'reception_application_decision',
id: receptionsetapplications.id,
revision_id: receptionsetapplications.revision_id,
field: {field_name: 'field_date_date_traitement_decis'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
<label for="applique_decision">{{ p_reception_application_decision.field_applique_decision.label }}</label> <label for="applique_decision">{{ p_reception_application_decision.field_applique_decision.label }}</label>
<p <!-- <p
name="applique_decision" name="applique_decision"
v-html="doleance.receptions_et_applications[opened_dol.field_index].applique_decision" /> v-html="doleance.receptions_et_applications[opened_dol.field_index].applique_decision" /> -->
<ContentEditable
tag="p"
name="applique_decision"
:value="receptionsetapplications.applique_decision"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'paragraph',
bundle: 'reception_application_decision',
id: receptionsetapplications.id,
revision_id: receptionsetapplications.revision_id,
field: {field_name: 'field_applique_decision', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
<label for="formule_decision_applic">{{ p_reception_application_decision.field_formule_decision_applic.label }}</label> <label for="formule_decision_applic">{{ p_reception_application_decision.field_formule_decision_applic.label }}</label>
<p <!-- <p
name="formule_decision_applic" name="formule_decision_applic"
v-html="doleance.receptions_et_applications[opened_dol.field_index].formule_decision_applic" /> v-html="doleance.receptions_et_applications[opened_dol.field_index].formule_decision_applic" /> -->
<ContentEditable
tag="p"
name="formule_decision_applic"
:value="receptionsetapplications.formule_decision_applic"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'paragraph',
bundle: 'reception_application_decision',
id: receptionsetapplications.id,
revision_id: receptionsetapplications.revision_id,
field: {field_name: 'field_formule_decision_applic', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
<label for="entite_recoit_decision">{{ p_reception_application_decision.field_entite_recoit_decision.label }}</label> <label for="entite_recoit_decision">{{ p_reception_application_decision.field_entite_recoit_decision.label }}</label>
<p <!-- <p
name="entite_recoit_decision" name="entite_recoit_decision"
v-html="doleance.receptions_et_applications[opened_dol.field_index].entite_recoit_decision" /> v-html="doleance.receptions_et_applications[opened_dol.field_index].entite_recoit_decision" /> -->
<ContentEditable
tag="p"
name="entite_recoit_decision"
:value="receptionsetapplications.entite_recoit_decision"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'paragraph',
bundle: 'reception_application_decision',
id: receptionsetapplications.id,
revision_id: receptionsetapplications.revision_id,
field: {field_name: 'field_entite_recoit_decision', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
</section> </section>
<section <section
@ -815,19 +1020,59 @@ export default {
<h5>Réussite / échec / reprise du cercle politique</h5> <h5>Réussite / échec / reprise du cercle politique</h5>
<label for="probleme_initial_resolu">{{ ct_cercle_politique.field_probleme_initial_resolu.label }}</label> <label for="probleme_initial_resolu">{{ ct_cercle_politique.field_probleme_initial_resolu.label }}</label>
<p <!-- <p
name="probleme_initial_resolu" name="probleme_initial_resolu"
v-html="doleance.probleme_initial_resolu" /> v-html="doleance.probleme_initial_resolu" /> -->
<SelectEditable
label="résolu"
:value="doleance.probleme_initial_resolu"
:options="{
'0': 'non',
'1': 'oui'}"
:data="{
entitytype: 'node',
bundle: 'cercle_politique',
nid: doleance.id,
field: 'field_probleme_initial_resolu'}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
<label for="oui_nouvelle_situation">{{ ct_cercle_politique.field_oui_nouvelle_situation.label }}</label> <label for="oui_nouvelle_situation">{{ ct_cercle_politique.field_oui_nouvelle_situation.label }}</label>
<p <!-- <p
name="oui_nouvelle_situation" name="oui_nouvelle_situation"
v-html="doleance.oui_nouvelle_situation" /> v-html="doleance.oui_nouvelle_situation" /> -->
<ContentEditable
tag="p"
name="oui_nouvelle_situation"
:value="doleance.oui_nouvelle_situation"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'node',
bundle: 'cercle_politique',
id: doleance.id,
field: {field_name: 'field_oui_nouvelle_situation', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
<label for="non_adresse_doleance">{{ ct_cercle_politique.field_non_adresse_doleance.label }}</label> <label for="non_adresse_doleance">{{ ct_cercle_politique.field_non_adresse_doleance.label }}</label>
<p <!-- <p
name="non_adresse_doleance" name="non_adresse_doleance"
v-html="doleance.non_adresse_doleance" /> v-html="doleance.non_adresse_doleance" /> -->
<ContentEditable
tag="p"
name="non_adresse_doleance"
:value="doleance.non_adresse_doleance"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="opened_concernement.can_update"
:data="{
entitytype: 'node',
bundle: 'cercle_politique',
id: doleance.id,
field: {field_name: 'field_non_adresse_doleance', value:'value'}
}"
v-on:updated="reloadConcernementCerclePol(cid)"/>
</section> </section>
</template> </template>
</section> </section>
@ -835,11 +1080,22 @@ export default {
<template v-slot:footer> <template v-slot:footer>
<template v-if="concernement.can_update"> <template v-if="concernement.can_update && opened_concernement.opened_doleance">
<template v-if="opened_concernement.opened_doleance.field === 'decision' || opened_concernement.opened_doleance.field === 'mise_en_oeuvre_decision'">
<div
v-if="!reloading_concernements"
@click="addMiseEnOeuvre"
class="add-miseenoeuvre-btn btn">
<span>Ajouter une mise-en-œuvre de la décision</span>
<svg-icon type="mdi" :path="mdiStickerPlusOutline_path"/>
</div>
<div v-else class="add-miseenoeuvre-btn btn">
<div class="loading">Chargement</div>
</div>
</template>
<template v-if="opened_concernement.opened_doleance.field === 'adresse_de_la_doleance' || opened_concernement.opened_doleance.field === 'reception_traitement'">
<template v-if="opened_concernement.opened_doleance.field === 'adresse_de_la_doleance' || opened_concernement.opened_doleance.field === 'reception_et_traitement'">
<div <div
v-if="!reloading_concernements" v-if="!reloading_concernements"
@click="addReceptionEtTraitement" @click="addReceptionEtTraitement"
@ -852,7 +1108,6 @@ export default {
</div> </div>
</template> </template>
<template v-if="opened_concernement.opened_doleance.field === 'lenquete' || opened_concernement.opened_doleance.field === 'groupesinterets'"> <template v-if="opened_concernement.opened_doleance.field === 'lenquete' || opened_concernement.opened_doleance.field === 'groupesinterets'">
<div <div
v-if="!reloading_concernements" v-if="!reloading_concernements"
@ -865,16 +1120,42 @@ export default {
<div class="loading">Chargement</div> <div class="loading">Chargement</div>
</div> </div>
</template> </template>
<template v-if="opened_concernement.opened_doleance.field === 'groupesinterets'"> <template v-if="opened_concernement.opened_doleance.field === 'adresse_de_la_decision' || opened_concernement.opened_doleance.field === 'receptions_et_applications'">
<div <div
v-if="!reloading_concernements" v-if="!reloading_concernements"
@click="addAdresseDoleance" @click="addReceptionApplicationDecision"
class="add-adressedoleance-btn btn"> class="add-receptionapplicationdecision-btn btn">
<span>Adresse de la doléance</span> <span>Ajouter réception et application</span>
<svg-icon type="mdi" :path="mdiStickerPlusOutline_path"/> <svg-icon type="mdi" :path="mdiStickerPlusOutline_path"/>
</div> </div>
<div v-else class="add-adressedoleance-btn btn"> <div v-else class="add-receptionapplicationdecision-btn btn">
<div class="loading">Chargement</div>
</div>
</template>
<template v-if="opened_concernement.opened_doleance.field === 'receptions_et_applications'">
<div
v-if="!reloading_concernements"
@click="addReussiteEchec"
class="add-receptionapplicationdecision-btn btn">
<span>Reussite / échec</span>
<svg-icon type="mdi" :path="mdiStickerPlusOutline_path"/>
</div>
<div v-else class="add-receptionapplicationdecision-btn btn">
<div class="loading">Chargement</div>
</div>
</template>
<template v-if="opened_concernement.opened_doleance.field === 'mise_en_oeuvre_decision'">
<div
v-if="!reloading_concernements"
@click="addAdresseDecision"
class="add-adressedecision-btn btn">
<span>Adresse de la décision à appliquer</span>
<svg-icon type="mdi" :path="mdiStickerPlusOutline_path"/>
</div>
<div v-else class="add-adressedecision-btn btn">
<div class="loading">Chargement</div> <div class="loading">Chargement</div>
</div> </div>
</template> </template>
@ -892,30 +1173,43 @@ export default {
</div> </div>
</template> </template>
<template v-if="opened_concernement.opened_doleance.field === 'leprobleme' || opened_concernement.opened_doleance.field === 'lenquete'"> <template v-if="opened_concernement.opened_doleance.field === 'groupesinterets'">
<div v-if="!reloading_concernements" <div
@click="addCerclePo" v-if="!reloading_concernements"
class="add-cerclepo-btn btn"> @click="addAdresseDoleance"
<span>Ajouter un cercle politique</span> class="add-adressedoleance-btn btn">
<span>Adresse de la doléance</span>
<svg-icon type="mdi" :path="mdiStickerPlusOutline_path"/> <svg-icon type="mdi" :path="mdiStickerPlusOutline_path"/>
</div> </div>
<div v-else class="add-cerclepo-btn btn"> <div v-else class="add-adressedoleance-btn btn">
<div class="loading">Chargement</div> <div class="loading">Chargement</div>
</div> </div>
</template> </template>
</template> </template>
<template v-if="!opened_concernement.opened_doleance || opened_concernement.opened_doleance.field === 'leprobleme' || opened_concernement.opened_doleance.field === 'lenquete'">
<div v-if="!reloading_concernements"
@click="addCerclePo"
class="add-cerclepo-btn btn">
<span>Ajouter un cercle politique</span>
<svg-icon type="mdi" :path="mdiStickerPlusOutline_path"/>
</div>
<div v-else class="add-cerclepo-btn btn">
<div class="loading">Chargement</div>
</div>
</template>
<!-- <vue-plyr> <!-- <vue-plyr>
<div class="plyr__video-embed"> --> <div class="plyr__video-embed"> -->
<iframe <!-- <iframe
v-if="opened_concernement.opened_doleance.field === 'leprobleme' || opened_concernement.opened_doleance.field === 'lenquete'" v-if="!opened_concernement.opened_doleance || opened_concernement.opened_doleance.field === 'leprobleme' || opened_concernement.opened_doleance.field === 'lenquete'"
src="https://www.youtube.com/embed/_Uogb4tJ9c4?amp;iv_load_policy=3&amp;modestbranding=1&amp;playsinline=1&amp;showinfo=0&amp;rel=0&amp;enablejsapi=1" src="https://www.youtube.com/embed/_Uogb4tJ9c4?amp;iv_load_policy=3&amp;modestbranding=1&amp;playsinline=1&amp;showinfo=0&amp;rel=0&amp;enablejsapi=1"
allowfullscreen allowfullscreen
allowtransparency allowtransparency
frameborder="0" frameborder="0"
></iframe> ></iframe> -->
<!-- </div> <!-- </div>
</vue-plyr> --> </vue-plyr> -->
</template> </template>

View File

@ -211,8 +211,10 @@ export default {
...mapActions(ConcernementsStore, ['setActiveRevision', ...mapActions(ConcernementsStore, ['setActiveRevision',
'setDetailsZoomValue', 'setDetailsZoomValue',
'loadConcernements', 'loadConcernements',
'setConcernementIsUpdating',
'reloadConcernements', 'reloadConcernements',
'reloadConcernementEntites', 'reloadConcernementEntites',
'reloadConcernementField',
'reloadProximites' 'reloadProximites'
]), ]),
...mapActions(UserStore, ['getUserEntitees']), ...mapActions(UserStore, ['getUserEntitees']),
@ -258,6 +260,22 @@ export default {
this.headerreduced = false; this.headerreduced = false;
} }
}, },
// triggered when focus out and gql patch xhr triggered
onFieldIsUpdating(cid){
this.setConcernementIsUpdating(cid);
},
// triggered when gql patch done
onFieldUpdated(cid){
this.setConcernementIsUpdating(null);
this.reloadConcernementEntites(cid);
},
concernementFieldIsUpdating(field){
this.setConcernementIsUpdating(this.cid);
},
concernementFieldUpdated(field){
this.setConcernementIsUpdating(null);
this.reloadConcernementField(this.cid, field);
},
onContentEditableFocusOut(e){ onContentEditableFocusOut(e){
console.log('onContentEditableFocusOut', e); console.log('onContentEditableFocusOut', e);
let new_field_content = e.target.innerText; let new_field_content = e.target.innerText;
@ -513,7 +531,7 @@ export default {
</script> </script>
<template> <template>
<CartoucheLayout ref="cartouche_layout" :cid="cid" @main_scrolled="onMainScrolled"> <CartoucheLayout ref="cartouche_layout" :cid="cid" :eid="eid" @main_scrolled="onMainScrolled">
<template v-slot:header> <template v-slot:header>
<div class="entite"> <div class="entite">
<!-- TODO update entite with revisions --> <!-- TODO update entite with revisions -->
@ -531,7 +549,8 @@ export default {
id: this.entite.id, id: this.entite.id,
field: {field_name: 'title', value:'value'} field: {field_name: 'title', value:'value'}
}" }"
v-on:updated="reloadConcernementEntites(cid)"/> v-on:updating="onFieldIsUpdating(cid)"
v-on:updated="onFieldUpdated(cid)"/>
<!-- proximité --> <!-- proximité -->
<section <section
@ -575,44 +594,44 @@ export default {
</div> </div>
</section> </section>
<!-- active --> <section class="entite-params" v-if="entite && entite.can_update">
<CheckboxEditable <!-- active -->
v-if="entite && entite.can_update" <CheckboxEditable
:checked="this.parag_entite.active" :checked="this.parag_entite.active"
label="Active" label="Active"
:data="{ :data="{
entitytype: 'paragraph', entitytype: 'paragraph',
bundle: 'entite_concernement', bundle: 'entite_concernement',
id: this.parag_entite.id, id: this.parag_entite.id,
field: 'field_active'}" field: 'field_active'}"
v-on:updated="reloadConcernementEntites(cid)"/> v-on:updated="reloadConcernementEntites(cid)"/>
<!-- agissante --> <!-- agissante -->
<CheckboxEditable <CheckboxEditable
v-if="entite && entite.can_update" :checked="entite.agissante"
:checked="entite.agissante" label="Entité action"
label="Entité action" :data="{
:data="{ entitytype: 'node',
entitytype: 'node', bundle: 'entite',
bundle: 'entite', id: this.entite.id,
id: this.entite.id, field: 'field_entite_agissante'}"
field: 'field_entite_agissante'}" v-on:updated="reloadConcernementEntites(cid)"/>
v-on:updated="reloadConcernementEntites(cid)"/>
<SelectEditable <!-- confidentialité -->
v-if="entite && entite.can_update" <SelectEditable
label="Confidentialité" label="Confidentialité"
:value="entite.confidentialite" :value="entite.confidentialite"
:options="{ :options="{
'confidentialite_prive': 'privé', 'confidentialite_prive': 'privé',
'confidentialite_interne': 'interne', 'confidentialite_interne': 'interne',
'confidentialite_public': 'public'}" 'confidentialite_public': 'public'}"
:data="{ :data="{
entitytype: 'node', entitytype: 'node',
bundle: 'entite', bundle: 'entite',
nid: this.entite.id, nid: this.entite.id,
field: 'field_confidentialite'}" field: 'field_confidentialite'}"
v-on:updated="reloadConcernementEntites(cid)"/> v-on:updated="reloadConcernementEntites(cid)"/>
</section>
</div> </div>
@ -635,7 +654,9 @@ export default {
bundle: 'concernement', bundle: 'concernement',
id: this.concernement.id, id: this.concernement.id,
field: {field_name: 'field_description', value:'value'} field: {field_name: 'field_description', value:'value'}
}" /> }"
v-on:updating="concernementFieldIsUpdating('description')"
v-on:updated="concernementFieldUpdated('description')"/>
</section> </section>
<section v-if="concernement.caillou || concernement.can_update" class="caillou"> <section v-if="concernement.caillou || concernement.can_update" class="caillou">
@ -651,7 +672,9 @@ export default {
bundle: 'concernement', bundle: 'concernement',
id: this.concernement.id, id: this.concernement.id,
field: {field_name: 'field_caillou', value:'value'} field: {field_name: 'field_caillou', value:'value'}
}" /> }"
v-on:updating="concernementFieldIsUpdating('caillou')"
v-on:updated="concernementFieldUpdated('caillou')"/>
</section> </section>
<template v-if="concernement.can_update"> <template v-if="concernement.can_update">
@ -666,7 +689,15 @@ export default {
</template> </template>
<!-- entite --> <!-- entite -->
<Entite v-if="entite" :concernement="concernement" :entite="entite" :eid="eid" v-on:reloadEntite="loadEntite"/> <Entite
v-if="entite"
:concernement="concernement"
:entite="entite"
:eid="eid"
v-on:reloadEntite="loadEntite"/>
<!-- v-on:updating="onFieldIsUpdating(cid)"
v-on:updated="onFieldUpdated(cid)" -->
</template> </template>
<template v-slot:footer> <template v-slot:footer>

View File

@ -29,7 +29,7 @@ export default {
default : 'Ajouter du texte' default : 'Ajouter du texte'
} }
}, },
emits: ['updated'], emits: ['updating', 'updated'],
data(){ data(){
return { return {
editor: null, editor: null,
@ -74,6 +74,7 @@ export default {
} }
}, },
save(content){ save(content){
this.$emit('updating');
// console.log('save csrf_token', this.csrf_token); // console.log('save csrf_token', this.csrf_token);
const params = { const params = {
type: this.data.bundle, type: this.data.bundle,

View File

@ -9,13 +9,14 @@ import { mdiHeadphones } from '@mdi/js';
import ContentEditable from '@components/editable/ContentEditable.vue'; import ContentEditable from '@components/editable/ContentEditable.vue';
export default { export default {
props: ['cid'], props: ['cid','eid'],
emits: ['main_scrolled'], emits: ['main_scrolled'],
data(){ data(){
return { return {
headphones_path: mdiHeadphones, headphones_path: mdiHeadphones,
mainscrolled: false, mainscrolled: false,
headerreduced: false, headerreduced: false,
entite: false
} }
}, },
created () { created () {
@ -25,18 +26,18 @@ export default {
}, },
mounted () { mounted () {
// console.log('cartouche layout mounted', this); // console.log('cartouche layout mounted', this);
this.$refs.cartouche_main.addEventListener('scroll', (event) => { // this.$refs.cartouche_main.addEventListener('scroll', (event) => {
// console.log('main is scrolling', event); // console.log('main is scrolling', event);
let $main = event.target; // let $main = event.target;
let scrolled = $main.scrollTop > 0; // let scrolled = $main.scrollTop > 0;
this.$emit('main_scrolled', scrolled); // this.$emit('main_scrolled', scrolled);
// TODO how to make this failsafe limit responsive ? // // TODO how to make this failsafe limit responsive ?
if(scrolled && $main.scrollHeight > 900){ // if(scrolled && $main.scrollHeight > 900){
this.headerreduced = true; // this.headerreduced = true;
} else { // } else {
this.headerreduced = false; // this.headerreduced = false;
} // }
}) // })
}, },
computed: { computed: {
...mapState(ConcernementsStore,['concernementsByID', 'opened_concernement', 'ct_concernement']), ...mapState(ConcernementsStore,['concernementsByID', 'opened_concernement', 'ct_concernement']),
@ -51,10 +52,29 @@ export default {
} }
}, },
deep: true deep: true
},
eid: {
handler (n, o) {
console.log(`TerrainDeVie watch eid o:${o}, n:${n}`);
if (n) {
this.entite = true;
}else{
this.entite = false;
}
},
deep: true
} }
}, },
methods: { methods: {
...mapActions(ConcernementsStore,['setMapMode']), ...mapActions(ConcernementsStore,['setMapMode',"setConcernementIsUpdating","reloadConcernementField"]),
// triggered when focus out and gql patch xhr triggered
concernementFieldIsUpdating(field){
this.setConcernementIsUpdating(this.cid);
},
concernementFieldUpdated(field){
this.setConcernementIsUpdating(null);
this.reloadConcernementField(this.cid, field);
}
}, },
components: { components: {
SvgIcon, SvgIcon,
@ -66,19 +86,21 @@ export default {
<template> <template>
<header ref="cartouche_header"> <header ref="cartouche_header">
<div class="concernement-cartouche-icons"> <div class="concernement-cartouche-icons">
<label :class="{ hidden: headerreduced }">{{ ct_concernement.title.description }}</label> <label class="concernement-label">{{ ct_concernement.title.description }}</label>
<!-- :class="{ hidden: headerreduced }" -->
<ContentEditable <ContentEditable
tag="h2" tag="h2"
:value="concernement.title" :value="concernement.title"
:class="{ ellipsed: headerreduced }" :class="{ ellipsed: entite }"
:contenteditable="concernement.can_update" :contenteditable="(concernement.can_update && !entite)"
:data="{ :data="{
entitytype: 'node', entitytype: 'node',
bundle: 'concernement', bundle: 'concernement',
id: this.concernement.id, id: this.concernement.id,
field: {field_name: 'title', value:'value'} field: {field_name: 'title', value:'value'}
}" /> }"
v-on:updating="concernementFieldIsUpdating('title')"
v-on:updated="concernementFieldUpdated('title')"/>
<!-- <nav class="icons"> <!-- <nav class="icons">

View File

@ -1,3 +1,4 @@
// import Vue from "vue"
import { createApp } from 'vue' import { createApp } from 'vue'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
@ -14,10 +15,36 @@ import './assets/main.scss'
import VuePlyr from 'vue-plyr' import VuePlyr from 'vue-plyr'
import 'vue-plyr/dist/vue-plyr.css' import 'vue-plyr/dist/vue-plyr.css'
// import * as Sentry from "@sentry/browser";
// import * as Integrations from "@sentry/integrations";
// Sentry.init({
// dsn: "https://d1780f9da2fc4dd28c9c17cb344a088f@frontlog.figli.io/2",
// integrations: [new Integrations.Vue()],
// });
import * as Sentry from "@sentry/vue";
import { createSentryPiniaPlugin } from "@sentry/vue";
const app = createApp(App) const app = createApp(App)
Sentry.init({
app,
dsn: "https://d1780f9da2fc4dd28c9c17cb344a088f@frontlog.figli.io/2",
integrations: [
Sentry.browserTracingIntegration({ router }),
],
tracesSampleRate: 0.01,
normalizeDepth: 10, // Or however deep you want your state context to be.
environment: "prod",
// release : '1'
release: __SENTRY_RELEASE__
});
const pinia = createPinia() const pinia = createPinia()
pinia.use( ({store}) => { store.router = router } ) pinia.use( ({store}) => { store.router = router } )
pinia.use(createSentryPiniaPlugin());
app.use(pinia) app.use(pinia)
app.use(router) app.use(router)
// app.use(VueCollapsiblePanel) // app.use(VueCollapsiblePanel)
@ -25,3 +52,5 @@ app.use(VuePlyr, {
plyr: {} plyr: {}
}) })
app.mount('#app') app.mount('#app')
// Sentry.captureMessage("sentry vue is working", "info");

View File

@ -50,6 +50,7 @@ export const ConcernementsStore = defineStore({
concernements_are_loading: false, concernements_are_loading: false,
concernement_active_revision: null, concernement_active_revision: null,
detailsZoomValue: 1, detailsZoomValue: 1,
concernement_is_updating_nid: null
}), }),
getters: { getters: {
@ -309,6 +310,9 @@ export const ConcernementsStore = defineStore({
// console.log(`end of parsing concernements`); // console.log(`end of parsing concernements`);
}, },
setConcernementIsUpdating(nid){
this.concernement_is_updating_nid = nid;
},
reloadConcernements () { reloadConcernements () {
console.log('reloadConcernements'); console.log('reloadConcernements');
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -429,9 +433,36 @@ export const ConcernementsStore = defineStore({
}) })
}) })
}, },
reloadConcernementField(nid, field){
console.log('reloadConcernementField', nid, field);
// let tmp_conc = this.concernementsByID[nid];
return new Promise((resolve, reject) => {
const ast = gql`{
concernement(id:${nid}) {
id
${field}
}
}
`
GQL.post('', { query: print(ast) })
.then(({ data : { data : { concernement } } }) => {
console.log(`reloadConcernementField loaded ${field}`, concernement)
let tmp_conc = this.concernementsByID[concernement.id];
// merge old concernement besoins with new once
_merge(tmp_conc, concernement);
resolve(concernement);
})
.catch(error => {
console.warn('Issue with reloadConcernementField', error)
reject(error);
Promise.reject(error)
})
});
},
reloadConcernementBesoins(nid){ reloadConcernementBesoins(nid){
let tmp_conc = this.concernementsByID[nid]; let tmp_conc = this.concernementsByID[nid];
console.log(`reloadConcernementEntites len: ${tmp_conc.entites.length} revision: ${tmp_conc.revision_id} nid: ${nid}`); // console.log(`reloadConcernementBesoins len: ${tmp_conc.entites.length} revision: ${tmp_conc.revision_id} nid: ${nid}`);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const ast = gql`{ const ast = gql`{
concernement(id:${nid}) { concernement(id:${nid}) {

View File

@ -40,7 +40,8 @@ export default {
...mapState(ConcernementsStore,['map_mode', ...mapState(ConcernementsStore,['map_mode',
'opened_concernement', 'opened_concernement',
'concernements_loaded', 'concernements_loaded',
'allSuperpositions_clustered']), 'allSuperpositions_clustered',
'concernement_is_updating_nid']),
...mapState(CommonStore,['cartouch_width']), ...mapState(CommonStore,['cartouch_width']),
// //
main_cid_eid () { main_cid_eid () {
@ -203,7 +204,20 @@ export default {
}, },
closeConcernement(){ closeConcernement(){
this.resetConcernementOpened(); // unfocus any active element to trigger recording if needed
document.activeElement.blur();
// setTimeout to let time for editable fields to focus out and record changes
this.waitForUpdatingEnded();
},
waitForUpdatingEnded(){
setTimeout(() => {
if (!this.concernement_is_updating_nid) {
this.resetConcernementOpened();
} else {
this.waitForUpdatingEnded();
}
}, 1);
} }
}, },
components: { components: {
@ -216,7 +230,7 @@ export default {
</script> </script>
<template> <template>
<section v-if="opened_concernement" class="concernement"> <section v-if="opened_concernement" class="concernement" :class="{ 'entity-opened': main_cid_eid.eid }">
<TerrainDeVie v-if="map_mode === 'terraindevie' || map_mode === 'action' || map_mode === 'superposition' || map_mode === 'proximite'" :cid="main_cid_eid.cid" :eid="main_cid_eid.eid"/> <TerrainDeVie v-if="map_mode === 'terraindevie' || map_mode === 'action' || map_mode === 'superposition' || map_mode === 'proximite'" :cid="main_cid_eid.cid" :eid="main_cid_eid.eid"/>
<PuissanceAgir v-if="map_mode === 'puissancedagir'" :cid="cid"/> <PuissanceAgir v-if="map_mode === 'puissancedagir'" :cid="cid"/>
<Doleancer v-if="map_mode === 'doleancer'" :cid="cid"/> <Doleancer v-if="map_mode === 'doleancer'" :cid="cid"/>

View File

@ -5,6 +5,21 @@ import vue from '@vitejs/plugin-vue'
import graphql from '@rollup/plugin-graphql'; import graphql from '@rollup/plugin-graphql';
import { viteRequire } from 'vite-require' import { viteRequire } from 'vite-require'
import svgLoader from 'vite-svg-loader' import svgLoader from 'vite-svg-loader'
import { sentryVitePlugin } from "@sentry/vite-plugin";
import { execSync } from 'child_process'
require('dotenv').config();
// Get short Git commit hash
function getGitCommitHash() {
try {
return execSync('git rev-parse --short HEAD').toString().trim()
} catch (e) {
console.warn('Could not retrieve Git commit hash')
return 'unknown'
}
}
const release = `ouatterrir@${getGitCommitHash()}`
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
@ -14,7 +29,18 @@ export default defineConfig({
whitespace: 'preserve' whitespace: 'preserve'
} }
} }
}), graphql(), viteRequire(), svgLoader({defaultImport: 'raw'})], }), graphql(), viteRequire(), svgLoader({defaultImport: 'raw'}),
sentryVitePlugin({
org: "figures-libres",
project: "atlas-atterrissage.com",
authToken: process.env.AUTH_TOKEN,
release: {
// name: "ouatterrir",
name: release
},
url: "https://frontlog.figli.io",
})
],
resolve: { resolve: {
alias: { alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)), '@': fileURLToPath(new URL('./src', import.meta.url)),
@ -36,6 +62,7 @@ export default defineConfig({
}, },
}, },
build: { build: {
sourcemap: true,
rollupOptions: { rollupOptions: {
// https://rollupjs.org/configuration-options/ // https://rollupjs.org/configuration-options/
}, },
@ -44,4 +71,7 @@ export default defineConfig({
esbuild: { esbuild: {
drop: ['console', 'debugger'], drop: ['console', 'debugger'],
}, },
define: {
__SENTRY_RELEASE__: JSON.stringify(release),
}
}) })