<template> <div> <h2 class="ui header"> Activité et commentaires </h2> <div id="feed-event" class="ui feed" > <div v-for="(event, index) in events" :key="'event' + index" > <div v-if="event.event_type === 'create'" > <div v-if="event.object_type === 'feature'" class="event" > <div class="content"> <div class="summary"> <div class="date"> {{ event.created_on }} </div> Création du signalement <span v-if="user">par {{ event.display_user }}</span> </div> </div> </div> <div v-else-if="event.object_type === 'comment'" class="event" > <div class="content"> <div class="summary"> <div class="date"> {{ event.created_on }} </div> Commentaire <span v-if="user">par {{ event.display_user }}</span> </div> <div class="extra text"> {{ event.related_comment.comment }} <div v-if="event.related_comment.attachment" > <br> <a :href=" DJANGO_BASE_URL + event.related_comment.attachment.url " target="_blank" > <i class="paperclip fitted icon" aria-hidden="true" /> {{ event.related_comment.attachment.title }} </a> </div> </div> </div> </div> </div> <div v-else-if="event.event_type === 'update'" class="event" > <div class="content"> <div class="summary"> <div class="date"> {{ event.created_on }} </div> Signalement mis à jour <span v-if="user">par {{ event.display_user }}</span> </div> </div> </div> </div> </div> <div v-if="permissions && permissions.can_create_feature && isOnline" class="ui segment" > <form id="form-comment" class="ui form" > <div class="required field"> <label :for="comment_form.comment.id_for_label" >Ajouter un commentaire</label> <ul v-if="comment_form.comment.errors" class="errorlist" > <li> {{ comment_form.comment.errors }} </li> </ul> <textarea v-model="comment_form.comment.value" :name="comment_form.comment.html_name" rows="2" /> </div> <label>Pièce jointe (facultative)</label> <div class="two fields"> <div class="field"> <label class="ui icon button" for="attachment_file" > <i class="paperclip icon" aria-hidden="true" /> <span class="label">{{ comment_form.attachment_file.value ? comment_form.attachment_file.value : "Sélectionner un fichier ..." }}</span> </label> <input id="attachment_file" type="file" accept="application/pdf, image/jpeg, image/png" style="display: none" name="attachment_file" @change="onFileChange" > </div> <div class="field"> <input id="title" v-model="comment_form.attachment_file.title" type="text" name="title" > {{ comment_form.attachment_file.errors }} </div> </div> <div v-if="enableKeyDocNotif" class="field" > <div class="ui checkbox"> <input id="is_key_document" v-model="comment_form.attachment_file.isKeyDocument" class="hidden" name="is_key_document" type="checkbox" > <label for="is_key_document">Envoyer une notification de publication aux abonnés du projet</label> </div> </div> <ul v-if="comment_form.attachment_file.errors" class="errorlist" > <li> {{ comment_form.attachment_file.errors }} </li> </ul> <button type="button" class="ui compact green icon button" @click="postComment" > <i class="plus icon" aria-hidden="true" /> Poster le commentaire </button> </form> </div> </div> </template> <script> import { mapState, mapGetters } from 'vuex'; import featureAPI from '@/services/feature-api'; export default { name: 'FeatureComments', props: { events: { type: Array, default: () => { return []; } }, enableKeyDocNotif: { type: Boolean, default: false, } }, data() { return { comment_form: { attachment_file: { errors: null, title: '', file: null, isKeyDocument: false }, comment: { id_for_label: 'add-comment', html_name: 'add-comment', errors: '', value: null, }, }, }; }, computed: { ...mapState([ 'user', 'isOnline', ]), ...mapGetters([ 'permissions', ]), ...mapState('feature', [ 'currentFeature', ]), DJANGO_BASE_URL() { return this.$store.state.configuration.VUE_APP_DJANGO_BASE; }, }, methods: { validateForm() { this.comment_form.comment.errors = ''; if (!this.comment_form.comment.value) { this.comment_form.comment.errors = 'Le commentaire ne peut pas être vide'; return false; } return true; }, postComment() { if (this.validateForm()) { featureAPI .postComment({ featureId: this.currentFeature.feature_id || this.currentFeature.id, comment: this.comment_form.comment.value, }) .then((response) => { if (response && this.comment_form.attachment_file.file) { featureAPI .postCommentAttachment({ featureId: this.currentFeature.feature_id || this.currentFeature.id, file: this.comment_form.attachment_file.file, fileName: this.comment_form.attachment_file.fileName, title: this.comment_form.attachment_file.title, isKeyDocument: this.comment_form.attachment_file.isKeyDocument, commentId: response.data.id, }) .then(() => { // Reset isKeyDocument to default this.comment_form.attachment_file.isKeyDocument = false; this.confirmComment(); }); } else { this.confirmComment(); } }); } }, confirmComment() { this.$store.commit('DISPLAY_MESSAGE', { comment: 'Ajout du commentaire confirmé', level: 'positive' }); this.$emit('fetchEvents'); //* display new comment on the page this.comment_form.attachment_file.file = null; //* empty all inputs this.comment_form.attachment_file.fileName = ''; this.comment_form.attachment_file.title = ''; this.comment_form.comment.value = null; }, onFileChange(e) { // * read image file const files = e.target.files || e.dataTransfer.files; const handleFile = (isValid) => { if (isValid) { this.comment_form.attachment_file.file = files[0]; //* store the file to post afterwards let title = files[0].name; this.comment_form.attachment_file.fileName = title; //* name of the file const fileExtension = title.substring(title.lastIndexOf('.') + 1); if ((title.length - fileExtension.length) > 11) { title = `${title.slice(0, 10)}[...].${fileExtension}`; } this.comment_form.attachment_file.title = title; //* title for display this.comment_form.attachment_file.errors = null; } else { this.comment_form.attachment_file.errors = "Transférez une image valide. Le fichier que vous avez transféré n'est pas une image, ou il est corrompu."; } }; if (files.length) { //* exception for pdf if (files[0].type === 'application/pdf') { handleFile(true); } else { this.comment_form.attachment_file.errors = null; //* check if file is an image and pass callback to handle file this.validateImgFile(files[0], handleFile); } } }, validateImgFile(files, handleFile) { const url = window.URL || window.webkitURL; const image = new Image(); image.onload = function () { handleFile(true); URL.revokeObjectURL(image.src); }; image.onerror = function () { handleFile(false); URL.revokeObjectURL(image.src); }; image.src = url.createObjectURL(files); }, } }; </script> <style lang="less" scoped> .event { margin-bottom: 1em; .content { display: block; flex: 1 1 auto; align-self: stretch; text-align: left; word-wrap: break-word; .summary { margin: 0; font-size: 1em; font-weight: 700; color: #252525; .date { display: inline-block; float: none; font-weight: 400; font-size: .85714286em; font-style: normal; margin: 0 1em 0 .5em; padding: 0; color: rgba(0,0,0,.4); } } .extra.text { margin-left: 107px; margin-top: 0; } } } </style>