Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • geocontrib/geocontrib-frontend
  • ext_matthieu/geocontrib-frontend
  • fnecas/geocontrib-frontend
  • MatthieuE/geocontrib-frontend
4 results
Show changes
<template>
<!-- <div>
<h1>{{ feature_type_slug }}</h1>
{{ feature_type }}
</div> -->
<div class="row">
<div class="five wide column">
<div class="ui attached secondary segment">
<h1 class="ui center aligned header">
<img
v-if="structure.geom_type == 'point'"
class="ui medium image"
src="@/assets/img/marker.png"
/>
<img
v-if="structure.geom_type == 'linestring'"
class="ui medium image"
src="@/assets/img/line.png"
/>
<img
v-if="structure.geom_type == 'polygon'"
class="ui medium image"
src="@/assets/img/polygon.png"
/>
{{ structure.title }}
</h1>
</div>
<div class="ui attached segment">
<div class="ui basic segment">
<div class="ui horizontal tiny statistic">
<div class="value">
{{ features.length }}
</div>
<div class="label">
Signalement{{ features.length > 1 ? "s" : "" }}
</div>
</div>
<h3 class="ui header">Champs</h3>
<div class="ui divided list">
<div
v-for="field in structure.customfield_set"
:key="field.label"
class="item"
>
<div class="right floated content">
<div class="description">{{ field.field_type }}</div>
</div>
<div class="content">{{ field.label }} ({{ field.name }})</div>
</div>
</div>
</div>
</div>
<div class="ui bottom attached secondary segment">
// ToDo : gérer permissions
<!-- <div v-if="permissions.can_create_feature" class="ui styled accordion"> -->
<div class="ui styled accordion">
<div
@click="showImport = !showImport"
:class="['title', { active: showImport }]"
>
<i class="dropdown icon"></i>
Importer des signalements
</div>
<div :class="['content', { active: showImport }]">
<form
id="form-import-features"
action="{% url 'geocontrib:import_from_geojson' slug=project.slug feature_type_slug=feature_type.slug %}"
method="post"
enctype="multipart/form-data"
class="ui form"
>
<div class="field">
<label
@click="importGeoJson"
class="ui icon button"
for="json_file"
>
<i class="file icon"></i>
<span class="label">Sélectionner un fichier GeoJSON ...</span>
</label>
<input
type="file"
accept="application/json, .json, .geojson"
style="display: none"
name="json_file"
id="json_file"
/>
</div>
// todo import file
<button type="submit" class="ui fluid teal icon button">
<i class="upload icon"></i> Lancer l'import
</button>
</form>
</div>
<div
@click="showExport = !showExport"
:class="['title', { active: showExport }]"
>
<i class="dropdown icon"></i>
Exporter les signalements
</div>
<div :class="['content', { active: showExport }]">
<p>
Vous pouvez télécharger l'ensemble des signalements ayant le
statut publiés pour ce type.
</p>
<a
class="ui fluid teal icon button"
href="{% url 'api:project-export' slug=project.slug feature_type_slug=feature_type.slug %}"
>
<i class="download icon"></i> Exporter
</a>
// todo gérer export
</div>
</div>
</div>
</div>
<div class="nine wide column">
<h3 class="ui header">Derniers signalements</h3>
<div
v-for="(feature, index) in features"
:key="feature.title + index"
class="ui small header"
>
<span v-if="feature.status == 'archived'" data-tooltip="Archivé">
<i class="grey archive icon"></i>
</span>
<span
v-else-if="feature.status == 'pending'"
data-tooltip="En attente de publication"
>
<i class="teal hourglass outline icon"></i>
</span>
<span v-else-if="feature.status == 'published'" data-tooltip="Publié">
<i class="olive check icon"></i>
</span>
<span v-else-if="feature.status == 'draft'" data-tooltip="Brouillon">
<i class="orange pencil alternate icon"></i>
</span>
<a
href="{% url 'geocontrib:feature_detail' slug=project.slug feature_type_slug=feature.feature_type.slug feature_id=feature.feature_id %}"
>
{{ feature.title }}
</a>
<div class="sub header">
<div>
{{ feature.description.substring(0, 200) }}
</div>
<div>
Créé le {{ feature.created_on }}
<span v-if="$store.state.user.is_authenticated">
par {{ feature.display_creator }}</span
>
</div>
</div>
</div>
<router-link
v-if="project"
:to="{ name: 'feature_list', params: { slug: project.slug } }"
class="ui right labeled icon button"
>
<i class="right arrow icon"></i>
Voir tous les signalements
</router-link>
<!-- v-if="permissions.can_create_feature" -->
<router-link
:to="{
name: 'ajouter-signalement',
params: { slug_type_signal: structure.title },
}"
class="ui icon button button-hover-green"
>
Ajouter un signalement
</router-link>
<br />// ToDo : gérer permissions
</div>
</div>
</template>
<script>
import { mapGetters, mapState } from "vuex";
export default {
name: "Feature_type_detail",
props: ["feature_type_slug"],
computed: {
...mapGetters(["project"]),
...mapState("feature", ["features"]),
...mapState("feature_type", ["feature_types"]),
structure: function () {
// * je ne sais pas pourquoi ça s'appelle structure
return this.feature_types.find(
(el) => el.title === this.feature_type_slug
);
}
},
data() {
return {
showImport: false,
showExport: true,
};
},
methods: {
toggleImport() {
console.log("toggleImport");
},
importGeoJson() {
console.log("Comment faire pour importer le geoJson ?");
},
},
created() {
if (!this.project) {
this.$store.commit("SET_PROJECT_SLUG", this.$route.params.slug);
}
},
};
</script>
\ No newline at end of file
<template>
<div v-frag>
<div v-frag v-if="permissions.can_view_project && project">
<div class="row">
<div class="four wide middle aligned column">
<img
class="ui small spaced image"
:src="
project.thumbnail.includes('default')
? require('@/assets/img/default.png')
: project.thumbnail
"
/>
<div class="ui hidden divider"></div>
<div class="ui basic teal label" data-tooltip="Membres">
<i class="user icon"></i>{{ project.nb_contributors }}
</div>
<div class="ui basic teal label" data-tooltip="Signalements">
<i class="map marker icon"></i>{{ project.nb_published_features }}
</div>
<div class="ui basic teal label" data-tooltip="Commentaires">
<i class="comment icon"></i
>{{ project.nb_published_features_comments }}
</div>
</div>
<div class="ten wide column">
<h1 class="ui header">
<div class="content">
{{ project.title }}
<div class="ui icon right floated compact buttons">
<!-- {% if permissions|lookup:'can_view_project' %} -->
<a
id="subscribe-button"
class="ui button button-hover-green"
data-tooltip="S'abonner au projet"
data-position="top center"
data-variation="mini"
@click="openModal = true"
>
<i class="inverted grey envelope icon"></i>
</a>
<!-- {% endif %} {% if project and
permissions|lookup:'can_update_project' %} -->
<router-link
v-if="$store.state.user"
:to="{ name: 'project_create', params: { action: 'update' } }"
class="ui button button-hover-orange"
data-tooltip="Modifier le projet"
data-position="top center"
data-variation="mini"
>
<i class="inverted grey pencil alternate icon"></i>
</router-link>
<!-- {% endif %} -->
</div>
<div class="ui hidden divider"></div>
<div class="sub header">
{{ project.description }}
<!-- {{ project.description | linebreaks }} -->
</div>
</div>
</h1>
</div>
</div>
<div class="row">
<div class="seven wide column">
<h3 class="ui header">Types de signalements</h3>
<!-- // todo : Create endpoints for feature_types -->
<div class="ui middle aligned divided list">
<div
v-for="(type, index) in feature_types"
:key="type.title + '-' + index"
class="item"
>
<div class="middle aligned content">
<router-link
:to="{
name: 'details-type-signalement',
params: { feature_type_slug: type.title },
}"
href="{% url 'geocontrib:feature_type_detail' slug=project.slug feature_type_slug=type.slug %}"
>
<img
v-if="type.geom_type == 'point'"
class="list-image-type"
src="@/assets/img/marker.png"
/>
<img
v-if="type.geom_type == 'linestring'"
class="list-image-type"
src="@/assets/img/line.png"
/>
<img
v-if="type.geom_type == 'polygon'"
class="list-image-type"
src="@/assets/img/polygon.png"
/>
{{ type.title }}
</router-link>
<!-- {% if project and feature_types and
permissions|lookup:'can_create_feature' %} -->
<!-- // todo: add permissions.can_create_feature and type.is_editable -->
<!-- v-if="
project &&
permissions.can_create_feature &&
type.is_editable
" -->
<router-link
:to="{
name: 'editer-signalement',
params: { slug_type_signal: type.title },
}"
v-if="project"
class="
ui
compact
small
icon
right
floated
button button-hover-green
"
data-tooltip="Éditer le type de signalement"
data-position="left center"
data-variation="mini"
href="{% url 'geocontrib:feature_type_update' slug=project.slug feature_type_slug=type.slug %}"
>
<i class="inverted grey pencil alternate icon"></i>
</router-link>
<a
v-if="project && permissions.can_create_feature"
class="
ui
compact
small
icon
right
floated
button button-hover-green
"
data-tooltip="Dupliquer un type de signalement"
data-position="left center"
data-variation="mini"
href="{% url 'geocontrib:feature_type_create' slug=project.slug %}?create_from=type.slug"
><!-- // todo : adapt -->
<i class="inverted grey copy alternate icon"></i>
</a>
<router-link
:to="{
name: 'ajouter-signalement',
params: { slug_type_signal: type.title },
}"
v-if="project && permissions.can_create_feature"
class="
ui
compact
small
icon
right
floated
button button-hover-green
"
data-tooltip="Ajouter un signalement"
data-position="left center"
data-variation="mini"
><!-- // todo : adapt -->
<i class="ui plus icon"></i>
</router-link>
<!-- {% endif %} -->
</div>
</div>
<!-- {% empty %} -->
<div>
<i> Le projet ne contient pas encore de type de signalements. </i>
</div>
<!-- {% endfor %} -->
</div>
<!-- {% if project and permissions|lookup:'can_update_project' %} -->
<!-- <a
class="ui compact basic button button-hover-green"
href="{% url 'geocontrib:feature_type_create' slug=project.slug %}"
> -->
<router-link
:to="{
name: 'ajouter-type-signalement',
params: { slug: project.slug },
}"
class="ui compact basic button button-hover-green"
>
<i class="ui plus icon"></i>Créer un nouveau type de signalement
</router-link>
<!-- </a> -->
<!-- {% endif %} -->
</div>
<div class="seven wide column">
<a href="{% url 'geocontrib:feature_list' slug=project.slug %}">
<div id="map"></div>
</a>
</div>
</div>
<div class="row">
<div class="fourteen wide column">
<div class="ui two stackable cards">
<div class="red card">
<div class="content">
<div class="center aligned header">Derniers signalements</div>
<div class="center aligned description">
<div class="ui relaxed list">
<!-- {% for item in last_features %} -->
<div class="item">
<div class="content">
<div>
<a
href="{% url 'geocontrib:feature_detail' slug=project.slug feature_type_slug=item.feature_type.slug feature_id=item.feature_id %}"
><!-- {{ item.title }} --></a
>
</div>
<div class="description">
<i
><!-- [{{ item.created_on|date:"d/m/Y" }}{% if
user.is_authenticated %}, par
{{ item.display_creator }} {% endif %}
] --></i
>
</div>
</div>
</div>
<!-- {% empty %} -->
<i>Aucun signalement pour le moment.</i>
<!-- {% endfor %} -->
</div>
</div>
</div>
</div>
<div class="orange card">
<div class="content">
<div class="center aligned header">Derniers commentaires</div>
<div class="center aligned description">
<div class="ui relaxed list">
<div
v-for="item in last_comments"
:key="item.id"
class="item"
>
// ? item.id exists ?
<div class="content">
<div>
<!-- // todo : adapt -->
<a href="item.related_feature.feature_url"
>"{{ item.comment }}"</a
>
</div>
<div class="description">
<i
>[ {{ item.created_on }}
<span v-if="user.is_authenticated">
, par {{ item.display_user }}
</span>
]</i
>
</div>
</div>
</div>
<i v-if="!last_comments || last_comments.length === 0"
>Aucun commentaire pour le moment.</i
>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="fourteen wide column">
<div class="ui grey segment">
<h3 class="ui header">Paramètres du projet</h3>
<div class="ui five stackable cards">
<div class="card">
<div class="center aligned content">
<h4 class="ui center aligned icon header">
<i class="disabled grey archive icon"></i>
<div class="content">Délai avant archivage automatique</div>
</h4>
</div>
<div class="center aligned extra content">
<!-- {{ project.archive_feature|default_if_none:"0" }} jours -->
{{ project.archive_feature }} jours
</div>
</div>
<div class="card">
<div class="content">
<h4 class="ui center aligned icon header">
<i class="disabled grey trash alternate icon"></i>
<div class="content">
Délai avant suppression automatique
</div>
</h4>
</div>
<div class="center aligned extra content">
<!-- {{ project.delete_feature|default_if_none:"0" }} jours -->
{{ project.delete_feature }} jours
</div>
</div>
<div class="card">
<div class="content">
<h4 class="ui center aligned icon header">
<i class="disabled grey eye icon"></i>
<div class="content">
Visibilité des signalements publiés
</div>
</h4>
</div>
<div class="center aligned extra content">
{{ project.access_level_pub_feature }}
</div>
</div>
<div class="card">
<div class="content">
<h4 class="ui center aligned icon header">
<i class="disabled grey eye icon"></i>
<div class="content">
Visibilité des signalements archivés
</div>
</h4>
</div>
<div class="center aligned extra content">
{{ project.access_level_arch_feature }}
</div>
</div>
<div class="card">
<div class="content">
<h4 class="ui center aligned icon header">
<i class="disabled grey cogs icon"></i>
<div class="content">Modération</div>
</h4>
</div>
<div class="center aligned extra content">
{{ project.moderation ? "Oui" : "Non" }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- {% else %} -->
<span v-else>
<i class="icon exclamation triangle"></i>
<span
>Vous ne disposez pas des droits nécessaires pour consulter ce
projet.</span
>
</span>
<!-- {% endif %} -->
<sui-modal v-model="openModal" mini class="mini subscription">
<!-- <div class="ui mini modal subscription"> -->
<i @click="openModal = false" class="close icon"></i>
<div class="ui icon header">
<i class="envelope icon"></i>
Notifications du projet
</div>
<div class="content">
<!-- {% if is_suscriber %} -->
<!-- <form
action="{% url 'geocontrib:subscription' slug=project.slug action='annuler' %}"
method="GET"
> -->
<button v-if="is_suscriber" class="ui red compact fluid button">
Se désabonner de ce projet
</button>
<!-- </form> -->
<!-- {% else %} -->
<!-- <form
action="{% url 'geocontrib:subscription' slug=project.slug action='ajouter' %}"
method="GET"
> -->
<button v-else class="ui green compact fluid button">
<!-- <button type="submit" class="ui green compact fluid button"> -->
S'abonner à ce projet
</button>
<!-- </form> -->
<!-- {% endif %} -->
</div>
<!-- </div> -->
</sui-modal>
</div>
</template>
<script>
import frag from "vue-frag";
import { mapGetters, mapState } from "vuex";
import { mapUtil } from "@/assets/js/map-util.js";
export default {
name: "Project_details",
directives: {
frag,
},
data() {
return {
slug: this.$route.params.slug,
openModal: false,
is_suscriber: false,
last_comments: [],
permissions: {
can_view_project: true,
can_create_feature: true,
},
};
},
computed: {
...mapGetters(["project"]),
...mapState("feature_type", ["feature_types"]),
BASE_URL: () => process.env.VUE_APP_BASE_URL,
},
created() {
this.$store.commit("SET_PROJECT_SLUG", this.slug);
},
mounted() {
if (this.project) {
this.initiateMap();
}
},
destroyed() {
const routes = this.$router.options.routes;
const nextRoute = this.$router.history.current.name;
if (!routes.find((el) => el.name === nextRoute).hasProject) {
this.$store.commit("SET_PROJECT", null);
}
},
methods: {
initiateMap() {
var mapDefaultViewCenter = [37.7749, -122.4194]; // defaultMapView.center;
var mapDefaultViewZoom = 13; // defaultMapView.zoom;
mapUtil.createMap({
mapDefaultViewCenter,
mapDefaultViewZoom,
});
// Load the layers.
// - if one basemap exists, check in the localstorage if one active basemap is set
// - if no current active basemap, get the first index
// - if not, load the default map and service options
// todo : create endpoints to get : 'baseMaps' ,'project' ,'layers' ,'serviceMap' ,'optionsMap' ,'features'
/* let layersToLoad = null;
if (baseMaps && baseMaps.length > 0) {
// Use active one if exists, otherwise index 0 (first basemap in the list)
const mapOptions =
JSON.parse(localStorage.getItem("geocontrib-map-options")) || {};
const basemapIndex =
mapOptions &&
mapOptions[project] &&
mapOptions[project]["current-basemap-index"]
? mapOptions[project]["current-basemap-index"]
: 0;
layersToLoad = baseMaps[basemapIndex].layers;
layersToLoad.forEach((layerToLoad) => {
layers.forEach((layer) => {
if (layer.id === layerToLoad.id) {
layerToLoad = Object.assign(layerToLoad, layer);
}
});
});
layersToLoad.reverse();
}
mapUtil.addLayers(layersToLoad, serviceMap, optionsMap);
// Remove multiple interactions with the map
mapUtil.getMap().dragging.disable();
mapUtil.getMap().doubleClickZoom.disable();
mapUtil.getMap().scrollWheelZoom.disable();
// Add the features
const featureGroup = mapUtil.addFeatures(features);
if (featureGroup && featureGroup.getLayers().length > 0) {
mapUtil.getMap().fitBounds(featureGroup.getBounds());
} */
},
},
};
</script>
<style>
@import "../../assets/resources/semantic-ui-2.4.2/semantic.min.css";
#map {
width: 100%;
height: 100%;
min-height: 250px;
}
.list-image-type {
margin-right: 5px;
height: 25px;
vertical-align: bottom;
}
</style>
\ No newline at end of file
<template>
<div class="fourteen wide column">
<form id="form-project-edit" class="ui form">
<!-- <div v-if="errors" class="ui error message"> // todo: spécifier les erreurs possibles à afficher
{{ form.non_field_errors }}
<span v-for="hidden_field in form.hidden_fields" :key="hidden_field">
{{ hidden_field.errors }}
{{ hidden_field }}
</span>
</div> -->
<!-- <i @click="goBack" class="close icon"></i> -->
<h1>
<span v-if="action === 'update'"
>Édition du projet "{{ project.title }}"</span
><!-- // todo : [pour UPDATE] récupérer project à éditer -->
<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="project.title"
/>
<!-- {{ form.title.errors }} // ? des erreurs possibles ? -->
</div>
<div class="field">
<label>Illustration du projet</label>
<img
v-if="project.thumbnail"
class="ui small image"
id="form-input-file-logo"
:src="project.thumbnail"
/>
<!-- <img
v-if="instance_thumbnail_url"
class="ui small image"
id="form-input-file-logo"
:src="instance_thumbnail_url"
/> -->
<label
@click.prevent="selectImg"
class="ui icon button"
for="thumbnail"
><!-- // todo : send image to the backend and display it after -->
<i class="file icon"></i>
<span class="label">{{
project.thumbnail
? [...project.thumbnail.split("/")].pop()
: "Sélectionner une image ..."
}}</span>
<!-- <span class="label">{{
thumbnail_value ? thumbnail_value : "Sélectionner une image ..."
}}</span> -->
</label>
<input
@change="processImgData"
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="project.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="project.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="project.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
>
<!-- <div class="ui selection dropdown">
<input
type="hidden"
:name="form.access_level_pub_feature.html_name"
:id="form.access_level_pub_feature.id_for_label"
v-model="form.access_level_pub_feature.value"
/>
<div class="default text"></div>
<i class="dropdown icon"></i>
<div class="menu">
<div
class="item"
v-for="(x, y) in form.access_level_pub_feature.field.choices"
:key="y"
:data-value="
x +
(form.access_level_pub_feature.value === x ? selected : '')
"
>
{{ x }}
</div>
</div>
</div> -->
<Dropdown
:options="form.access_level_pub_feature.field.choices"
:selected="project.access_level_pub_feature"
:selection.sync="project.access_level_pub_feature"
/>
<!-- <sui-dropdown
:text="access_level_pub_feature_selected"
:options="optionsAccessPub"
selection
v-model="access_level_pub_feature_selected"
>
</sui-dropdown> -->
<!-- {{ form.access_level_pub_feature.errors }} -->
</div>
<div class="required field">
<label for="access_level_arch_feature">
Visibilité des signalements archivés
</label>
<Dropdown
:options="form.access_level_arch_feature.field.choices"
:selected="project.access_level_arch_feature"
:selection.sync="project.access_level_arch_feature"
/>
<!-- <div class="ui selection dropdown">
<input
type="hidden"
name="access_level_arch_feature"
id="access_level_arch_feature"
v-model="project.access_level_arch_feature"
/>
<div class="default text"></div>
<i class="dropdown icon"></i>
<div class="menu">
{% for x,y in form.access_level_arch_feature.field.choices %}
<div class="item" data-value="{{ x }}" {% if form.access_level_arch_feature.value == x %} selected{% endif %}>{{ y }}</div>
{% endfor %}
</div>
</div> -->
<!-- {{ form.access_level_arch_feature.errors }} -->
</div>
</div>
<div class="field">
<div class="ui checkbox">
<input
type="checkbox"
:checked="project.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"
:checked="project.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>
<!-- {% for hidden_field in form.hidden_fields %} -->
<!-- pour passer le slug du projet parent entre GET et POST // ? marche en span ? -->
<!-- <span v-for="hidden_field in form.hidden_fields" :key="hidden_field">{{
hidden_field
}}</span> -->
<button @click.prevent="postForm" class="ui teal icon button">
<i class="white save icon"></i> Enregistrer les changements
</button>
</form>
</div>
</template>
<script>
import Dropdown from "@/components/dropdown.vue";
export default {
name: "Project_edit",
components: {
Dropdown,
},
props: ["action"],
data() {
return {
project: {
title: "Vuetification (Copie-23/07/2021 09:19)",
slug: "6-vuetification-copie-23072021-0919",
created_on: "23/07/2021",
updated_on: "29/07/2021",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
moderation: true,
thumbnail: "http://localhost:8000/media/user_1/albinoscom.jpg",
creator: 1,
access_level_pub_feature: "Utilisateur anonyme",
access_level_arch_feature: "Utilisateur anonyme",
archive_feature: 0,
delete_feature: 0,
nb_features: 2,
nb_published_features: 1,
nb_comments: 0,
nb_published_features_comments: 0,
nb_contributors: 2,
is_project_type: false,
},
// * utile pour front
thumbnail_value: null,
instance_thumbnail_url: null,
access_level_pub_feature_selected: null,
// * structure de formulaire propre à django, trop complexe pour réactivité dans vue.js
form: {
access_level_pub_feature: {
id_for_label: null,
field: {
choices: [
"Utilisateur anonyme",
"Utilisateur connecté",
"Contributeur",
],
},
},
access_level_arch_feature: {
id_for_label: null,
field: {
choices: [
"Utilisateur anonyme",
"Utilisateur connecté",
"Contributeur",
],
},
},
archive_feature: {
thumbnail: {
label: {
url: null,
},
},
},
delete_feature: {
thumbnail: {
label: {
url: null,
},
},
},
instance: {
title: null,
thumbnail: {
label: {
url: this.instance_thumbnail_url,
},
},
},
is_project_type: {
html_name: null,
label: "Est un projet type",
},
description: {
id_for_label: null,
},
moderation: {
html_name: null,
label: "Modération",
},
title: {
id_for_label: null,
help_text: null,
label: null,
field: {
max_length: null,
},
},
thumbnail: {
label: "Illustration du projet",
url: null,
value: this.thumbnail_value,
},
},
errors: null,
x: null,
};
},
computed: {
optionsAccessPub() {
return this.form.access_level_pub_feature.field.choices.map((choice) => {
return { text: choice, name: choice };
});
},
optionsAccessArchive() {
return this.form.access_level_pub_feature.field.choices.map((choice) => {
return { text: choice, name: choice };
});
},
},
methods: {
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;
},
processImgData(e) {
// * read image file
const file = e.target.files[0];
if (file) {
this.thumbnail_value = file.name;
// this.thumbnail.value = file.name;
}
let reader = new FileReader();
let _this = this;
reader.onload = function (e) {
//_this.form.instance.thumbnail.url = e.target.result;
_this.instance_thumbnail_url = e.target.result;
};
reader.readAsDataURL(file);
// todo : send file to the back (?) (not in base64)
},
selectImg() {
// * call click on hidden input field
document.getElementsByClassName("file-selection")[0].click();
},
goBack() {
const routerHistory = this.$router.options.routerHistory;
this.$router.push(routerHistory[routerHistory.length - 1] || "/");
},
postForm() {
const data = JSON.stringify(this.project);
console.log("TEST : ", data)
}
},
};
</script>
<style media="screen">
#form-input-file-logo {
margin-left: auto;
margin-right: auto;
}
.close.icon:hover {
cursor: pointer;
}
</style>
\ No newline at end of file
<template>
<div class="fourteen wide column">
<h1 class="ui header">Administration des fonds cartographiques</h1>
<form
id="form-layers"
action="."
method="post"
enctype="multipart/form-data"
class="ui form"
>
{{ formset.management_form }}
<div class="ui buttons">
<a
class="ui compact small icon left floated button green"
data-variation="mini"
:data-add-form="formset.prefix + '-ADD'"
>
<i class="ui plus icon"></i>
<span>Créer un fond cartographique</span>
</a>
</div>
<div class="ui" :data-segments="formset.prefix + '-SEGMENTS'">
<!-- {% for form in formset.forms %} {% include
'geocontrib/project/project_mapping_basemap.html' with formset=formset
form=form is_empty=False %} {% endfor %} -->
<ProjectMappingBasemap
v-for="form in formset.forms"
:key="form.id"
:form="formset.empty_form"
/>
// * need form datas from back
<fieldset disabled="disabled" style="display: none">
<div
class="formset_hidden"
:data-empty-form="formset.prefix + '-EMPTY'"
style="display: none"
>
<ProjectMappingBasemap :form="formset.empty_form" />
<!-- {% include 'geocontrib/project/project_mapping_basemap.html' with
formset=formset form=formset.empty_form is_empty=True %} -->
</div>
</fieldset>
</div>
<button type="submit" class="ui teal icon floated button">
<i class="white save icon"></i> Enregistrer les changements
</button>
</form>
</div>
</template>
<script>
// todo: add script |-> import (or not ?) from "@/assets/js/nested_formset_handlers.js"
//import Project_mapping_basemap from "@/components/project/project_mapping_basemap.vue"
import Project_mapping_basemap from "@/components/project/project_mapping_basemap.vue";
export default {
name: "Project_mapping",
components: {
ProjectMappingBasemap: Project_mapping_basemap,
},
data() {
return {
formset: {
non_form_errors: null,
empty_form: {
non_form_errors: null,
management_form: null,
forms: [
{
title: {
value: "test",
},
},
],
prefix: null,
hidden_fields: null,
title: {
id_for_label: null,
field: {
max_length: null,
},
},
nested: {
management_form: null,
},
},
management_form: null,
forms: [],
prefix: null,
hidden_fields: null,
title: {
id_for_label: null,
field: {
max_length: null,
},
},
nested: {
management_form: null,
},
},
};
},
};
</script>
\ No newline at end of file
<template>
<div class="fourteen wide column">
<h1 class="ui header">Gérer les membres</h1>
<form
id="form-members"
action="."
method="post"
enctype="multipart/form-data"
class="ui form"
>
{{ formset.non_form_errors }}
<table class="ui red table">
<tbody>
<thead>
<tr>
<th>Membre</th>
<th>{{ formset.empty_form.level.label }}</th>
</tr>
</thead>
<div id="formsets-members">
{{ formset.management_form }}
<!-- {% for form in formset %} {% if not form.DELETE.value %} {% for
hidden in form.hidden_fields %} -->
// ! À adapter une fois défini comment faire le formulaire
<!-- <div v-frag v-for="form in Object.entries(formset)" :key="form.level.id_for_label">
<div v-frag v-if="!form.DELETE.value">
<span v-for="hidden in form.hidden_fields" :key="hidden">
{{ hidden }}
</span>
<tr>
<td>
{{ form.last_name.value }} {{ form.first_name.value
}}<br /><i>{{ form.username.value }}</i>
</td>
<td>
<div class="required field">
<div class="ui selection search dropdown">
<input
type="hidden"
:name="form.level.html_name"
:id="form.level.id_for_label"
:value="form.level.value"
/>
<div class="default text"></div>
<i class="dropdown icon"></i>
<div class="menu">
{% for x,y in form.level.field.choices %}
<div
v-for="(x, y) in form.level.field.choices"
:key="y"
class="item"
:data-value="x"
:selected="form.level.value === x"
>
{{ y }}
</div>
</div>
</div>
{{ form.level.errors }}
</div>
</td>
</tr>
</div>
</div> -->
</div>
</tbody>
</table>
<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>
</template>
<script>
import frag from "vue-frag";
export default {
name: "Project_members",
directives: {
frag,
},
data() {
return {
formset: {
non_form_errors: null,
empty_form: {
level: {
label: null,
},
non_form_errors: null,
management_form: null,
forms: [
{
title: {
value: "test",
},
},
],
prefix: null,
hidden_fields: null,
title: {
id_for_label: null,
field: {
max_length: null,
},
},
nested: {
management_form: null,
},
},
management_form: null,
forms: [],
prefix: null,
hidden_fields: null,
title: {
id_for_label: null,
field: {
max_length: null,
},
},
nested: {
management_form: null,
},
},
};
},
};
</script>
\ No newline at end of file
<template>
<div class="row">
<div class="seven wide column">
<h3 class="ui header">
Créer un projet à partir d'un modèle disponible:
</h3>
<div class="ui divided items">
<div v-for="project in project_types" :key="project.slug" class="item">
<div class="ui tiny image">
<img :src="project.thumbnail" />
</div>
<div class="middle aligned content">
<div class="description">
// todo : create link to edit page from project //
<a
:href="`project_create?create_from=${project.slug}`"
>{{ project.title }}</a
>
<p>{{ project.description }}</p>
<strong v-if="project.moderation">Projet modéré</strong>
<strong v-else>Projet non modéré</strong>
</div>
<div class="meta">
<span data-tooltip="Délai avant archivage">
{{ project.archive_feature }}&nbsp;<i class="box icon"></i>
</span>
<span data-tooltip="Délai avant suppression">
{{ project.archive_feature }}&nbsp;<i
class="trash alternate icon"
></i>
</span>
<span data-tooltip="Date de création">
{{ project.created_on }}&nbsp;<i class="calendar icon"></i>
</span>
</div>
<div class="meta">
<span data-tooltip="Visibilité des signalement publiés">
{{ project.access_level_pub_feature }}&nbsp;<i
class="eye icon"
></i>
</span>
<span data-tooltip="Visibilité des signalement archivés">
{{ project.access_level_arch_feature }}&nbsp;<i
class="archive icon"
></i>
</span>
</div>
</div>
</div>
<span v-if="!project_types || project_types.length === 0">Aucun projet type n'est défini.</span>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from "vuex"
export default {
name: "Project_type_list",
computed: {
...mapGetters(["project_types"])
}
}
</script>
\ No newline at end of file
<template>
<div>
<div class="row">
<div class="fourteen wide column">
<img
class="ui centered small image"
src="@/assets/img/logo-neogeo-circle.png"
/>
<h2 class="ui center aligned icon header">
<div class="content">
{{ APPLICATION_NAME }}
<div class="sub header">{{ APPLICATION_ABSTRACT }}</div>
</div>
</h2>
</div>
</div>
<div class="row">
<div class="six wide column">
<h3 class="ui horizontal divider header">CONNEXION</h3>
<div v-if="form.errors" class="ui warning message">
<div class="header">
Les informations d'identification sont incorrectes.
</div>
NB: Seuls les comptes actifs peuvent se connecter.
</div>
<form class="ui form" role="form" type="post" @submit.prevent="login">
<div class="ui stacked secondary segment">
<div class="six field required">
<div class="ui left icon input">
<i class="user icon"></i>
<input
v-model="username_value"
type="text"
name="username"
placeholder="Utilisateur"
/>
</div>
</div>
<div class="six field required">
<div class="ui left icon input">
<i class="lock icon"></i>
<input
v-model="password_value"
type="password"
name="password"
placeholder="Mot de passe"
/>
</div>
</div>
<button class="ui fluid large teal submit button" type="submit">
Login
</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
username_value: null,
password_value: null,
logged: false,
form: {
errors: null,
},
};
},
computed: {
LOGO_PATH: () => process.env.VUE_APP_LOGO_PATH,
APPLICATION_NAME: () => process.env.VUE_APP_APPLICATION_NAME,
APPLICATION_ABSTRACT: () => process.env.VUE_APP_APPLICATION_ABSTRACT,
},
methods: {
login() {
this.$store.dispatch("LOGIN", {
username: this.username_value,
password: this.password_value,
});
},
},
};
</script>
\ No newline at end of file
const webpack = require('webpack')
const fs = require('fs')
const packageJson = fs.readFileSync('./package.json')
const version = JSON.parse(packageJson).version || 0
const webpack = require('webpack');
const fs = require('fs');
const packageJson = fs.readFileSync('./package.json');
const version = JSON.parse(packageJson).version || 0;
module.exports = {
configureWebpack: {
plugins: [
new webpack.DefinePlugin({
'process.env': {
PACKAGE_VERSION: '"' + version + '"'
}
})
]
publicPath: '/geocontrib/',
devServer: {
proxy: {
'^/api': {
target: 'https://geocontrib.dev.neogeo.fr/api',
ws: true,
changeOrigin: true
}
}
},
pwa: {
workboxPluginMode: 'InjectManifest',
workboxOptions: {
swSrc: 'src/service-worker.js',
exclude: [
/\.map$/,
/config\/config.*\.json$/,
/manifest\.json$/
],
},
// the rest of your original module.exports code goes here
}
\ No newline at end of file
iconPaths: {
faviconSVG: null,
favicon32: null,
favicon16: null,
appleTouchIcon: null,
maskIcon: null,
msTileImage: null,
},
themeColor: '#1da025'
},
configureWebpack: {
devtool: 'source-map',
plugins: [
new webpack.DefinePlugin({
'process.env': {
PACKAGE_VERSION: '"' + version + '"'
}
})
]
},
transpileDependencies: [
// Add dependencies that use modern JavaScript syntax, based on encountered errors
'ol',
'color-rgba',
'color-parse',
'@sentry/browser',
'@sentry/core',
'@sentry/vue',
'@sentry-internal'
]
};
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
}
};
\ No newline at end of file