entite image is now editable, add, delete. remains the alt field
This commit is contained in:
		@@ -1,9 +1,11 @@
 | 
			
		||||
fragment EntiteFields on Entite {
 | 
			
		||||
  id
 | 
			
		||||
  action
 | 
			
		||||
  menacemaintien
 | 
			
		||||
  uuid
 | 
			
		||||
  title
 | 
			
		||||
  can_update
 | 
			
		||||
  agissante
 | 
			
		||||
  action
 | 
			
		||||
  menacemaintien
 | 
			
		||||
  image {
 | 
			
		||||
    alt
 | 
			
		||||
    url
 | 
			
		||||
 
 | 
			
		||||
@@ -1047,12 +1047,41 @@ body{
 | 
			
		||||
  border: #eee 2px solid;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  padding: 0.3em!important;
 | 
			
		||||
  margin-bottom: 1em;
 | 
			
		||||
  margin: 1em 0 0;
 | 
			
		||||
  font-size: 0.756em;
 | 
			
		||||
  &>*{ 
 | 
			
		||||
    display: inline-block!important;
 | 
			
		||||
    padding: 0!important;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.editable-image{
 | 
			
		||||
  background: #eee;
 | 
			
		||||
  max-width: 100%;
 | 
			
		||||
  div.btn{
 | 
			
		||||
    border: #eee 2px solid;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
    margin: 1em 0 0;
 | 
			
		||||
    font-size: 1em;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100px;
 | 
			
		||||
    line-height:100px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    transition: all 0.2s ease-in-out;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    >span{
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
      vertical-align: middle;
 | 
			
		||||
    }
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    &:hover{
 | 
			
		||||
      border: #01ffe2 2px solid;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
  input[type="file"]{
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +1,19 @@
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
import REST from '@api/rest-axios'
 | 
			
		||||
import JSONAPI from '@api/json-axios'
 | 
			
		||||
 | 
			
		||||
import { mapActions, mapState } from 'pinia'
 | 
			
		||||
import { ConcernementsStore } from '@stores/concernements'
 | 
			
		||||
import { UserStore } from '@stores/user'
 | 
			
		||||
 | 
			
		||||
import ContentEditable from '@components/editable/ContentEditable.vue';
 | 
			
		||||
import CheckboxEditable from '@components/editable/CheckboxEditable.vue';
 | 
			
		||||
import ImageEditable from '@components/editable/ImageEditable.vue';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  props: ['concernement', 'entite', 'eid'],
 | 
			
		||||
  emits: ['reloadEntite'],
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
    }
 | 
			
		||||
@@ -15,6 +22,7 @@ export default {
 | 
			
		||||
    ...mapState(ConcernementsStore,['opened_concernement',
 | 
			
		||||
                                    'ct_concernement',
 | 
			
		||||
                                    'ct_entite']),
 | 
			
		||||
    ...mapState(UserStore,['csrf_token']),
 | 
			
		||||
    field_menace_maintien_label (){
 | 
			
		||||
      let str;
 | 
			
		||||
      if (this.concernement.entites_byid[this.eid].menacemaintien < 0) {
 | 
			
		||||
@@ -35,38 +43,34 @@ export default {
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    
 | 
			
		||||
    reloadEntite(){
 | 
			
		||||
      this.$emit('reloadEntite');
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  components: {
 | 
			
		||||
    ContentEditable,
 | 
			
		||||
    CheckboxEditable
 | 
			
		||||
    CheckboxEditable,
 | 
			
		||||
    ImageEditable,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <section class="entite">
 | 
			
		||||
    <!-- <section v-if="entite.can_update" class="editable">
 | 
			
		||||
      <label><input type="checkbox" name="action"> Entité action</label>
 | 
			
		||||
    </section> -->
 | 
			
		||||
    <CheckboxEditable 
 | 
			
		||||
      v-if="entite.can_update"
 | 
			
		||||
      label="Entité action" 
 | 
			
		||||
      :data="{
 | 
			
		||||
        entitytype: 'node',
 | 
			
		||||
        bundle: 'entite',
 | 
			
		||||
        nid: this.entite.id,
 | 
			
		||||
        field: 'field_entite_agissante'
 | 
			
		||||
      }" />
 | 
			
		||||
    <section v-if="entite.image.length || entite.can_update" class="image">
 | 
			
		||||
      <ImageEditable 
 | 
			
		||||
        :image="entite.image"
 | 
			
		||||
        :data="{
 | 
			
		||||
          entitytype: 'node',
 | 
			
		||||
          bundle: 'entite',
 | 
			
		||||
          nid: this.entite.id,
 | 
			
		||||
          uuid: this.entite.uuid,
 | 
			
		||||
          field: 'field_image'
 | 
			
		||||
        }"
 | 
			
		||||
        v-on:updated="reloadEntite" />
 | 
			
		||||
 | 
			
		||||
    <section v-if="entite.image.length" class="image">
 | 
			
		||||
      <figure>
 | 
			
		||||
        <img :src="entite.image[0].url" :alt="entite.image[0].alt"/>
 | 
			
		||||
        <figcaption>{{ entite.image[0].alt }}</figcaption>
 | 
			
		||||
      </figure>
 | 
			
		||||
      <!-- TODO admin add image -->
 | 
			
		||||
    </section>
 | 
			
		||||
    <section v-if="entite.action" class="action">
 | 
			
		||||
    <section v-if="entite.action || entite.can_update" class="action">
 | 
			
		||||
        <label v-if="ct_entite">{{ ct_entite.field_action.description }}</label>
 | 
			
		||||
        <!-- <p>{{ entite.action }}</p> -->
 | 
			
		||||
        <ContentEditable 
 | 
			
		||||
@@ -78,10 +82,11 @@ export default {
 | 
			
		||||
            bundle: 'entite',
 | 
			
		||||
            nid: this.entite.id,
 | 
			
		||||
            field: 'field_action'
 | 
			
		||||
          }" />
 | 
			
		||||
          }"
 | 
			
		||||
          v-on:updated="reloadEntite" />
 | 
			
		||||
          
 | 
			
		||||
    </section>
 | 
			
		||||
    <section v-if="entite.menacemaintien" class="menace-maintien">
 | 
			
		||||
    <section v-if="entite.menacemaintien || entite.can_update" class="menace-maintien">
 | 
			
		||||
        <label v-if="ct_entite">{{ field_menace_maintien_label }}</label>
 | 
			
		||||
        <!-- <p>{{ entite.menacemaintien }}</p> -->
 | 
			
		||||
        <ContentEditable 
 | 
			
		||||
@@ -93,7 +98,8 @@ export default {
 | 
			
		||||
            bundle: 'entite',
 | 
			
		||||
            nid: this.entite.id,
 | 
			
		||||
            field: 'field_menace_maintien'
 | 
			
		||||
          }" />
 | 
			
		||||
          }"
 | 
			
		||||
          v-on:updated="reloadEntite" />
 | 
			
		||||
        
 | 
			
		||||
    </section>
 | 
			
		||||
    <!-- SOURCES (experiences vecues) -->
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ import { mdiChevronRight } from '@mdi/js';
 | 
			
		||||
import { mdiChevronDown } from '@mdi/js';
 | 
			
		||||
 | 
			
		||||
import ContentEditable from '@components/editable/ContentEditable.vue';
 | 
			
		||||
import CheckboxEditable from '@components/editable/CheckboxEditable.vue';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  props: ['cid', 'eid'],
 | 
			
		||||
@@ -221,7 +222,8 @@ export default {
 | 
			
		||||
    Entite,
 | 
			
		||||
    VueSlider,
 | 
			
		||||
    SvgIcon,
 | 
			
		||||
    ContentEditable
 | 
			
		||||
    ContentEditable,
 | 
			
		||||
    CheckboxEditable
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -246,14 +248,25 @@ export default {
 | 
			
		||||
            nid: this.entite.id,
 | 
			
		||||
            field: 'title'
 | 
			
		||||
          }" />
 | 
			
		||||
          
 | 
			
		||||
 | 
			
		||||
        <CheckboxEditable 
 | 
			
		||||
          v-if="entite && entite.can_update"
 | 
			
		||||
          :checked="entite.agissante"
 | 
			
		||||
          label="Entité action" 
 | 
			
		||||
          :data="{
 | 
			
		||||
            entitytype: 'node',
 | 
			
		||||
            bundle: 'entite',
 | 
			
		||||
            nid: this.entite.id,
 | 
			
		||||
            field: 'field_entite_agissante'
 | 
			
		||||
          }" />
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    
 | 
			
		||||
    <template v-slot:main>
 | 
			
		||||
      <!-- concernement -->
 | 
			
		||||
      <template v-if="!entite">
 | 
			
		||||
        <section v-if="concernement.description" class="description">
 | 
			
		||||
        <section v-if="concernement.description || concernement.can_update" class="description">
 | 
			
		||||
            <label v-if="ct_concernement">{{ ct_concernement.field_description.description }}</label>
 | 
			
		||||
            
 | 
			
		||||
            <ContentEditable 
 | 
			
		||||
@@ -270,7 +283,7 @@ export default {
 | 
			
		||||
              }" />
 | 
			
		||||
 | 
			
		||||
        </section>
 | 
			
		||||
        <section v-if="concernement.caillou" class="caillou">
 | 
			
		||||
        <section v-if="concernement.caillou || concernement.can_update" class="caillou">
 | 
			
		||||
            <label v-if="ct_concernement">{{ ct_concernement.field_caillou.description }}</label>
 | 
			
		||||
            
 | 
			
		||||
            <ContentEditable 
 | 
			
		||||
@@ -289,7 +302,7 @@ export default {
 | 
			
		||||
      </template>
 | 
			
		||||
 | 
			
		||||
      <!-- entite -->
 | 
			
		||||
      <Entite v-if="entite" :concernement="concernement" :entite="entite" :eid="eid"/>
 | 
			
		||||
      <Entite v-if="entite" :concernement="concernement" :entite="entite" :eid="eid" v-on:reloadEntite="loadEntite"/>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <template v-slot:footer>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,15 +3,17 @@
 | 
			
		||||
import REST from '@api/rest-axios'
 | 
			
		||||
 | 
			
		||||
import { mapActions, mapState } from 'pinia'
 | 
			
		||||
import { ConcernementsStore } from '@stores/concernements'
 | 
			
		||||
import { UserStore } from '@stores/user'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    checked: Boolean,
 | 
			
		||||
    label: String, 
 | 
			
		||||
    data: Object
 | 
			
		||||
  },
 | 
			
		||||
  // emits: ['returned'],
 | 
			
		||||
  emits: ['updated'],
 | 
			
		||||
  data(){
 | 
			
		||||
    return {
 | 
			
		||||
      
 | 
			
		||||
@@ -21,12 +23,13 @@ export default {
 | 
			
		||||
    ...mapState(UserStore,['csrf_token']),
 | 
			
		||||
  },
 | 
			
		||||
  created () {
 | 
			
		||||
    console.log('ContentEditable created');
 | 
			
		||||
    console.log('CheckboxEditable created');
 | 
			
		||||
  },
 | 
			
		||||
  mounted () {
 | 
			
		||||
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(ConcernementsStore, ['reloadConcernements']),
 | 
			
		||||
    onInput(e){
 | 
			
		||||
      // console.log('onInput checkbox e', e);
 | 
			
		||||
      let checked  = e.target.checked;
 | 
			
		||||
@@ -47,6 +50,8 @@ export default {
 | 
			
		||||
        .then(({ data }) => {
 | 
			
		||||
          console.log('user REST post node data', data)
 | 
			
		||||
          // TODO if success update the data in pinia 
 | 
			
		||||
          // this.reloadConcernements();
 | 
			
		||||
          this.$emit('updated');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(error => {
 | 
			
		||||
          console.warn(`Issue with patch node ${this.data.bundle}`, error)
 | 
			
		||||
@@ -59,6 +64,6 @@ export default {
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <section class="editable">
 | 
			
		||||
    <label><input type="checkbox" @input="onInput"> {{ label }}</label>
 | 
			
		||||
    <label><input type="checkbox" :checked="checked" @input="onInput"> {{ label }}</label>
 | 
			
		||||
  </section>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
import REST from '@api/rest-axios'
 | 
			
		||||
 | 
			
		||||
import { mapActions, mapState } from 'pinia'
 | 
			
		||||
import { ConcernementsStore } from '@stores/concernements'
 | 
			
		||||
import { UserStore } from '@stores/user'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -20,7 +21,7 @@ export default {
 | 
			
		||||
    }, 
 | 
			
		||||
    data: Object
 | 
			
		||||
  },
 | 
			
		||||
  // emits: ['returned'],
 | 
			
		||||
  emits: ['updated'],
 | 
			
		||||
  data(){
 | 
			
		||||
    return {
 | 
			
		||||
      
 | 
			
		||||
@@ -36,6 +37,7 @@ export default {
 | 
			
		||||
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(ConcernementsStore, ['reloadConcernements']),
 | 
			
		||||
    onContentEditableFocusOut(e){
 | 
			
		||||
      console.log('onContentEditableFocusOut', e);
 | 
			
		||||
      // console.log('onContentEditableFocusOut data', this.data);
 | 
			
		||||
@@ -57,6 +59,8 @@ export default {
 | 
			
		||||
        .then(({ data }) => {
 | 
			
		||||
          console.log('user REST post node data', data)
 | 
			
		||||
          // TODO if success update the data in pinia 
 | 
			
		||||
          // this.reloadConcernements();
 | 
			
		||||
          this.$emit('updated');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(error => {
 | 
			
		||||
          console.warn(`Issue with patch node ${this.data.bundle}`, error)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										136
									
								
								src/components/editable/ImageEditable.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/components/editable/ImageEditable.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
import JSONAPI from '@api/json-axios'
 | 
			
		||||
import REST from '@api/rest-axios'
 | 
			
		||||
 | 
			
		||||
import { mapActions, mapState } from 'pinia'
 | 
			
		||||
import { ConcernementsStore } from '@stores/concernements'
 | 
			
		||||
import { UserStore } from '@stores/user'
 | 
			
		||||
 | 
			
		||||
import SvgIcon from '@jamescoyle/vue-icon';
 | 
			
		||||
import { mdiTrashCanOutline } from '@mdi/js';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    image: Object,
 | 
			
		||||
    data: Object
 | 
			
		||||
  },
 | 
			
		||||
  emits: ['updated'],
 | 
			
		||||
  data(){
 | 
			
		||||
    return {
 | 
			
		||||
      mdiTrashCanOutline_path: mdiTrashCanOutline
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    ...mapState(UserStore,['csrf_token']),
 | 
			
		||||
  },
 | 
			
		||||
  created () {
 | 
			
		||||
    console.log('ImageEditable created');
 | 
			
		||||
  },
 | 
			
		||||
  mounted () {
 | 
			
		||||
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(ConcernementsStore, ['reloadConcernements']),
 | 
			
		||||
    addImage(e){
 | 
			
		||||
      console.log('addImage', this.$refs);
 | 
			
		||||
      this.$refs.image_input.click();
 | 
			
		||||
    },
 | 
			
		||||
    onInput(e){
 | 
			
		||||
      console.log('onFileInput', e);
 | 
			
		||||
      let file = e.target.files[0];
 | 
			
		||||
      console.log('onFileInput file', file);
 | 
			
		||||
      this.save(file);
 | 
			
		||||
    },
 | 
			
		||||
    save(file){
 | 
			
		||||
      const configs = {
 | 
			
		||||
        headers: {
 | 
			
		||||
          'X-CSRF-Token': this.csrf_token,
 | 
			
		||||
          'Content-Type': 'application/octet-stream',
 | 
			
		||||
          'Content-Disposition': `file; filename="${file.name}"`,
 | 
			
		||||
        },
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      JSONAPI.post(`/${this.data.entitytype}/${this.data.bundle}/${this.data.uuid}/${this.data.field}`, file, configs)
 | 
			
		||||
        .then(({ data : { data } }) => {
 | 
			
		||||
          console.log('jsonapi post image', data)
 | 
			
		||||
          this.$emit('updated');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(error => {
 | 
			
		||||
          console.warn('Issue with jsonapi post image', error)
 | 
			
		||||
          Promise.reject(error)
 | 
			
		||||
        })
 | 
			
		||||
    },
 | 
			
		||||
    onDeleteImg(e){
 | 
			
		||||
      console.log('onDeleteImg', e);
 | 
			
		||||
 | 
			
		||||
      const params = {
 | 
			
		||||
        type: this.data.bundle,
 | 
			
		||||
        nid: [{"value":this.data.nid}],
 | 
			
		||||
        [this.data.field]: {value: null}
 | 
			
		||||
      };
 | 
			
		||||
      const configs = {
 | 
			
		||||
        headers: {'X-CSRF-Token': this.csrf_token}
 | 
			
		||||
      };
 | 
			
		||||
      REST.patch(`/node/${this.data.nid}?_format=json`, params, configs)
 | 
			
		||||
        .then(({ data }) => {
 | 
			
		||||
          console.log(`user REST patch node ${this.data.bundle} ${this.data.field}`, data)
 | 
			
		||||
          // TODO if success update the data in pinia 
 | 
			
		||||
          // this.reloadConcernements();
 | 
			
		||||
          this.$emit('updated');
 | 
			
		||||
        })
 | 
			
		||||
        .catch(error => {
 | 
			
		||||
          console.warn(`Issue with patch node ${this.data.bundle} ${this.data.field}`, error)
 | 
			
		||||
          Promise.reject(error)
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
      // 405 JSONAPI operation not allowed, don't know why
 | 
			
		||||
      
 | 
			
		||||
      // const configs = {
 | 
			
		||||
      //   headers: {
 | 
			
		||||
      //     'X-CSRF-Token': this.csrf_token,
 | 
			
		||||
      //     'Content-Type': 'application/octet-stream',
 | 
			
		||||
      //     'Content-Disposition': `file; filename=""`,
 | 
			
		||||
      //   },
 | 
			
		||||
      // };
 | 
			
		||||
 | 
			
		||||
      // JSONAPI.delete(`/${this.data.entitytype}/${this.data.bundle}/${this.data.uuid}/${this.data.field}`, {}, configs)
 | 
			
		||||
      //   .then(({ data : { data } }) => {
 | 
			
		||||
      //     console.log('jsonapi delete image', data)
 | 
			
		||||
      //     this.$emit('updated');
 | 
			
		||||
      //   })
 | 
			
		||||
      //   .catch(error => {
 | 
			
		||||
      //     console.warn('Issue with jsonapi post image', error)
 | 
			
		||||
      //     Promise.reject(error)
 | 
			
		||||
      //   })
 | 
			
		||||
      // console.log('save csrf_token', this.csrf_token);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  components: {
 | 
			
		||||
    SvgIcon,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="editable-image">
 | 
			
		||||
    <!-- with img -->
 | 
			
		||||
    <template v-if="image.length">
 | 
			
		||||
      <figure>
 | 
			
		||||
        <img :src="image[0].url" :alt="image[0].alt"/>
 | 
			
		||||
        <figcaption v-if="image[0].alt">{{ image[0].alt }}</figcaption>
 | 
			
		||||
      </figure>
 | 
			
		||||
      <svg-icon type="mdi" :path="mdiTrashCanOutline_path" @click="onDeleteImg" />
 | 
			
		||||
    </template>
 | 
			
		||||
    <!-- with out img -->
 | 
			
		||||
    <template v-else>
 | 
			
		||||
      <div @click="addImage" class="btn">
 | 
			
		||||
 | 
			
		||||
        <span>ajouter une image</span>
 | 
			
		||||
      </div>
 | 
			
		||||
      <input ref="image_input" type="file" accept ="image/jpeg, image/png, image/jpg" @input="onInput">
 | 
			
		||||
    </template>
 | 
			
		||||
    
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -251,9 +251,9 @@ export const ConcernementsStore = defineStore({
 | 
			
		||||
    reloadConcernements () {
 | 
			
		||||
      console.log('reloadConcernements');
 | 
			
		||||
      // reset the arrays
 | 
			
		||||
      this.concernements = [];
 | 
			
		||||
      this.concernementsByID = {};
 | 
			
		||||
      this.concernements_loaded = false;
 | 
			
		||||
      // this.concernements = [];
 | 
			
		||||
      // this.concernementsByID = {};
 | 
			
		||||
      // this.concernements_loaded = false;
 | 
			
		||||
      this.loadConcernements();
 | 
			
		||||
    },
 | 
			
		||||
    loadContentTypeDefinition () {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user