ImageEditable.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <script>
  2. import JSONAPI from '@api/json-axios'
  3. import REST from '@api/rest-axios'
  4. import { mapActions, mapState } from 'pinia'
  5. import { ConcernementsStore } from '@stores/concernements'
  6. import { UserStore } from '@stores/user'
  7. import ContentEditable from '@components/editable/ContentEditable.vue';
  8. import SvgIcon from '@jamescoyle/vue-icon';
  9. import { mdiTrashCanOutline } from '@mdi/js';
  10. import { mdiImagePlus } from '@mdi/js';
  11. export default {
  12. props: {
  13. can_update: Boolean,
  14. image: Object,
  15. data: Object
  16. },
  17. emits: ['updated'],
  18. data(){
  19. return {
  20. mdiTrashCanOutline_path: mdiTrashCanOutline,
  21. mdiImagePlus_path: mdiImagePlus
  22. }
  23. },
  24. computed: {
  25. ...mapState(UserStore,['csrf_token']),
  26. },
  27. created () {
  28. console.log('ImageEditable created');
  29. },
  30. mounted () {
  31. },
  32. methods: {
  33. ...mapActions(ConcernementsStore, ['reloadConcernements']),
  34. addImage(e){
  35. console.log('addImage', this.$refs);
  36. this.$refs.image_input.click();
  37. },
  38. onInput(e){
  39. console.log('onFileInput', e);
  40. let file = e.target.files[0];
  41. console.log('onFileInput file', file);
  42. this.save(file);
  43. },
  44. save(file){
  45. const configs = {
  46. headers: {
  47. 'X-CSRF-Token': this.csrf_token,
  48. 'Content-Type': 'application/octet-stream',
  49. 'Content-Disposition': `file; filename="${file.name}"`,
  50. },
  51. };
  52. JSONAPI.post(`/${this.data.entitytype}/${this.data.bundle}/${this.data.uuid}/${this.data.field}`, file, configs)
  53. .then(({ data : { data } }) => {
  54. console.log('jsonapi post image', data)
  55. this.$emit('updated');
  56. })
  57. .catch(error => {
  58. console.warn('Issue with jsonapi post image', error)
  59. Promise.reject(error)
  60. })
  61. },
  62. onDeleteImg(e){
  63. console.log('onDeleteImg', e);
  64. const params = {
  65. type: this.data.bundle,
  66. nid: [{"value":this.data.nid}],
  67. [this.data.field]: {value: null}
  68. };
  69. const configs = {
  70. headers: {'X-CSRF-Token': this.csrf_token}
  71. };
  72. REST.patch(`/node/${this.data.nid}?_format=json`, params, configs)
  73. .then(({ data }) => {
  74. console.log(`user REST patch node ${this.data.bundle} ${this.data.field}`, data)
  75. // TODO if success update the data in pinia
  76. // this.reloadConcernements();
  77. this.$emit('updated');
  78. })
  79. .catch(error => {
  80. console.warn(`Issue with patch node ${this.data.bundle} ${this.data.field}`, error)
  81. Promise.reject(error)
  82. })
  83. // 405 JSONAPI operation not allowed, don't know why
  84. // const configs = {
  85. // headers: {
  86. // 'X-CSRF-Token': this.csrf_token,
  87. // 'Content-Type': 'application/octet-stream',
  88. // 'Content-Disposition': `file; filename=""`,
  89. // },
  90. // };
  91. // JSONAPI.delete(`/${this.data.entitytype}/${this.data.bundle}/${this.data.uuid}/${this.data.field}`, {}, configs)
  92. // .then(({ data : { data } }) => {
  93. // console.log('jsonapi delete image', data)
  94. // this.$emit('updated');
  95. // })
  96. // .catch(error => {
  97. // console.warn('Issue with jsonapi post image', error)
  98. // Promise.reject(error)
  99. // })
  100. // console.log('save csrf_token', this.csrf_token);
  101. }
  102. },
  103. components: {
  104. SvgIcon,
  105. ContentEditable
  106. }
  107. }
  108. </script>
  109. <template>
  110. <div class="editable-image">
  111. <!-- with img -->
  112. <template v-if="image.length">
  113. <figure>
  114. <img :src="image[0].url" :alt="image[0].alt"/>
  115. <figcaption
  116. :contenteditable="can_update"
  117. v-if="image[0].alt || can_update"
  118. >
  119. {{ image[0].alt }}
  120. </figcaption>
  121. <ContentEditable
  122. tag="figcaption"
  123. :value="image[0].alt"
  124. :contenteditable="can_update"
  125. :data="{
  126. entitytype: data.entitytype,
  127. bundle: data.bundle,
  128. nid: data.nid,
  129. field: {field_name: data.field, value:'alt', additional_values:{target_id:image[0].id}}
  130. }" />
  131. </figure>
  132. <div v-if="can_update" @click="onDeleteImg" class="delete-btn">
  133. <svg-icon type="mdi" :path="mdiTrashCanOutline_path" />
  134. </div>
  135. </template>
  136. <!-- with out img -->
  137. <template v-else-if="can_update">
  138. <div @click="addImage" class="btn">
  139. <svg-icon type="mdi" :path="mdiImagePlus_path" @click="onDeleteImg" />
  140. <!-- <span>ajouter une image</span> -->
  141. </div>
  142. <input ref="image_input" type="file" accept ="image/jpeg, image/png, image/jpg" @input="onInput">
  143. </template>
  144. </div>
  145. </template>