can patch node from editablecontent fields

This commit is contained in:
Bachir Soussi Chiadmi 2024-03-18 18:57:07 +01:00
parent 4dc5644898
commit 8c90f54b3c
7 changed files with 216 additions and 28 deletions

View File

@ -23,6 +23,7 @@ fragment ConcernementFields on Concernement {
}
created
changed
can_update
lieu {
name
}

View File

@ -1026,3 +1026,40 @@ body{
}
}
*[contenteditable="true"] {
background: #eee;
border: #eee 2px solid;
border-radius: 5px;
$p:0.3em;
padding:$p;
margin:0 0 0 -$p;
box-sizing: border-box;
transition: all 0.2s ease-in-out;
&:focus{
outline: none;
border: #01ffe2 2px solid;
}
}
button.edit-btn,
button.save-btn{
background-color: #444;
color: #fff;
border: none;
border-radius: 6px;
$size: 25px;
width: $size; height:$size;
display: inline;
>svg{
width:100%;
height:100%;
}
transition: all 0.2s ease-in-out;
&:hover{
cursor:pointer;
opacity: 0.7;
}
}

View File

@ -1985,7 +1985,7 @@ export default {
}.bind(this);
this.paper_main_object.onMouseMove = function(event){
console.log(`onmousemove ${this.id}`, this.cartouch_is_opened);
// console.log(`onmousemove ${this.id}`, this.cartouch_is_opened);
// prevent hover map item mouse event if cartouch is opened
if (this.cartouch_is_opened && this.map_mode !== "superposition") return;
@ -2068,7 +2068,7 @@ export default {
}
let result = paper_group_tohit ? paper_group_tohit.hitTest(event.point) : null;
console.log('move result', result);
// console.log('move result', result);
if (result && result.item.item_id && (result.item.name != "label_click_zone" || this.detailsZoomValue > 2)) {
console.log('move has result', result);
let new_hover_elmt = {

View File

@ -21,6 +21,8 @@ import SvgIcon from '@jamescoyle/vue-icon';
import { mdiChevronRight } from '@mdi/js';
import { mdiChevronDown } from '@mdi/js';
import ContentEditable from '@components/misc/ContentEditable.vue';
export default {
props: ['cid', 'eid'],
data(){
@ -206,13 +208,20 @@ export default {
} else {
this.headerreduced = false;
}
},
onContentEditableFocusOut(e){
console.log('onContentEditableFocusOut', e);
let new_field_content = e.target.innerText;
console.log('onContentEditableFocusOut', new_field_content);
console.log('onContentEditableFocusOut this.concernement.title', this.concernement.title);
}
},
components: {
CartoucheLayout,
Entite,
VueSlider,
SvgIcon
SvgIcon,
ContentEditable
}
}
@ -233,13 +242,36 @@ export default {
<template v-if="!entite">
<section v-if="concernement.description" class="description">
<label v-if="ct_concernement">{{ ct_concernement.field_description.description }}</label>
<p v-html="concernement.description"/>
<!-- <p>{{ concernement.description }}</p> -->
<ContentEditable
tag="p"
:value="concernement.description"
:html="true"
:class="{ ellipsed: headerreduced }"
:contenteditable="concernement.can_update"
:data="{
entitytype: 'node',
bundle: 'concernement',
nid: this.concernement.id,
field: 'field_description'
}" />
</section>
<section v-if="concernement.caillou" class="caillou">
<label v-if="ct_concernement">{{ ct_concernement.field_caillou.description }}</label>
<!-- <p v-html="concernement.caillou"/> -->
<p>{{ concernement.caillou }}</p>
<ContentEditable
tag="p"
:value="concernement.caillou"
:class="{ ellipsed: headerreduced }"
:contenteditable="concernement.can_update"
:data="{
entitytype: 'node',
bundle: 'concernement',
nid: this.concernement.id,
field: 'field_caillou'
}" />
</section>
</template>

View File

@ -6,6 +6,8 @@ import { ConcernementsStore } from '@stores/concernements'
import SvgIcon from '@jamescoyle/vue-icon';
import { mdiHeadphones } from '@mdi/js';
import ContentEditable from '@components/misc/ContentEditable.vue';
export default {
props: ['cid'],
emits: ['main_scrolled'],
@ -19,6 +21,7 @@ export default {
created () {
console.log('Cartouch layout created', this.cid);
this.concernement = this.concernementsByID[this.cid];
console.log('can_update', this.concernement.can_update);
},
mounted () {
// console.log('cartouche layout mounted', this);
@ -44,16 +47,18 @@ export default {
console.log(`TerrainDeVie watch cid o:${o}, n:${n}`);
if (n) {
this.concernement = this.concernementsByID[n];
console.log('can_update', this.concernement.can_update);
}
},
deep: true
}
},
methods: {
...mapActions(ConcernementsStore,['setMapMode'])
...mapActions(ConcernementsStore,['setMapMode']),
},
components: {
SvgIcon
SvgIcon,
ContentEditable
}
}
</script>
@ -62,7 +67,20 @@ export default {
<header ref="cartouche_header">
<div class="concernement-cartouche-icons">
<label :class="{ hidden: headerreduced }">{{ ct_concernement.title.description }}</label>
<h2 :class="{ ellipsed: headerreduced }">{{ concernement.title }}</h2>
<ContentEditable
tag="h2"
:value="concernement.title"
:class="{ ellipsed: headerreduced }"
:contenteditable="concernement.can_update"
:data="{
entitytype: 'node',
bundle: 'concernement',
nid: this.concernement.id,
field: 'title'
}" />
<!-- <nav class="icons">
<ul>
<li v-if="concernement.has_recit" >

View File

@ -0,0 +1,95 @@
<script>
import REST from '@api/rest-axios'
// import JSONAPI from '@api/json-axios'
// import qs from 'querystring-es3'
// import { print } from 'graphql/language/printer'
// import gql from 'graphql-tag'
// import GQL from '@api/graphql-axios'
import { mapActions, mapState } from 'pinia'
import { UserStore } from '@stores/user'
export default {
props: {
tag: String,
value: String,
contenteditable : {
type : [Boolean, String],
default : true,
},
html : {
type : [Boolean, String],
default : false,
},
data: Object
},
// emits: ['returned'],
data(){
return {
}
},
computed: {
...mapState(UserStore,['csrf_token']),
},
created () {
console.log('ContentEditable created');
},
mounted () {
},
methods: {
onContentEditableFocusOut(e){
console.log('onContentEditableFocusOut', e);
// console.log('onContentEditableFocusOut data', this.data);
let new_field_content = this.html ? e.target.innerHTML : e.target.innerText;
// console.log('onContentEditableFocusOut', new_field_content);
this.save(new_field_content)
},
save(content){
console.log('save csrf_token', this.csrf_token);
const params = {
type: this.data.bundle,
nid: [{"value":this.data.nid}],
[this.data.field]: {value: content}
};
const configs = {
headers: {
'X-CSRF-Token': this.csrf_token,
// Authorization: `Bearer ${this.csrf_token}`,
// 'customheader': "bobobo"
}
};
console.log('REST', REST);
REST.patch(`/node/${this.data.nid}?_format=json`, params, configs)
.then(({ data }) => {
console.log('user REST post node data', data)
// TODO if success update the data in pinia
})
.catch(error => {
console.warn('Issue with post node', error)
Promise.reject(error)
})
}
},
}
</script>
<template>
<component
v-if="!html"
:is="tag"
:contenteditable="contenteditable"
@focusout="onContentEditableFocusOut"
>{{ value }}</component>
<component
v-else
:is="tag"
v-html="value"
:contenteditable="contenteditable"
@focusout="onContentEditableFocusOut"
/>
</template>

View File

@ -38,27 +38,32 @@ export const UserStore = defineStore({
this.name = data.attributes.name
this.isloggedin = true //data.attributes.status
console.log('user store checkuser isloggedin', this.isloggedin);
this.userGetRoles()
.then(({ data : { data : { user } } }) => {
console.log('graphql user loaded', user)
this.roles = user.roles
this.checkIsAdmin()
})
.catch(error => {
console.warn('Issue with graphql user loading', error)
Promise.reject(error)
})
this.getUser(); // necessery to get the csrf-token
// this.userGetRoles()
// .then(({ data : { data : { user } } }) => {
// console.log('graphql user loaded', user)
// this.roles = user.roles
// this.checkIsAdmin()
// })
// .catch(error => {
// console.warn('Issue with graphql user loading', error)
// Promise.reject(error)
// })
})
}
})
},
getSessionToken(){
},
userLogin (credentials) {
console.log('user store userLogin', credentials);
return new Promise((resolve, reject) => {
this.getToken(credentials)
this.postCredentials(credentials)
.then((response) => {
console.log('userLogin getToken response', response)
console.log('userLogin postCredentials response', response)
if (response.status === 200) {
this.uid = response.data.current_user.uid
@ -71,24 +76,24 @@ export const UserStore = defineStore({
console.log('User Loggedin')
// todo reload concernements
// concrnmtStore().reloadConcernements(); // INFO would be good but to much complicated for now, just reload the page
window.location.reload();
// window.location.reload();
resolve()
})
} else {
this.loginMessage = response.data.message
console.warn('Issue with getToken', response)
console.warn('Issue with postCredentials', response)
console.log('user loggein failed', this.loginMessage)
Promise.reject(new Error('user loggin failed'))
}
})
.catch(error => {
console.warn('Issue with Dispatch getToken', error)
console.warn('Issue with Dispatch postCredentials', error)
Promise.reject(error)
})
})
},
getToken (credentials) {
console.log('userStore getToken', credentials)
postCredentials (credentials) {
console.log('userStore postCredentials', credentials)
return REST.post('/user/login?_format=json',
credentials,
{