<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" @blur="updateStore" /> {{ 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" @blur="updateStore" ></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> </div> <br /> </span> </div> {{ 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" @blur="updateStore" /> <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" @blur="updateStore" /> {% 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" @blur="updateStore" /> <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" @blur="updateStore" /> </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" @blur="updateStore" /> {% 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" @blur="updateStore" /> </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" @blur="updateStore" ></textarea> {% endif %} {{ field.errors }} </div> {% endfor %} <!-- Pièces jointes --> <div class="ui horizontal divider">PIÈCES JOINTES</div> <!-- {{ attachment_formset.non_form_errors }} --> <div id="formsets-attachment"> <!-- {{ attachment_formset.management_form }} --> <FeatureAttachmentForm v-for="form in attachmentFormset" :key="form.dataKey" :attachmentForm="form" /> </div> <button @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 }} --> <FeatureLinkedForm v-for="form in linkedFormset" :key="form.dataKey" :linkedForm="form" :features="features" /> </div> <button @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 FeatureAttachmentForm from "@/components/feature/FeatureAttachmentForm"; import FeatureLinkedForm from "@/components/feature/FeatureLinkedForm"; import Dropdown from "@/components/dropdown.vue"; export default { name: "Feature_edit", directives: { frag, }, props: ["slug_type_signal"], components: { FeatureAttachmentForm, FeatureLinkedForm, Dropdown, }, computed: { ...mapState(["project"]), ...mapState("feature", ["attachmentFormset", "linkedFormset", "features"]), /* 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 ); }, */ // * nécessaire pour modèle de création - pourrait être déplacé dans le store... 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(); }, }, }, data() { return { attachmentDataKey: 0, linkedDataKey: 0, feature_form: { title: { errors: null, id_for_label: "name", field: { max_length: 30, }, html_name: "name", label: "Nom", value: "", }, status: { errors: null, id_for_label: "status", field: { choices: ["Brouillon", "Publié", "Archivé"], }, html_name: "status", label: "Statut", value: "Brouillon", }, description: { errors: null, id_for_label: "description", html_name: "description", label: "Description", value: "", }, geom: { label: "Localisation", }, }, extra_form: [], // * formulaires pour les liaisons }; }, methods: { 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 }, add_linked_formset() { this.$store.commit("feature/ADD_LINKED_FORM", this.linkedDataKey); // * create an object with the counter in store this.linkedDataKey += 1; // * increment counter for key in v-for }, 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%; border: 1px solid grey; } @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; } </style>