can patch node from editablecontent fields
This commit is contained in:
parent
4dc5644898
commit
8c90f54b3c
@ -23,6 +23,7 @@ fragment ConcernementFields on Concernement {
|
|||||||
}
|
}
|
||||||
created
|
created
|
||||||
changed
|
changed
|
||||||
|
can_update
|
||||||
lieu {
|
lieu {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1985,7 +1985,7 @@ export default {
|
|||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
this.paper_main_object.onMouseMove = function(event){
|
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
|
// prevent hover map item mouse event if cartouch is opened
|
||||||
if (this.cartouch_is_opened && this.map_mode !== "superposition") return;
|
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;
|
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)) {
|
if (result && result.item.item_id && (result.item.name != "label_click_zone" || this.detailsZoomValue > 2)) {
|
||||||
console.log('move has result', result);
|
console.log('move has result', result);
|
||||||
let new_hover_elmt = {
|
let new_hover_elmt = {
|
||||||
|
@ -21,6 +21,8 @@ import SvgIcon from '@jamescoyle/vue-icon';
|
|||||||
import { mdiChevronRight } from '@mdi/js';
|
import { mdiChevronRight } from '@mdi/js';
|
||||||
import { mdiChevronDown } from '@mdi/js';
|
import { mdiChevronDown } from '@mdi/js';
|
||||||
|
|
||||||
|
import ContentEditable from '@components/misc/ContentEditable.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['cid', 'eid'],
|
props: ['cid', 'eid'],
|
||||||
data(){
|
data(){
|
||||||
@ -206,13 +208,20 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.headerreduced = false;
|
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: {
|
components: {
|
||||||
CartoucheLayout,
|
CartoucheLayout,
|
||||||
Entite,
|
Entite,
|
||||||
VueSlider,
|
VueSlider,
|
||||||
SvgIcon
|
SvgIcon,
|
||||||
|
ContentEditable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,13 +242,36 @@ export default {
|
|||||||
<template v-if="!entite">
|
<template v-if="!entite">
|
||||||
<section v-if="concernement.description" class="description">
|
<section v-if="concernement.description" class="description">
|
||||||
<label v-if="ct_concernement">{{ ct_concernement.field_description.description }}</label>
|
<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>
|
||||||
<section v-if="concernement.caillou" class="caillou">
|
<section v-if="concernement.caillou" class="caillou">
|
||||||
<label v-if="ct_concernement">{{ ct_concernement.field_caillou.description }}</label>
|
<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>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@ import { ConcernementsStore } from '@stores/concernements'
|
|||||||
import SvgIcon from '@jamescoyle/vue-icon';
|
import SvgIcon from '@jamescoyle/vue-icon';
|
||||||
import { mdiHeadphones } from '@mdi/js';
|
import { mdiHeadphones } from '@mdi/js';
|
||||||
|
|
||||||
|
import ContentEditable from '@components/misc/ContentEditable.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['cid'],
|
props: ['cid'],
|
||||||
emits: ['main_scrolled'],
|
emits: ['main_scrolled'],
|
||||||
@ -19,6 +21,7 @@ export default {
|
|||||||
created () {
|
created () {
|
||||||
console.log('Cartouch layout created', this.cid);
|
console.log('Cartouch layout created', this.cid);
|
||||||
this.concernement = this.concernementsByID[this.cid];
|
this.concernement = this.concernementsByID[this.cid];
|
||||||
|
console.log('can_update', this.concernement.can_update);
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
// console.log('cartouche layout mounted', this);
|
// console.log('cartouche layout mounted', this);
|
||||||
@ -44,16 +47,18 @@ export default {
|
|||||||
console.log(`TerrainDeVie watch cid o:${o}, n:${n}`);
|
console.log(`TerrainDeVie watch cid o:${o}, n:${n}`);
|
||||||
if (n) {
|
if (n) {
|
||||||
this.concernement = this.concernementsByID[n];
|
this.concernement = this.concernementsByID[n];
|
||||||
|
console.log('can_update', this.concernement.can_update);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(ConcernementsStore,['setMapMode'])
|
...mapActions(ConcernementsStore,['setMapMode']),
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
SvgIcon
|
SvgIcon,
|
||||||
|
ContentEditable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -62,7 +67,20 @@ export default {
|
|||||||
<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="{ 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">
|
<!-- <nav class="icons">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-if="concernement.has_recit" >
|
<li v-if="concernement.has_recit" >
|
||||||
|
95
src/components/misc/ContentEditable.vue
Normal file
95
src/components/misc/ContentEditable.vue
Normal 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>
|
@ -39,26 +39,31 @@ export const UserStore = defineStore({
|
|||||||
this.isloggedin = true //data.attributes.status
|
this.isloggedin = true //data.attributes.status
|
||||||
console.log('user store checkuser isloggedin', this.isloggedin);
|
console.log('user store checkuser isloggedin', this.isloggedin);
|
||||||
|
|
||||||
this.userGetRoles()
|
this.getUser(); // necessery to get the csrf-token
|
||||||
.then(({ data : { data : { user } } }) => {
|
|
||||||
console.log('graphql user loaded', user)
|
// this.userGetRoles()
|
||||||
this.roles = user.roles
|
// .then(({ data : { data : { user } } }) => {
|
||||||
this.checkIsAdmin()
|
// console.log('graphql user loaded', user)
|
||||||
})
|
// this.roles = user.roles
|
||||||
.catch(error => {
|
// this.checkIsAdmin()
|
||||||
console.warn('Issue with graphql user loading', error)
|
// })
|
||||||
Promise.reject(error)
|
// .catch(error => {
|
||||||
})
|
// console.warn('Issue with graphql user loading', error)
|
||||||
|
// Promise.reject(error)
|
||||||
|
// })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
getSessionToken(){
|
||||||
|
|
||||||
},
|
},
|
||||||
userLogin (credentials) {
|
userLogin (credentials) {
|
||||||
console.log('user store userLogin', credentials);
|
console.log('user store userLogin', credentials);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.getToken(credentials)
|
this.postCredentials(credentials)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log('userLogin getToken response', response)
|
console.log('userLogin postCredentials response', response)
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
this.uid = response.data.current_user.uid
|
this.uid = response.data.current_user.uid
|
||||||
@ -71,24 +76,24 @@ export const UserStore = defineStore({
|
|||||||
console.log('User Loggedin')
|
console.log('User Loggedin')
|
||||||
// todo reload concernements
|
// todo reload concernements
|
||||||
// concrnmtStore().reloadConcernements(); // INFO would be good but to much complicated for now, just reload the page
|
// concrnmtStore().reloadConcernements(); // INFO would be good but to much complicated for now, just reload the page
|
||||||
window.location.reload();
|
// window.location.reload();
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.loginMessage = response.data.message
|
this.loginMessage = response.data.message
|
||||||
console.warn('Issue with getToken', response)
|
console.warn('Issue with postCredentials', response)
|
||||||
console.log('user loggein failed', this.loginMessage)
|
console.log('user loggein failed', this.loginMessage)
|
||||||
Promise.reject(new Error('user loggin failed'))
|
Promise.reject(new Error('user loggin failed'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.warn('Issue with Dispatch getToken', error)
|
console.warn('Issue with Dispatch postCredentials', error)
|
||||||
Promise.reject(error)
|
Promise.reject(error)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getToken (credentials) {
|
postCredentials (credentials) {
|
||||||
console.log('userStore getToken', credentials)
|
console.log('userStore postCredentials', credentials)
|
||||||
return REST.post('/user/login?_format=json',
|
return REST.post('/user/login?_format=json',
|
||||||
credentials,
|
credentials,
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user