Skip to content
Snippets Groups Projects
FeatureDetail.vue 10.6 KiB
Newer Older
Florent Lavelle's avatar
Florent Lavelle committed
      v-if="currentFeature"
Florent Lavelle's avatar
Florent Lavelle committed
      class="ui grid stackable"
Florent Lavelle's avatar
Florent Lavelle committed
        <div class="sixteen wide column">
            :features-count="featuresCount"
            :slug-signal="slugSignal"
            :feature-type="featureType"
            @setIsCancelling="isCanceling = true"
Florent Lavelle's avatar
Florent Lavelle committed
        <div class="eight wide column">
          <FeatureTable
            :feature-type="featureType"
            @tofeature="pushNgo"
Florent Lavelle's avatar
Florent Lavelle committed
          />
Florent Lavelle's avatar
Florent Lavelle committed
        <div class="eight wide column">
          <div
            id="map"
            ref="map"
          />
          <div
            id="popup"
DESPRES Damien's avatar
DESPRES Damien committed
            class="ol-popup"
          >
            <a
              id="popup-closer"
              href="#"
DESPRES Damien's avatar
DESPRES Damien committed
              class="ol-popup-closer"
            />
DESPRES Damien's avatar
DESPRES Damien committed
              id="popup-content"
            />
          </div>
Florent Lavelle's avatar
Florent Lavelle committed
        <div class="eight wide column">
          <FeatureAttachements
            :attachments="attachments"
          />
Florent Lavelle's avatar
Florent Lavelle committed
        <div class="eight wide column">
          <FeatureComments
            :events="events"
Florent Lavelle's avatar
Florent Lavelle committed
          />
        class="ui dimmer modals visible active"
        <div
          :class="[
            'ui mini modal subscription',
            { 'active visible': isCanceling },
          ]"
        >
Florent Lavelle's avatar
Florent Lavelle committed
          <i
            class="close icon"
Florent Lavelle's avatar
Florent Lavelle committed
            aria-hidden="true"
            @click="isCanceling = false"
          />
Florent Lavelle's avatar
Florent Lavelle committed
            <i
              class="trash alternate icon"
              aria-hidden="true"
            />
            Supprimer le signalement
          </div>
          <div class="actions">
Timothee P's avatar
Timothee P committed
            <button
              type="button"
              class="ui red compact fluid button"
              @click="deleteFeature"
Timothee P's avatar
Timothee P committed
              Confirmer la suppression
            </button>
Florent Lavelle's avatar
Florent Lavelle committed
    <div v-else>
      Pas de signalement correspondant trouvé
    </div>
Florent Lavelle's avatar
Florent Lavelle committed
import { mapState, mapActions, mapMutations } from 'vuex';
DESPRES Damien's avatar
DESPRES Damien committed
import mapService from '@/services/map-service';
Florent Lavelle's avatar
Florent Lavelle committed

import axios from '@/axios-client.js';
Florent Lavelle's avatar
Florent Lavelle committed
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';
DESPRES Damien's avatar
DESPRES Damien committed
import { buffer } from 'ol/extent';
  name: 'FeatureDetail',
Florent Lavelle's avatar
Florent Lavelle committed
  components: {
    FeatureHeader,
    FeatureTable,
    FeatureAttachements,
    FeatureComments
Timothee P's avatar
Timothee P committed
  },

      attachments: [],
          title: '',
          file: null,
          id_for_label: 'add-comment',
          html_name: 'add-comment',
          errors: '',
Timothee P's avatar
Timothee P committed
    ...mapState('projects', [
      'project'
    ]),
Florent Lavelle's avatar
Florent Lavelle committed
    ...mapState('feature-type', [
      'feature_types'
    ]),
    ...mapState('feature', [
Florent Lavelle's avatar
Florent Lavelle committed
      'currentFeature'
Timothee P's avatar
Timothee P committed

  watch: {
    '$route.query'(newValue, oldValue) {
      if (newValue !== oldValue) { //* Navigate back or forward to the previous or next URL
        this.initPage(); //* doesn't update the page at query changes, thus it is done manually here
      }
    },
  },

Timothee P's avatar
Timothee P committed
  created() {
    if (this.$route.params.slug_type_signal) {
      this.SET_CURRENT_FEATURE_TYPE_SLUG(this.$route.params.slug_type_signal);
    }
Timothee P's avatar
Timothee P committed
  },

  mounted() {
Timothee P's avatar
Timothee P committed
  },

  beforeDestroy() {
    this.$store.commit('CLEAR_MESSAGES');
Timothee P's avatar
Timothee P committed
  },

Florent Lavelle's avatar
Florent Lavelle committed
    ...mapMutations([
      'DISPLAY_LOADER',
      'DISCARD_LOADER'
    ]),
    ...mapMutations('feature', [
      'SET_CURRENT_FEATURE'
    ]),
Florent Lavelle's avatar
Florent Lavelle committed
    ...mapMutations('feature-type', [
      'SET_CURRENT_FEATURE_TYPE_SLUG'
    ]),
    ...mapActions('projects', [
      'GET_PROJECT',
      'GET_PROJECT_INFO'
    ]),
    ...mapActions('feature', [
Florent Lavelle's avatar
Florent Lavelle committed
      'GET_PROJECT_FEATURE',
      'GET_PROJECT_FEATURES'
    ]),
    async initPage() {
      await this.getPageInfo();
      this.initMap();
    },

    async getPageInfo() {
      if (this.$route.params.slug_signal) { // if coming from the route with an id
        this.slugSignal = this.$route.params.slug_signal;
      } //* else it would be retrieve after fetchFilteredFeature with offset
      this.DISPLAY_LOADER('Recherche du signalement');
      let promises = [];
      //* Chargements des features et infos projet en cas d'arrivée directe sur la page ou de refresh
      if (!this.project) {
        promises.push(
          this.GET_PROJECT(this.$route.params.slug),
          this.GET_PROJECT_INFO(this.$route.params.slug),
        );
      }
      //* changement de requête selon s'il y a un id ou un offset
      if (this.$route.query.offset >= 0) {
        promises.push(this.fetchFilteredFeature());
      } else if (!this.currentFeature || this.currentFeature.feature_id !== this.slugSignal) {
        promises.push(
          this.GET_PROJECT_FEATURE({
            project_slug: this.$route.params.slug,
            feature_id: this.slugSignal,
          })
        );
      }
      await axios.all(promises);
      this.getFeatureEvents();
      this.getFeatureAttachments();
      this.getLinkedFeatures();
      this.DISCARD_LOADER();
    },

    async pushNgo(newEntry) {
      this.$router.push(newEntry); //* update the params or queries in the route/url
      await this.getPageInfo();
      mapService.removeFeatures();
leandro's avatar
leandro committed
    goBackToProject(message) {
      this.$router.push({
        name: 'project_detail',
leandro's avatar
leandro committed
        params: {
leandro's avatar
leandro committed
          message,
        },
      });
    },
Florent Lavelle's avatar
Florent Lavelle committed
        .dispatch('feature/DELETE_FEATURE', { feature_id: this.currentFeature.feature_id })
        .then(async (response) => {
            await this.GET_PROJECT_FEATURES({
              project_slug: this.$route.params.slug
            });
    fetchFilteredFeature() {
      const queryString = new URLSearchParams(this.$route.query);
      const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature-paginated/?limit=1&${queryString}`;
      return featureAPI.getPaginatedFeatures(url)
        .then((data) => {
          if (data && data.results && data.results[0]) {
            this.featuresCount = data.count;
            this.previous = data.previous;
            this.next = data.next;
            this.SET_CURRENT_FEATURE(data.results[0]);
            const { feature_id, feature_type } = data.results[0];
            this.slugSignal = feature_id;
            this.featureType = feature_type;
            return { feature_id };
          }
          return;
        });
    },

    initMap() {
      var mapDefaultViewCenter =
        this.$store.state.configuration.DEFAULT_MAP_VIEW.center;
      var mapDefaultViewZoom =
        this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom;
DESPRES Damien's avatar
DESPRES Damien committed
      this.map = mapService.createMap(this.$refs.map, {
Florent Lavelle's avatar
Florent Lavelle committed
        interactions : {
          doubleClickZoom :false,
          mouseWheelZoom: false,
          dragPan: false
        }
      });

      // Update link to feature list with map zoom and center
DESPRES Damien's avatar
DESPRES Damien committed
      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;
DESPRES Damien's avatar
DESPRES Damien committed
        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();
      }
DESPRES Damien's avatar
DESPRES Damien committed
      mapService.addLayers(
        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() {
leandro's avatar
leandro committed
      const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/` +
                  `?feature_id=${this.slugSignal}&output=geojson`;
          if (response.data.features.length > 0) {
DESPRES Damien's avatar
DESPRES Damien committed
            const featureGroup = mapService.addFeatures(
Florent Lavelle's avatar
Florent Lavelle committed
              this.feature_types,
              true
DESPRES Damien's avatar
DESPRES Damien committed
            mapService.fitExtent(buffer(featureGroup.getExtent(),200));
    getFeatureEvents() {
      featureAPI
        .then((data) => (this.events = data));
    },

    getFeatureAttachments() {
      featureAPI
        .then((data) => (this.attachments = data));
    },

    getLinkedFeatures() {
      featureAPI
          this.$store.commit('feature/SET_LINKED_FEATURES', data)
Timothee P's avatar
Timothee P committed
<style scoped>
#map {
  width: 100%;
  height: 100%;
  min-height: 250px;
  max-height: 70vh;
}