<template> <div id="feature-detail"> <div v-if="currentFeature" class="ui grid stackable" > <div class="row"> <div class="sixteen wide column"> <FeatureHeader @setIsCancelling="isCanceling = true" /> </div> </div> <div class="row"> <div class="eight wide column"> <FeatureTable @pushNGo="pushNgo" /> </div> <div class="eight wide column"> <div id="map" ref="map" /> <div id="popup" class="ol-popup" > <a id="popup-closer" href="#" class="ol-popup-closer" /> <div id="popup-content" /> </div> </div> </div> <div class="row"> <div class="eight wide column"> <FeatureAttachements :attachments="attachments" /> </div> <div class="eight wide column"> <FeatureComments :events="events" @fetchEvents="getFeatureEvents" /> </div> </div> <div v-if="isCanceling" class="ui dimmer modals transition visible active" style="display: flex !important" > <div :class="[ 'ui mini modal subscription', { 'active visible': isCanceling }, ]" > <i class="close icon" aria-hidden="true" @click="isCanceling = false" /> <div class="ui icon header"> <i class="trash alternate icon" aria-hidden="true" /> Supprimer le signalement </div> <div class="actions"> <button type="button" class="ui red compact fluid button" @click="deleteFeature" > Confirmer la suppression </button> </div> </div> </div> </div> <div v-else> Pas de signalement correspondant trouvé </div> </div> </template> <script> import { mapState, mapActions, mapMutations } from 'vuex'; import mapService from '@/services/map-service'; import axios from '@/axios-client.js'; import featureAPI from '@/services/feature-api'; import FeatureHeader from '@/components/Feature/Detail/FeatureHeader'; import FeatureTable from '@/components/Feature/Detail/FeatureTable'; import FeatureAttachements from '@/components/Feature/Detail/FeatureAttachements'; import FeatureComments from '@/components/Feature/Detail/FeatureComments'; import { buffer } from 'ol/extent'; export default { name: 'FeatureDetail', components: { FeatureHeader, FeatureTable, FeatureAttachements, FeatureComments }, data() { return { attachments: [], comment_form: { attachment_file: { errors: null, title: '', file: null, }, comment: { id_for_label: 'add-comment', html_name: 'add-comment', errors: '', value: null, }, }, events: [], isCanceling: false, }; }, computed: { ...mapState('projects', [ 'project' ]), ...mapState('feature-type', [ 'feature_types' ]), ...mapState('feature', [ 'currentFeature' ]), }, created() { this.SET_CURRENT_FEATURE_TYPE_SLUG(this.$route.params.slug_type_signal); this.getFeatureEvents(); this.getFeatureAttachments(); this.getLinkedFeatures(); }, mounted() { this.DISPLAY_LOADER('Recherche du signalement'); if (!this.project) { // Chargements des features et infos projet en cas d'arrivée directe sur la page ou de refresh axios.all([ this.GET_PROJECT(this.$route.params.slug), this.GET_PROJECT_INFO(this.$route.params.slug), this.GET_PROJECT_FEATURE({ project_slug: this.$route.params.slug, feature_id: this.$route.params.slug_signal })]) .then(() => { this.DISCARD_LOADER(); this.initMap(); }); } if (!this.currentFeature || this.currentFeature.feature_id !== this.$route.params.slug_signal) { this.GET_PROJECT_FEATURE({ project_slug: this.$route.params.slug, feature_id: this.$route.params.slug_signal }) .then(() => { this.DISCARD_LOADER(); this.initMap(); }); } else { this.DISCARD_LOADER(); this.initMap(); } }, beforeDestroy() { this.$store.commit('CLEAR_MESSAGES'); }, methods: { ...mapMutations([ 'DISPLAY_LOADER', 'DISCARD_LOADER' ]), ...mapMutations('feature-type', [ 'SET_CURRENT_FEATURE_TYPE_SLUG' ]), ...mapActions('projects', [ 'GET_PROJECT', 'GET_PROJECT_INFO' ]), ...mapActions('feature', [ 'GET_PROJECT_FEATURE', 'GET_PROJECT_FEATURES' ]), pushNgo(link) { this.$router.push({ name: 'details-signalement', params: { slug_type_signal: link.feature_to.feature_type_slug, slug_signal: link.feature_to.feature_id, }, }); this.getFeatureEvents(); this.getFeatureAttachments(); this.getLinkedFeatures(); this.addFeatureToMap(); }, goBackToProject(message) { this.$router.push({ name: 'project_detail', params: { slug: this.$route.params.slug, message, }, }); }, deleteFeature() { this.$store .dispatch('feature/DELETE_FEATURE', { feature_id: this.currentFeature.feature_id }) .then(async (response) => { if (response.status === 204) { await this.GET_PROJECT_FEATURES({ project_slug: this.$route.params.slug }); this.goBackToProject(); } }); }, initMap() { var mapDefaultViewCenter = this.$store.state.configuration.DEFAULT_MAP_VIEW.center; var mapDefaultViewZoom = this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom; this.map = mapService.createMap(this.$refs.map, { mapDefaultViewCenter, mapDefaultViewZoom, interactions : { doubleClickZoom :false, mouseWheelZoom: false, dragPan: false } }); // Update link to feature list with map zoom and center mapService.addMapEventListener('moveend', function () { // update link to feature list with map zoom and center /*var $featureListLink = $("#feature-list-link") var baseUrl = $featureListLink.attr("href").split("?")[0] $featureListLink.attr("href", baseUrl +`?zoom=${this.map.getZoom()}&lat=${this.map.getCenter().lat}&lng=${this.map.getCenter().lng}`)*/ }); // Load the layers. // - if one basemap exists, we load the layers of the first one // - if not, load the default map and service options let layersToLoad = null; var baseMaps = this.$store.state.map.basemaps; var layers = this.$store.state.map.availableLayers; if (baseMaps && baseMaps.length > 0) { const basemapIndex = 0; layersToLoad = baseMaps[basemapIndex].layers; layersToLoad.forEach((layerToLoad) => { layers.forEach((layer) => { if (layer.id === layerToLoad.id) { layerToLoad = Object.assign(layerToLoad, layer); } }); }); layersToLoad.reverse(); } mapService.addLayers( layersToLoad, this.$store.state.configuration.DEFAULT_BASE_MAP_SERVICE, this.$store.state.configuration.DEFAULT_BASE_MAP_OPTIONS, this.$store.state.configuration.DEFAULT_BASE_MAP_SCHEMA_TYPE, ); this.addFeatureToMap(); }, addFeatureToMap() { const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/` + `?feature_id=${this.$route.params.slug_signal}&output=geojson`; axios .get(url) .then((response) => { if (response.data.features.length > 0) { const featureGroup = mapService.addFeatures( response.data.features, {}, this.feature_types, true ); mapService.fitExtent(buffer(featureGroup.getExtent(),200)); } }) .catch((error) => { throw error; }); }, getFeatureEvents() { featureAPI .getFeatureEvents(this.$route.params.slug_signal) .then((data) => (this.events = data)); }, getFeatureAttachments() { featureAPI .getFeatureAttachments(this.$route.params.slug_signal) .then((data) => (this.attachments = data)); }, getLinkedFeatures() { featureAPI .getFeatureLinks(this.$route.params.slug_signal) .then((data) => this.$store.commit('feature/SET_LINKED_FEATURES', data) ); }, }, }; </script> <style scoped> #map { width: 100%; height: 100%; min-height: 250px; max-height: 70vh; } .prewrap { white-space: pre-wrap; } </style>