<template> <div class="fourteen wide column"> <form id="form-project-edit" class="ui form"> <h1> <span v-if="action === 'edit'" >Édition du projet "{{ form.title }}"</span > <span v-else-if="action === 'create'">Création d'un projet</span> </h1> <div class="ui horizontal divider">INFORMATIONS</div> <div class="two fields"> <div class="required field"> <label for="title">Titre</label> <!-- <small>{{ form.title.help_text }}</small > --><!-- | safe // ? utile ? --> <input type="text" required maxlength="128" name="title" id="title" v-model="form.title" /> <!-- {{ form.title.errors }} --> </div> <div class="field"> <label>Illustration du projet</label> <img class="ui small image" id="form-input-file-logo" :src=" thumbnailFileSrc ? thumbnailFileSrc : DJANGO_BASE_URL + form.thumbnail " /> <label class="ui icon button" for="thumbnail"> <i class="file icon"></i> <span class="label">{{ form.thumbnail_name ? form.thumbnail_name : fileToImport.name }}</span> </label> <input @change="onFileChange" class="file-selection" type="file" accept="image/jpeg, image/png" style="display: none" name="thumbnail" id="thumbnail" /> <!-- {{ form.thumbnail.errors }} --> </div> </div> <div class="field"> <label for="description">Description</label> <textarea v-model="form.description" name="description" rows="5" ></textarea> <!-- {{ form.description.errors }} --> </div> <div class="ui horizontal divider">PARAMÈTRES</div> <div class="four fields"> <div class="field"> <label for="archive_feature">Délai avant archivage</label> <div class="ui right labeled input"> <input type="number" min="0" style="padding: 1px 2px" name="archive_feature" id="archive_feature" v-model="form.archive_feature" /> <div class="ui label">jour(s)</div> </div> <!-- {{ form.archive_feature.errors }} --> </div> <div class="field"> <label for="delete_feature">Délai avant suppression</label> <div class="ui right labeled input"> <input type="number" min="0" style="padding: 1px 2px" name="delete_feature" id="delete_feature" v-model="form.delete_feature" /> <div class="ui label">jour(s)</div> </div> <!-- {{ form.delete_feature.errors }} --> </div> <div class="required field"> <label for="access_level_pub_feature" >Visibilité des signalements publiés</label > <Dropdown :options="levelPermissions" :selected="form.access_level_pub_feature.name" :selection.sync="form.access_level_pub_feature" /> </div> <div class="required field"> <label for="access_level_arch_feature"> Visibilité des signalements archivés </label> <Dropdown :options="levelPermissions" :selected="form.access_level_arch_feature.name" :selection.sync="form.access_level_arch_feature" /> </div> </div> <div class="field"> <div class="ui checkbox"> <input type="checkbox" v-model="form.moderation" name="moderation" id="moderation" /> <label for="moderation">Modération</label> </div> <!-- {{ form.moderation.errors }} --> </div> <div class="field"> <div class="ui checkbox"> <input type="checkbox" v-model="form.is_project_type" name="is_project_type" id="is_project_type" /> <label for="is_project_type">Est un projet type</label> </div> <!-- {{ form.is_project_type.errors }} --> </div> <div class="ui divider"></div> <button @click="postForm" type="button" class="ui teal icon button"> <i class="white save icon"></i> Enregistrer les changements </button> </form> </div> </template> <script> const axios = require("axios"); import Dropdown from "@/components/Dropdown.vue"; import { mapGetters } from "vuex"; export default { name: "Project_edit", components: { Dropdown, }, data() { return { action: "create", levelPermissions: [ { name: "Utilisateur anonyme", value: "anonymous" }, { name: "Utilisateur connecté", value: "logged_user" }, { name: "Contributeur", value: "contributor" }, ], fileToImport: { name: "Sélectionner une image ...", size: 0, }, form: { title: "", slug: "", created_on: "", updated_on: "", description: "", moderation: false, thumbnail: "", // todo : utiliser l'image par défaut thumbnail_name: "", // todo: delete after getting image in jpg or png instead of data64 (require post to django) creator: null, access_level_pub_feature: { name: "", value: "" }, access_level_arch_feature: { name: "", value: "" }, archive_feature: 0, delete_feature: 0, nb_features: 0, nb_published_features: 0, nb_comments: 0, nb_published_features_comments: 0, nb_contributors: 0, is_project_type: false, }, thumbnailFileSrc: "", }; }, computed: { ...mapGetters(["project"]), DJANGO_BASE_URL:function () { return this.$store.state.configuration.VUE_APP_DJANGO_BASE; }, }, methods: { definePageType() { if (this.$router.history.current.name === "project_create") { this.action = "create"; } else if (this.$router.history.current.name === "project_edit") { this.action = "edit"; } else if (this.$router.history.current.name === "project_create_from") { this.action = "create_from"; } }, truncate(n, len) { var ext = n.substring(n.lastIndexOf(".") + 1, n.length).toLowerCase(); var filename = n.replace("." + ext, ""); if (filename.length <= len) { return n; } filename = filename.substr(0, len) + (n.length > len ? "[...]" : ""); return filename + "." + ext; }, onFileChange(e) { // * read image file const files = e.target.files || e.dataTransfer.files; if (!files.length) return; //* abort if no file this.fileToImport = files[0]; //* stock the file to post later let reader = new FileReader(); //* read the file to display in the page let _this = this; //* 'this' is different in onload function reader.onload = function (e) { _this.thumbnailFileSrc = e.target.result; }; reader.readAsDataURL(this.fileToImport); }, goBackNrefresh(slug) { let _this = this; // * go back to project list this.$router.push( { name: "project_detail", params: { slug }, }, function () { _this.$store.dispatch("GET_ALL_PROJECTS"); //* & refresh project list } ); }, postProjectThumbnail(projectSlug) { //* send img to the backend when feature_type is created if (this.fileToImport.size > 0) { let formData = new FormData(); formData.append("file", this.fileToImport); const url = this.$store.state.configuration.VUE_APP_DJANGO_API_BASE + "projects/" + projectSlug + "/thumbnail/"; return axios .put(url, formData, { headers: { "Content-Type": "multipart/form-data", }, }) .then((response) => { if (response && response.status === 200) { //dispatch("GET_IMPORTS", feature_type_slug); // ? Besoin de vérifier le statut de l'import ? this.goBackNrefresh(projectSlug); } }) .catch((error) => { throw error; }); } }, async postForm() { // todo: check form //let url = `${configuration.VUE_APP_DJANGO_API_BASE}projects/`; const projectData = { title: this.form.title, description: this.form.description, access_level_arch_feature: this.form.access_level_arch_feature.value, access_level_pub_feature: this.form.access_level_pub_feature.value, archive_feature: this.form.archive_feature, delete_feature: this.form.delete_feature, is_project_type: this.form.is_project_type, moderation: this.form.moderation, }; if (this.action === "create" || this.action === "duplicate") { await axios .post(`${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/`, projectData) .then((response) => { if (response && response.status === 201 && response.data) { //* send thumbnail after feature_type was created if (this.fileToImport.size > 0){ this.postProjectThumbnail(response.data.slug); }else { this.goBackNrefresh(response.data.slug); } } }) .catch((error) => { throw error; }); } else if (this.action === "edit") { await axios .put( `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.project.slug}/`, projectData ) .then((response) => { if (response && response.status === 200) { //* send thumbnail after feature_type was created if (this.fileToImport) this.postProjectThumbnail(this.project.slug); } else { this.goBackNrefresh(this.project.slug); } }) .catch((error) => { throw error; }); } }, }, created() { this.definePageType(); if (this.action === "create") { this.thumbnailFileSrc = require("@/assets/img/default.png"); } else if (this.action === "edit") { if (!this.project) { this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug); } this.form = this.project; /* this.form.thumbnail = //* add api base to display image src configuration.VUE_APP_DJANGO_BASE + this.form.thumbnail; */ //* transform string values to objects for dropdowns display (could be in a computed) this.form.access_level_pub_feature = { name: this.project.access_level_pub_feature, value: this.levelPermissions.find( (el) => (el.name = this.project.access_level_pub_feature) ).value, }; this.form.access_level_arch_feature = { name: this.project.access_level_arch_feature, value: this.levelPermissions.find( (el) => (el.name = this.project.access_level_arch_feature) ).value, }; } }, }; </script> <style media="screen"> #form-input-file-logo { margin-left: auto; margin-right: auto; } .close.icon:hover { cursor: pointer; } </style>