view client/src/store/imports.js @ 3605:d02d4e31491b

sidebar: move staging notifications to store and update notifications after finishing review
author Thomas Junk <thomas.junk@intevation.de>
date Wed, 05 Jun 2019 11:48:15 +0200
parents 3ada3d0347bd
children a130b5e55ffc
line wrap: on
line source

/* This is Free Software under GNU Affero General Public License v >= 3.0
 * without warranty, see README.md and license for details.
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 * License-Filename: LICENSES/AGPL-3.0.txt
 *
 * Copyright (C) 2018 by via donau
 *   – Österreichische Wasserstraßen-Gesellschaft mbH
 * Software engineering by Intevation GmbH
 *
 * Author(s):
 * Thomas Junk <thomas.junk@intevation.de>
 */

import { HTTP } from "@/lib/http";
import { WFS } from "ol/format";
import { equalTo as equalToFilter } from "ol/format/filter";
import { startOfHour, endOfHour } from "date-fns";

const STATES = {
  NEEDSAPPROVAL: "pending",
  APPROVED: "accepted",
  REJECTED: "declined"
};

// initial state
const init = () => {
  return {
    failed: false,
    pending: false,
    accepted: false,
    declined: false,
    warning: false,
    stretches: [],
    selectedStretchId: null,
    sections: [],
    selectedSectionId: null,
    imports: [],
    reviewed: [],
    show: null,
    showAdditional: null,
    showLogs: null,
    details: [],
    startDate: startOfHour(new Date()),
    endDate: endOfHour(new Date()),
    stagingNotifications: null,
    prev: null,
    next: null
  };
};

const getFromWFS = (type, filter) => {
  return new Promise((resolve, reject) => {
    var featureCollectionRequest = new WFS().writeGetFeature({
      srsName: "EPSG:4326",
      featureNS: "gemma",
      featurePrefix: "gemma",
      featureTypes: [type],
      outputFormat: "application/json",
      filter: filter
    });
    HTTP.post(
      "/internal/wfs",
      new XMLSerializer().serializeToString(featureCollectionRequest),
      {
        headers: {
          "X-Gemma-Auth": localStorage.getItem("token"),
          "Content-type": "text/xml; charset=UTF-8"
        }
      }
    )
      .then(response => {
        resolve(response);
      })
      .catch(error => {
        reject(error);
      });
  });
};

const clearFilterCriteria = state => {
  state.warning = false;
  state.successful = false;
  state.failed = false;
  state.pending = false;
  state.accepted = false;
  state.declined = false;
};

const imports = {
  init,
  namespaced: true,
  state: init(),
  getters: {
    filters: state => {
      return ["failed", "pending", "accepted", "declined", "warning"].filter(
        x => state[x]
      );
    }
  },
  mutations: {
    setStagingNotifications: (state, stagingNotifications) => {
      state.stagingNotifications = stagingNotifications;
    },
    setPrev: (state, prev) => {
      state.prev = prev;
    },
    setNext: (state, next) => {
      state.next = next;
    },
    setStartDate: (state, start) => {
      state.startDate = start;
    },
    setEndDate: (state, end) => {
      state.endDate = end;
    },
    setCurrentDetails: (state, details) => {
      state.details = details;
    },
    toggleFilter: (state, name) => {
      state[name] = !state[name];
      const allSet =
        state.failed &&
        state.pending &&
        state.accepted &&
        state.declined &&
        state.warning;
      if (allSet) {
        clearFilterCriteria(state);
      }
    },
    clearFilters: state => {
      clearFilterCriteria(state);
    },
    setStretches: (state, stretches) => {
      state.stretches = stretches;
    },
    selectedStretchId: (state, id) => {
      state.selectedStretchId = id;
    },
    setSections: (state, sections) => {
      state.sections = sections;
    },
    selectedSectionId: (state, id) => {
      state.selectedSectionId = id;
    },
    setReviewed: (state, reviewed) => {
      state.reviewed = reviewed;
    },
    setImports: (state, imports) => {
      const lookUp = state.reviewed.reduce((o, n) => {
        const { id, status } = n;
        o[id] = status;
        return o;
      }, {});
      imports = imports.map(x => {
        if (x.state === "pending") {
          const reviewState = lookUp[x.id];
          if (reviewState) {
            x.status = reviewState;
          } else {
            x.status = STATES.NEEDSAPPROVAL;
          }
        }
        return x;
      });
      state.imports = imports;
    },
    showDetailsFor: (state, id) => {
      state.show = id;
    },
    hideDetails: state => {
      state.show = null;
    },
    showAdditionalInfoFor: (state, id) => {
      state.showAdditional = id;
    },
    hideAdditionalInfo: state => {
      state.showAdditional = false;
    },
    showAdditionalLogsFor: (state, id) => {
      state.showLogs = id;
    },
    hideAdditionalLogs: state => {
      state.showLogs = false;
    },
    toggleApprove: (state, change) => {
      const { id, newStatus } = change;
      const stagedResult = state.imports.find(e => {
        return e.id === id;
      });
      if (stagedResult.status === newStatus) {
        stagedResult.status = STATES.NEEDSAPPROVAL;
        state.reviewed = state.reviewed.filter(x => x.id !== stagedResult.id);
      } else {
        stagedResult.status = newStatus;
        let index = state.reviewed.findIndex(r => r.id === id);
        if (index !== -1) {
          state.reviewed[index].status = newStatus;
        } else {
          state.reviewed.push({ id: stagedResult.id, status: newStatus });
        }
      }
    }
  },
  actions: {
    loadStagingNotifications({ commit }) {
      return new Promise((resolve, reject) => {
        HTTP.get("/imports?states=pending&count=true", {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            commit("setStagingNotifications", response.data);
            resolve(response);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    loadStretch(context, name) {
      return new Promise((resolve, reject) => {
        getFromWFS("stretches_geoserver", equalToFilter("name", name))
          .then(response => {
            resolve(response);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    loadStretches({ commit }) {
      return new Promise((resolve, reject) => {
        getFromWFS("stretches_geoserver", equalToFilter("staging_done", true))
          .then(response => {
            if (response.data.features) {
              commit("setStretches", response.data.features);
            } else {
              commit("setStretches", []);
            }
            resolve(response);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    saveStretch(context, stretch) {
      return new Promise((resolve, reject) => {
        HTTP.post("/imports/st", stretch, {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            resolve(response);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    loadSection(context, name) {
      return new Promise((resolve, reject) => {
        getFromWFS("sections_geoserver", equalToFilter("name", name))
          .then(response => {
            resolve(response);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    loadSections({ commit }) {
      return new Promise((resolve, reject) => {
        getFromWFS("sections_geoserver", equalToFilter("staging_done", true))
          .then(response => {
            if (response.data.features) {
              commit("setSections", response.data.features);
            } else {
              commit("setSections", []);
            }
            resolve(response);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    saveSection(context, section) {
      return new Promise((resolve, reject) => {
        HTTP.post("/imports/sec", section, {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            resolve(response);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    getImports({ commit }, options) {
      let { filter, from, to, query } = options;
      let queryParams = "";
      const hasWarning = filter.includes("warning");
      filter = filter.filter(x => x != "warning");
      if (filter && filter.length > 0) {
        queryParams = "?states=" + filter.join(",");
        if (hasWarning) queryParams += "&warnings=true";
        queryParams += "&from=" + from;
        queryParams += "&to=" + to;
        queryParams += "&query=" + query;
      } else {
        if (hasWarning) {
          queryParams += "?warnings=true";
          queryParams += "&from=" + from;
          queryParams += "&to=" + to;
          queryParams += "&query=" + query;
        } else {
          queryParams += "?from=" + from;
          queryParams += "&to=" + to;
          queryParams += "&query=" + query;
        }
      }
      return new Promise((resolve, reject) => {
        HTTP.get("/imports" + queryParams, {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            const { imports, prev, next } = response.data;
            commit("setPrev", prev);
            commit("setNext", next);
            commit("setImports", imports);
            resolve(response);
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    confirmReview(context, reviewResults) {
      return new Promise((resolve, reject) => {
        HTTP.patch("/imports", reviewResults, {
          headers: {
            "X-Gemma-Auth": localStorage.getItem("token"),
            "Content-type": "application/json"
          }
        })
          .then(response => {
            resolve(response);
          })
          .catch(error => {
            reject(error);
          });
      });
    }
  }
};

export { imports, STATES };