Skip to content
Snippets Groups Projects
Feature_edit.vue 16 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="selected_status"
              :selection.sync="selected_status"
            {{ 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 }} -->
          <FeatureAttachmentFormset
            v-for="form in attachmentFormset"
            :key="form.dataKey"
            :attachmentForm="form"
          />
          @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>
  </div>
</template>

<script>
import frag from "vue-frag";
import { mapState } from "vuex";
import FeatureAttachmentFormset from "@/components/feature/FeatureAttachmentFormset";
import Dropdown from "@/components/dropdown.vue";
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"],

    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
      );
    },
    selected_status: {
      // getter
      get() {
        return this.feature_form.status.value;
      },
      // setter
      set(newValue) {
        this.feature_form.status.value = newValue;
        this.updateStore();
      },
    },
      attachmentDataKey: 0, // * formulaire de pièces jointes, ajouter à la volée
          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",
      // * formulaires pour les liaisons
      linked_formset: [],
    add_attachement_formset() {
      this.$store.commit("feature/ADD_ATTACHMENT_FORM", this.attachmentDataKey); // * create an object with the counter in store
      this.attachmentDataKey += 1; // * increment counter for key in v-for
      /* 
          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
    },
    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
      );
    },
    updateStore() {
      this.$store.commit("feature/UPDATE_FORM", {
        title: this.feature_form.title.value,
        status: this.feature_form.status.value,
        description: this.feature_form.description,
        // ? geom ?
      });
  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;
}
/* // ! margin écrasé par class last-child first-child, pas normal ... */
.ui.segment {
  margin: 1rem 0 !important;
}