Newer
Older

Timothee P
committed
<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>

Timothee P
committed
</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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
/>
{{ 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"

Timothee P
committed
:selected="selected_status"
:selection.sync="selected_status"

Timothee P
committed
{{ 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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
></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>

Timothee P
committed
<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>

Timothee P
committed
</div>

Timothee P
committed
{{ 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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
/>
<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

Timothee P
committed
"geocontrib/map-layers/sidebar-layers.html" with
basemaps=serialized_base_maps layers=serialized_layers
project=project.slug%} {% endif %} -->

Timothee P
committed
</div>
</div>
<!-- Extra Fields -->
<div class="ui horizontal divider">DONNÉES MÉTIER</div>
// ? Les données métiers s'affichent quand ?

Timothee P
committed
<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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
/>
{% 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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
/>
<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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
/>
</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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
/>
{% 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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
/>
</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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
></textarea>
{% endif %}
{{ field.errors }}
</div>
{% endfor %}
<!-- Pièces jointes -->
<div class="ui horizontal divider">PIÈCES JOINTES</div>

Timothee P
committed
<!-- {{ attachment_formset.non_form_errors }} -->

Timothee P
committed
<div id="formsets-attachment">

Timothee P
committed
<!-- {{ attachment_formset.management_form }} -->
<FeatureAttachmentFormset
v-for="form in attachmentFormset"
:key="form.dataKey"
:attachmentForm="form"
/>

Timothee P
committed

Timothee P
committed
<button

Timothee P
committed
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>

Timothee P
committed
{{ 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"
>

Timothee P
committed
<div class="ui teal segment">
<h4>
Liaison
<button

Timothee P
committed
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/>
<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"

Timothee P
committed
@blur="updateStore"

Timothee P
committed
/>
<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>

Timothee P
committed
<button

Timothee P
committed
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";

Timothee P
committed
import FeatureAttachmentFormset from "@/components/feature/FeatureAttachmentFormset";
import Dropdown from "@/components/dropdown.vue";

Timothee P
committed
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: "",
},
};

Timothee P
committed
export default {
name: "Feature_edit",
directives: {
frag,
},
props: ["action", "slug_type_signal"],

Timothee P
committed
components: {

Timothee P
committed
FeatureAttachmentFormset,
Dropdown,
},
computed: {
...mapState(["project"]),

Timothee P
committed
...mapState("feature", ["attachmentFormset"]),
/* 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
);
}, */

Timothee P
committed
// * nécessaire pour modèle de création
feature_type: function () {
return this.$store.state.feature_type.feature_types.find(
(el) => el.title === this.slug_type_signal
);
},

Timothee P
committed
selected_status: {
// getter
get() {
return this.feature_form.status.value;
},
// setter
set(newValue) {
this.feature_form.status.value = newValue;
this.updateStore();
},
},

Timothee P
committed
},
data() {
return {

Timothee P
committed
attachmentDataKey: 0, // * formulaire de pièces jointes, ajouter à la volée

Timothee P
committed
feature_form: {
title: {
errors: null,
id_for_label: "name",

Timothee P
committed
field: {
max_length: 30,
},
html_name: "name",
label: "Nom",
value: "",

Timothee P
committed
},
status: {
errors: null,
id_for_label: "status",

Timothee P
committed
field: {
choices: ["Brouillon", "Publié", "Archivé"],

Timothee P
committed
},
html_name: "status",
label: "Statut",
value: "Brouillon",

Timothee P
committed
},
description: {
errors: null,
id_for_label: "description",
html_name: "description",
label: "Description",
value: "",

Timothee P
committed
},
geom: {

Timothee P
committed
},
},
extra_form: [],
// * formulaires pour les liaisons
linked_formset: [],

Timothee P
committed
};
},
methods: {

Timothee P
committed
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

Timothee P
committed
*/
},
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
);
},

Timothee P
committed
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 ?
});

Timothee P
committed
},
created() {
if (!this.project) {
this.$store.commit("SET_PROJECT_SLUG", this.$route.params.slug);
}
},

Timothee P
committed
};
// TODO : add script from django and convert:
</script>
<style>
#map {
height: 70vh;
width: 100%;

Timothee P
committed
border: 1px solid grey;

Timothee P
committed
@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;
}

Timothee P
committed
/* // ! margin écrasé par class last-child first-child, pas normal ... */
.ui.segment {
margin: 1rem 0 !important;
}