Skip to content
Snippets Groups Projects
Feature_edit.vue 18.9 KiB
Newer Older
<template>
  <div v-frag>
    <div class="fourteen wide column">
      <h1 v-if="$router.history.current.name === 'editer-signalement'">
        Mise à jour du signalement "{{ feature.title }}"
      </h1>
      <h1 v-else-if="$router.history.current.name === 'ajouter-signalement'">
        Création d'un signalement <small>[{{ feature_type.title }}]</small>
      </h1>

      <form
        id="form-feature-edit"
        action=""
        method="post"
        enctype="multipart/form-data"
        class="ui form"
      >
        <!-- Feature Fields -->
        <div class="two fields">
          <div class="required field">
            <label :for="feature_form.title.id_for_label">{{
              feature_form.title.label
            }}</label>
            <input
              type="text"
              required
              :maxlength="feature_form.title.field.max_length"
              :name="feature_form.title.html_name"
              :id="feature_form.title.id_for_label"
              v-model="feature_form.title.value"
            />
            {{ feature_form.title.errors }}
          </div>
          <div class="required field">
            <label :for="feature_form.status.id_for_label">{{
              feature_form.status.label
            }}</label>
            <Dropdown
              :options="feature_form.status.field.choices"
              :selected="feature_form.status.value"
              :selection.sync="feature_form.status.value"
            />

            {{ feature_form.status.errors }}
          </div>
        </div>
        <div class="field">
          <label :for="feature_form.description.id_for_label">{{
            feature_form.description.label
          }}</label>
          <textarea
            :name="feature_form.description.html_name"
            rows="5"
            v-model="feature_form.description.value"
          ></textarea>
          {{ feature_form.description.errors }}
        </div>

        <!-- Geom Field -->
        <div class="field">
          <label for="feature_form.geom.id_for_label">{{
            feature_form.geom.label
          }}</label>

          <!-- Import GeoImage -->
          <div v-frag v-if="feature_type.geom_type === 'point'">
            <p>
              <button
                id="add-geo-image"
                type="button"
                class="ui compact button"
              >
                <i class="file image icon"></i>Importer une image géoréférencée
              </button>
              Vous pouvez utiliser une image géoréférencée pour localiser le
              signalement.
            </p>
            <p>
              <button
                id="create-point-geoposition"
                type="button"
                class="ui compact button"
              >
                <i class="ui map marker alternate icon"></i>Positionner le
                signalement à partir de votre géolocalisation
              </button>
            </p>
            <span id="erreur-geolocalisation" style="display: none">
              <div class="ui negative message">
                <div class="header">
                  Une erreur est survenue avec la fonctionnalité de
                  géolocalisation
                </div>
                <p id="erreur-geolocalisation-message"></p>

          {{ feature_form.geom.errors }}
          <!-- Map -->
          <input
            type="hidden"
            :name="feature_form.geom.html_name"
            :id="feature_form.geom.id_for_label"
            v-model="feature_form.geom.value"
          />
          <div class="ui tab active map-container" data-tab="map">
            <div id="map"></div>
            // todo: ajouter carte & template sidebar-layer
            <!-- {% if serialized_base_maps|length > 0 %} {% include
            "geocontrib/map-layers/sidebar-layers.html" with
            basemaps=serialized_base_maps layers=serialized_layers
            project=project.slug%} {% endif %} -->
          </div>
        </div>

        <!-- Extra Fields -->
        <div class="ui horizontal divider">DONNÉES MÉTIER</div>
        // ? Les données métiers s'affichent quand ?
        <div v-for="field in extra_form" :key="field" class="field">
          {% if field.field.widget.attrs|lookup:'field_type' == 'char' %}
          <label for="field.name">{{ field.label }}</label>
          <input
            type="text"
            :name="field.name"
            :id="field.name"
            v-model="field.value"
          />
          {% elif field.field.widget.attrs|lookup:'field_type' == 'list' %}
          <label for="field.name">{{ field.label }}</label>
          <div class="ui selection dropdown">
            <input
              type="hidden"
              :name="field.name"
              :id="field.name"
              v-model="field.value"
            />
            <div class="default text"></div>
            <i class="dropdown icon"></i>
            <div class="menu">
              {% for x,y in field.field.choices %}
              <div class="item" :data-value="x" :selected="field.value === x">
                {{ y }}
              </div>
              {% endfor %}
            </div>
          </div>
          {% elif field.field.widget.attrs|lookup:'field_type' == 'integer' %}
          <label for="field.name">{{ field.label }}</label>
          <div class="ui input">
            <input
              type="number"
              :name="field.name"
              :id="field.name"
              v-model="field.value"
            />
          </div>
          {% elif field.field.widget.attrs|lookup:'field_type' == 'boolean' %}
          <div class="ui checkbox">
            <input
              type="checkbox"
              :checked="field.value"
              :name="field.name"
              :id="field.name"
            />
            <label for="field.name">{{ field.label }}</label>
          </div>
          {% elif field.field.widget.attrs|lookup:'field_type' == 'date' %}
          <label for="field.name">{{ field.label }}</label>
          <input
            type="date"
            :name="field.name"
            :id="field.name"
            v-model="field.value"
          />
          {% elif field.field.widget.attrs|lookup:'field_type' == 'decimal' %}
          <label for="field.name">{{ field.label }}</label>
          <div class="ui input">
            <input
              type="number"
              step=".01"
              :name="field.name"
              :id="field.name"
              v-model="field.value"
            />
          </div>
          {% elif field.field.widget.attrs|lookup:'field_type' == 'text' %}
          <label :for="field.name">{{ field.label }}</label>
          <textarea
            :name="field.name"
            rows="3"
            v-model="field.value"
          ></textarea>
          {% endif %}
          {{ field.errors }}
        </div>
        {% endfor %}

        <!-- Pièces jointes -->
        <div class="ui horizontal divider">PIÈCES JOINTES</div>
        {{ attachment_formset.non_form_errors }}
          {{ attachment_formset.management_form }}

          <div
            :key="'attachment_formset' + form.dataKey"
          >
            <span v-for="hidden in form.hidden_fields" :key="hidden">
              {{ hidden }}
            </span>

            <div class="ui teal segment">
              <h4>
                Pièce jointe
                <button
                  @click="remove_attachment_formset(form.dataKey)"
                  class="
                    ui
                    small
                    compact
                    right
                    floated
                    icon
                    button
                    remove-formset
                  "
                  type="button"
                >
                  <i class="ui times icon"></i>
                </button>
              </h4>
              {{ form.errors }}
              <div class="visible-fields">
                <div class="two fields">
                  <div class="required field">
                    <label :for="form.title.id_for_label">{{
                      form.title.label
                    }}</label>
                    <input
                      type="text"
                      required
                      :maxlength="form.title.field.max_length"
                      :name="form.title.html_name"
                      :id="form.title.id_for_label"
                      v-model="form.title.value"
                    />
                    {{ form.title.errors }}
                  </div>
                  <div class="required field">
                    <label>Fichier (PDF, PNG, JPEG)</label>
                    // todo : mettre en place la sélection de fichier
                      @click="selectFile"
                      class="ui icon button"
                      :for="form.attachment_file.id_for_label"
                    >
                      <i class="file icon"></i>
                      <span v-if="form.attachment_file.value" class="label">{{
                      <span v-else class="label"
                        >Sélectionner un fichier ...</span
                      >
                    // todo: récupérer cette valeur :accept="IMAGE_FORMAT"
                    <input
                      @change="processImgData"
                      type="file"
                      style="display: none"
                      :name="form.attachment_file.html_name"
                      class="image_file"
                      :id="form.attachment_file.id_for_label"
                    />
                    {{ form.attachment_file.errors }}
                  </div>
                </div>
                <div class="field">
                  <label for="form.info.id_for_label">{{
                    form.info.label
                  }}</label>
                  <textarea
                    name="form.info.html_name"
                    rows="5"
                    v-model="form.info.value"
                  ></textarea>
                  {{ form.info.errors }}
                </div>
              </div>
            </div>
          </div>
          @click="add_attachement_formset"
          id="add-attachment"
          type="button"
          class="ui compact basic button button-hover-green"
        >
          <i class="ui plus icon"></i>Ajouter une pièce jointe
        </button>

        <!-- Signalements liés -->
        <div class="ui horizontal divider">SIGNALEMENTS LIÉS</div>
        {{ linked_formset.non_form_errors }}
        <div id="formsets-link">
          {{ linked_formset.management_form }}
          <div
            v-for="form of linked_formset"
            :key="'linked_formset' + form.dataKey"
          >
                  @click="remove_linked_formset"
                  class="
                    ui
                    small
                    compact
                    right
                    floated
                    icon
                    button
                    remove-formset
                  "
                  type="button"
                >
                  <i class="ui times icon"></i>
                </button>
              </h4>
              {{ form.errors }}
              <div class="visible-fields">
                <div class="two fields">
                  <div class="required field">
                    <label for="form.relation_type.id_for_label">{{
                      form.relation_type.label
                    }}</label>
                    <div class="ui selection dropdown">
                      <input
                        type="hidden"
                        :name="form.relation_type.html_name"
                        :id="form.relation_type.id_for_label"
                        v-model="form.relation_type.value"
                      />
                      <div class="default text"></div>
                      <i class="dropdown icon"></i>
                      <div class="menu">
                        <div
                          v-for="(x, y) in form.relation_type.field.choices"
                          :key="y"
                          class="item"
                          :data-value="x"
                          :selected="form.relation_type.value === x"
                        >
                          {{ y }}
                        </div>
                      </div>
                    </div>
                    {{ form.relation_type.errors }}
                  </div>
                  <div class="required field">
                    <label for="form.feature_to.id_for_label">{{
                      form.feature_to.label
                    }}</label>
                    <div class="ui selection search dropdown">
                      <input
                        type="hidden"
                        :name="form.feature_to.html_name"
                        :id="form.feature_to.id_for_label"
                        v-model="form.feature_to.value"
                      />
                      <div class="default text"></div>
                      <i class="dropdown icon"></i>
                      <div class="menu">
                        <div
                          v-for="(x, y) in form.feature_to.field.choices"
                          :key="y"
                          class="item"
                          :data-value="x"
                          :selected="form.feature_to.value === x"
                        >
                          {{ y }}
                        </div>
                      </div>
                    </div>
                    {{ form.feature_to.errors }}
                  </div>
                </div>
              </div>
            </div>
          </div>
          @click="add_linked_formset"
          id="add-link"
          type="button"
          class="ui compact basic button button-hover-green"
        >
          <i class="ui plus icon"></i>Ajouter une liaison
        </button>

        <div class="ui divider"></div>

        <button type="submit" class="ui teal icon button">
          <i class="white save icon"></i> Enregistrer les changements
        </button>
      </form>
    </div>

    <Project-edit-modal />
  </div>
</template>

<script>
import frag from "vue-frag";
import { mapState } from "vuex";
import Project_edit_modal from "@/components/feature/Feature_edit_modal";
import Dropdown from "@/components/dropdown.vue";
let attachment_formset = {
  dataKey: 0,
  title: {
    errors: null,
    id_for_label: "titre",
    field: {
      max_length: 30,
    },
    html_name: "titre",
    label: "Titre",
    value: "",
  },
  attachment_file: {
    errors: null,
    id_for_label: "titre",
    field: {
      max_length: 30,
    },
    html_name: "titre",
    label: "Titre",
    value: "",
  },
  info: {
    value: "",
    errors: null,
    html_name: "?",
  },
};
let linked_formset = {
  dataKey: 0,
  errors: null,
  relation_type: {
    errors: null,
    id_for_label: "relation_type",
    field: {
      choices: ["Doublon", "Remplace", "Est remplacé par", "Dépend de"],
    },
    html_name: "relation_type",
    label: "Type de liaison",
    value: "",
  },
  feature_to: {
    errors: null,
    id_for_label: "feature_to",
    field: {
      max_length: 30,
    },
    html_name: "feature_to",
    label: "Signalement lié",
    value: "",
  },
};

  props: ["action", "slug_type_signal"],

  components: {
    "Project-edit-modal": Project_edit_modal,
    Dropdown,
  },

  computed: {
    ...mapState(["project"]),
    /* feature: function () { // * nécessaire pour édition (si c'est ce template ...?)
      return this.$store.state.feature.features.find(
        (el) => el.title === this.slug_type_signal
      );
    }, */
    feature_type: function () {
      return this.$store.state.feature_type.feature_types.find(
        (el) => el.title === this.slug_type_signal
      );
    },
          errors: null,
          id_for_label: "name",
          html_name: "name",
          label: "Nom",
          value: "",
          errors: null,
          id_for_label: "status",
            choices: ["Brouillon", "Publié", "Archivé"],
          html_name: "status",
          label: "Statut",
          value: "Brouillon",
          errors: null,
          id_for_label: "description",
          html_name: "description",
          label: "Description",
          value: "",
          label: "Localisation",
      // ? Qu'est-ce que c'est ???
      // * formulaire de pièces jointes, ajouter à la volée
      attachment_formset: [],
      // * formulaires pour les liaisons
      linked_formset: [],
    };
  },

  methods: {
    processImgData(e) {
      // * read image file
      const file = e.target.files[0];
      if (file) {
        this.form.attachment_file.value = file.name;
      }

      let reader = new FileReader();
      let _this = this;
      reader.onload = function (e) {
        _this.form.attachment_file.value = e.target.result;
      };

      reader.readAsDataURL(file);
      // todo : send image to the back (?)
    add_attachement_formset() {
      this.attachment_formset.push({ ...attachment_formset }); //* spread évite de muter l'objet de départ
      attachment_formset.dataKey += 1; //* permet d'identifier uniquement les formulaires ajoutés
    },
    remove_attachment_formset(dataKey) {
      this.attachment_formset = this.attachment_formset.filter(
        (form) => form.dataKey !== dataKey
      );
    },
    add_linked_formset() {
      this.linked_formset.push({ ...linked_formset }); //* spread évite de muter l'objet de départ
      linked_formset.dataKey += 1; //* permet d'identifier uniquement les formulaires ajoutés
    },
    remove_linked_formset(dataKey) {
      this.linked_formset = this.linked_formset.filter(
        (form) => form.dataKey !== dataKey
      );
    },
    selectFile() {
      console.log("selectFile");
    },
  created() {
    if (!this.project) {
      this.$store.commit("SET_PROJECT_SLUG", this.$route.params.slug);
    }
  },
};

// TODO : add script from django and convert:
</script>

<style>
#map {
  height: 70vh;
  width: 100%;

@media only screen and (max-width: 767px) {
  #map {
    height: 80vh;
  }
}
/* // ! missing style in semantic.min.css, je ne comprends pas comment... */
.ui.right.floated.button {
  float: right;
  margin-right: 0;
  margin-left: 0.25em;
}