Skip to content
Snippets Groups Projects
Project_edit.vue 11.6 KiB
Newer Older
<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>