Skip to content
Snippets Groups Projects
feature.store.js 12.9 KiB
Newer Older
import axios from '@/axios-client.js';
import router from '../../router'


const feature = {
  namespaced: true,
  state: {
    attachmentFormset: [],
    attachmentsToDelete: [],
    checkedFeatures: [],
    extra_form: [],
leandro's avatar
leandro committed
    features_count: 0,
DESPRES Damien's avatar
DESPRES Damien committed
    current_feature: [],
    linkedFormset: [],
    linked_features: [],
    statusChoices: [
      {
        name: "Brouillon",
        value: "draft",
      },
      {
        name: "En attente de publication",
        value: "pending",
      },
      {
        name: "Publié",
        value: "published",
      },
      {
        name: "Archivé",
        value: "archived",
      },
    ],
      state.features = features.sort((a, b) => {
        return new Date(b.created_on) - new Date(a.created_on); // sort features chronologically
      });
leandro's avatar
leandro committed
    SET_FEATURES_COUNT(state, features_count) {
      state.features_count = features_count;
    },
DESPRES Damien's avatar
DESPRES Damien committed
    SET_CURRENT_FEATURE(state, feature) {
      state.current_feature = feature;
    },
    UPDATE_FORM(state, payload) {
      state.form = payload;
    },
    UPDATE_EXTRA_FORM(state, extra_form) {
      const index = state.extra_form.findIndex(el => el.label === extra_form.label);
      if (index !== -1) {
        state.extra_form[index] = extra_form;
      }
    },
    SET_EXTRA_FORM(state, extra_form) {
      state.extra_form = extra_form;
    },
    CLEAR_EXTRA_FORM(state) {
      state.extra_form = [];
    },
    ADD_ATTACHMENT_FORM(state, attachmentFormset) {
      state.attachmentFormset = [...state.attachmentFormset, attachmentFormset];
    },
    UPDATE_ATTACHMENT_FORM(state, payload) {
      const index = state.attachmentFormset.findIndex((el) => el.dataKey === payload.dataKey);
      if (index !== -1) state.attachmentFormset[index] = payload
    },
    REMOVE_ATTACHMENT_FORM(state, payload) {
      state.attachmentFormset = state.attachmentFormset.filter(form => form.dataKey !== payload);
    },
    CLEAR_ATTACHMENT_FORM(state) {
      state.attachmentFormset = [];
    },
    ADD_LINKED_FORM(state, linkedFormset) {
      state.linkedFormset = [...state.linkedFormset, linkedFormset];
    },
    UPDATE_LINKED_FORM(state, payload) {
      const index = state.linkedFormset.findIndex((el) => el.dataKey === payload.dataKey);
      if (index !== -1) state.linkedFormset[index] = payload
    },
    REMOVE_LINKED_FORM(state, payload) {
      state.linkedFormset = state.linkedFormset.filter(form => form.dataKey !== payload);
    },
    SET_LINKED_FEATURES(state, payload) {
      state.linked_features = payload;
    },

    ADD_ATTACHMENT_TO_DELETE(state, attachementId) {
      state.attachmentsToDelete.push(attachementId);
    },
    REMOVE_ATTACHMENTS_ID_TO_DELETE(state, attachementId) {
      state.attachmentsToDelete = state.attachmentsToDelete.filter(el => el !== attachementId);
    },
    UPDATE_CHECKED_FEATURES(state, checkedFeatures) {
      state.checkedFeatures = checkedFeatures;
    }
Florent Lavelle's avatar
Florent Lavelle committed
    async GET_PROJECT_FEATURES({ commit, rootState }, { project_slug, feature_type__slug, ordering, search, limit, geojson = false }) {
Florent's avatar
Florent committed
      if (rootState.cancellableSearchRequest.length > 0) {
        const currentRequestCancelToken =
          rootState.cancellableSearchRequest[rootState.cancellableSearchRequest.length - 1];
        currentRequestCancelToken.cancel();
      }
Florent's avatar
Florent committed
      const cancelToken = axios.CancelToken.source();
      commit('SET_CANCELLABLE_SEARCH_REQUEST', cancelToken, { root: true });
DESPRES Damien's avatar
DESPRES Damien committed
      commit("SET_FEATURES", []);
leandro's avatar
leandro committed
      commit("SET_FEATURES_COUNT", 0);
Florent's avatar
Florent committed
      let url = `${rootState.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/feature/`;
      if (feature_type__slug) {
        url = url.concat('', `${url.includes('?') ? '&' : '?'}feature_type__slug=${feature_type__slug}`);
      }
      if (ordering) {
        url = url.concat('', `${url.includes('?') ? '&' : '?'}ordering=${ordering}`);
      }
Florent's avatar
Florent committed
      if (search) {
Timothee P's avatar
Timothee P committed
        url = url.concat('', `${url.includes('?') ? '&' : '?'}title__icontains=${search}`);
Florent's avatar
Florent committed
      }
      if (limit) {
        url = url.concat('', `${url.includes('?') ? '&' : '?'}limit=${limit}`);
Florent's avatar
Florent committed
      }
      if (geojson) url = url.concat('', '&output=geojson');
Florent Lavelle's avatar
Florent Lavelle committed

      try {
        const response = await axios.get(url, { cancelToken: cancelToken.token });
        if (response.status === 200 && response.data) {
          const features = response.data.features;
          commit("SET_FEATURES", features);
          const features_count = response.data.count;
          commit("SET_FEATURES_COUNT", features_count);
        }
Florent Lavelle's avatar
Florent Lavelle committed
      } catch (error) {
        console.error(error);
    GET_PROJECT_FEATURE({ commit, rootState }, { project_slug, feature_id }) {
DESPRES Damien's avatar
DESPRES Damien committed
      if (rootState.cancellableSearchRequest.length > 0) {
        const currentRequestCancelToken =
          rootState.cancellableSearchRequest[rootState.cancellableSearchRequest.length - 1];
        currentRequestCancelToken.cancel();
      }
DESPRES Damien's avatar
DESPRES Damien committed
      const cancelToken = axios.CancelToken.source();
      commit('SET_CANCELLABLE_SEARCH_REQUEST', cancelToken, { root: true });
      commit("SET_CURRENT_FEATURE", null);
      let url = `${rootState.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/feature/?id=${feature_id}`;
      return axios
        .get(url, { cancelToken: cancelToken.token })
DESPRES Damien's avatar
DESPRES Damien committed
        .then((response) => {
          if (response.status === 200 && response.data.features) {
            const feature = response.data.features[0];
            commit("SET_CURRENT_FEATURE", feature);
          }
          return response;
        })
        .catch((error) => {
          throw error;
        });
    },
    SEND_FEATURE({ state, rootState, commit, dispatch }, routeName) {
      commit("DISPLAY_LOADER", "Le signalement est en cours de création", { root: true })
      const message = routeName === "editer-signalement" ? "Le signalement a été mis à jour" : "Le signalement a été crée";
      function redirect(featureId) {
Florent's avatar
Florent committed
        dispatch(
          'GET_PROJECT_FEATURE',
Florent's avatar
Florent committed
          {
            project_slug: rootState.project_slug,
            feature_id: featureId
Florent's avatar
Florent committed
          }
        )
          .then(() => {
            commit("DISCARD_LOADER", null, { root: true })
            router.push({
              name: "details-signalement",
              params: {
                slug_type_signal: rootState.feature_type.current_feature_type_slug,
                slug_signal: featureId,
                message,
              },
            });
            dispatch("GET_ALL_PROJECTS", null, {root:true}) //* & refresh project list
      async function handleOtherForms(featureId) {
        await dispatch("SEND_ATTACHMENTS", featureId)
        await dispatch("PUT_LINKED_FEATURES", featureId)
        redirect(featureId);
      }

      //* prepare feature data to send
      let extraFormObject = {}; //* prepare an object to be flatten in properties of geojson
      for (const field of state.extra_form) {
        extraFormObject[field.name] = field.value;
      const geojson = {
        "id": state.form.feature_id,
        "type": "Feature",
        "geometry": state.form.geometry,
        "properties": {
          "title": state.form.title,
          "description": state.form.description.value,
          "status": state.form.status.value,
          "project": rootState.project_slug,
          "feature_type": rootState.feature_type.current_feature_type_slug,
      let url = `${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/`
      if (routeName === "editer-signalement") {
        url += `${state.form.feature_id}/?` +
        `feature_type__slug=${rootState.feature_type.current_feature_type_slug}` +
        `&project__slug=${rootState.project_slug}`
      }
      return axios({
        url,
        method: routeName === "editer-signalement" ? "PUT" : "POST",
        data: geojson
      }).then((response) => {
          if ((response.status === 200 || response.status === 201) && response.data) {
            if (state.attachmentFormset.length > 0 || state.linkedFormset.length > 0 || state.attachmentFormset.length > 0 || state.attachmentsToDelete.length > 0) {
              handleOtherForms(response.data.id)
            } else {
              redirect(response.data.id)
          }
        })
        .catch((error) => {
          commit("DISCARD_LOADER", null, { root: true })
          if (error.message === "Network Error" || window.navigator.onLine === false) {
            let arraysOffline = [];
            let localStorageArray = localStorage.getItem("geocontrib_offline");
            if (localStorageArray) {
              arraysOffline = JSON.parse(localStorageArray);
            let updateMsg = {
              project: rootState.project_slug,
              type: routeName === "editer-signalement" ? "put" : "post",
              featureId: state.form.feature_id,
              geojson: geojson
            };
            arraysOffline.push(updateMsg);
            localStorage.setItem("geocontrib_offline", JSON.stringify(arraysOffline));
            router.push({
              name: "offline-signalement",
              params: {
                slug_type_signal: rootState.feature_type.current_feature_type_slug
              },
            });
          }
          else {
            console.error(error)
    async SEND_ATTACHMENTS({ state, rootState, dispatch }, featureId) {
      const DJANGO_API_BASE = rootState.configuration.VUE_APP_DJANGO_API_BASE;
      function addFile(attachment, attchmtId) {
        let formdata = new FormData();
        formdata.append("file", attachment.fileToImport, attachment.fileToImport.name);
        return axios
          .put(`${DJANGO_API_BASE}features/${featureId}/attachments/${attchmtId}/upload-file/`, formdata)
          .then((response) => {
            return response;
          })
          .catch((error) => {
            console.error(error);
            return error
          });
      }

      function putOrPostAttachement(attachment) {
        let formdata = new FormData();
        formdata.append("title", attachment.title);
        formdata.append("info", attachment.info);

        let url = `${DJANGO_API_BASE}features/${featureId}/attachments/`
        if (attachment.id) {
          url += `${attachment.id}/`
Timothee P's avatar
Timothee P committed
        }

        return axios({
          url,
          method: attachment.id ? "PUT" : "POST",
          data: formdata
        }).then((response) => {
          if (response && (response.status === 200 || response.status === 201) && attachment.fileToImport) {
            return addFile(attachment, response.data.id);
          }
          return response
        })
        .catch((error) => {
          console.error(error);
          return error
        });

      function deleteAttachement(attachmentsId, featureId) {
          'attachmentsId': attachmentsId,
          'featureId': featureId
        }
        return dispatch("DELETE_ATTACHMENTS", payload)
          .then((response) => response);
      }
      const promisesResult = await Promise.all([
        ...state.attachmentFormset.map((attachment) => putOrPostAttachement(attachment)),
        ...state.attachmentsToDelete.map((attachmentsId) => deleteAttachement(attachmentsId, featureId))
      );
      state.attachmentsToDelete = []
      return promisesResult
    },


    DELETE_ATTACHMENTS({ commit }, payload) {
      let url = `${this.state.configuration.VUE_APP_DJANGO_API_BASE}features/${payload.featureId}/attachments/${payload.attachmentsId}/`
      return axios
        .delete(url)
        .then((response) => {
          if (response && response.status === 204) {
            commit("REMOVE_ATTACHMENTS_ID_TO_DELETE", payload.attachmentsId)
            return response
          }
        })
        .catch((error) => {
          console.error(error);
          return error
        });
    PUT_LINKED_FEATURES({ state, rootState }, featureId) {
      return axios
        .put(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${featureId}/feature-links/`, state.linkedFormset)
        .then((response) => {
          if (response.status === 200 && response.data) {
            return "La relation a bien été ajouté"
          }
        })
        .catch((error) => {
          throw error;
        });
    },

    DELETE_FEATURE({ rootState }, feature_id) {
leandro's avatar
leandro committed
      const url = `${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${feature_id}/?` +
        `feature_type__slug=${rootState.feature_type.current_feature_type_slug}` +
        `&project__slug=${rootState.project_slug}`;
      return axios
        .delete(url)
        .then((response) => response)
        .catch(() => {
          return false;
        });
leandro's avatar
leandro committed
    },
export default feature