Mercurial > gemma
diff client/src/components/sections/Sections.vue @ 3290:3ada3d0347bd
client: define sections: duplicated and adjusted code from stretches
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Thu, 16 May 2019 13:18:11 +0200 |
parents | |
children | dc435fbb2d7a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/components/sections/Sections.vue Thu May 16 13:18:11 2019 +0200 @@ -0,0 +1,249 @@ +<template> + <div class="d-flex flex-column"> + <UIBoxHeader icon="road" :title="title" :closeCallback="$parent.close" /> + <div class="position-relative"> + <UISpinnerOverlay v-if="loading" /> + <SectionForm v-if="showForm" :editSection="editSection" /> + <div v-else> + <UITableHeader + :columns="[ + { id: 'properties.name', title: `${nameLabel}`, class: 'col-4' }, + { + id: 'properties.date_info', + title: `${dateLabel}`, + class: 'col-2' + }, + { + id: 'properties.source_organization', + title: `${sourceorganizationLabel}`, + class: 'col-3' + } + ]" + /> + <UITableBody + :data="filteredSections() | sortTable(sortColumn, sortDirection)" + > + <template v-slot:row="{ item: section }"> + <div class="py-1 px-2 col-4"> + <a @click="moveMapToSection(section)" href="#"> + {{ section.properties.name }} + </a> + </div> + <div class="py-1 px-2 col-2"> + {{ section.properties.date_info | surveyDate }} + </div> + <div class="py-1 px-2 col-3"> + {{ section.properties.source_organization }} + </div> + <div class="py-1 px-2 col text-right"> + <button + v-if="isInStaging(section.properties.name)" + @click="gotoStaging(section.properties.name)" + class="btn btn-xs btn-danger mr-1" + > + <font-awesome-icon + icon="exclamation-triangle" + fixed-width + v-tooltip="reviewTooltip" + /> + </button> + <button + class="btn btn-xs btn-dark mr-1" + @click=" + showForm = true; + editSection = section; + " + > + <font-awesome-icon icon="pencil-alt" fixed-width /> + </button> + <button + class="btn btn-xs btn-dark" + @click="deleteSection(section)" + > + <font-awesome-icon icon="trash" fixed-width /> + </button> + </div> + </template> + </UITableBody> + <div class="text-right p-2 border-top"> + <button + @click=" + showForm = true; + editSection = null; + " + class="btn btn-sm btn-info" + > + <translate>New section</translate> + </button> + </div> + </div> + </div> + </div> +</template> + +<style lang="sass" scoped> +.input-button + border-top-left-radius: 0 + border-bottom-left-radius: 0 + right: 0 + height: 31px +</style> + +<script> +/* 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, 2019 by via donau + * – Österreichische Wasserstraßen-Gesellschaft mbH + * Software engineering by Intevation GmbH + * + * Author(s): + * Thomas Junk <thomas.junk@intevation.de> + * Tom Gottfried <tom.gottfried@intevation.de> + */ +import { mapState, mapGetters } from "vuex"; +import { displayError, displayInfo } from "@/lib/errors"; +import { HTTP } from "@/lib/http"; +import { sortTable } from "@/lib/mixins"; + +export default { + mixins: [sortTable], + components: { + SectionForm: () => import("./SectionForm") + }, + data() { + return { + staging: [], + loading: false, + showForm: false, + editSection: null + }; + }, + computed: { + ...mapState("application", ["searchQuery"]), + ...mapGetters("map", ["openLayersMap"]), + ...mapState("imports", ["sections"]), + title() { + return this.$gettext("Define Sections"); + }, + nameLabel() { + return this.$gettext("Name"); + }, + dateLabel() { + return this.$gettext("Date"); + }, + sourceorganizationLabel() { + return this.$gettext("Source organization"); + }, + reviewTooltip() { + return this.$gettext("Review pending import"); + } + }, + methods: { + filteredSections() { + return this.sections.filter(s => { + return (s.properties.name + s.properties.source_organization) + .toLowerCase() + .includes(this.searchQuery.toLowerCase()); + }); + }, + gotoStaging(sectionName) { + let pendingImport = this.staging.find(s => s.name === sectionName); + if (pendingImport) + this.$router.push("/imports/overview/" + pendingImport.id); + }, + isInStaging(sectionName) { + return !!this.staging.find(s => s.name === sectionName); + }, + loadStagingData() { + HTTP.get("/imports?states=pending&kinds=sec", { + headers: { "X-Gemma-Auth": localStorage.getItem("token") } + }) + .then(response => { + response.data.imports.forEach(i => { + HTTP.get("/imports/" + i.id, { + headers: { "X-Gemma-Auth": localStorage.getItem("token") } + }) + .then(response => { + this.staging.push({ + id: i.id, + name: response.data.summary.section + }); + }) + .catch(error => { + const { status, data } = error.response; + displayError({ + title: this.$gettext("Backend Error"), + message: `${status}: ${data.message || data}` + }); + }) + .finally(() => (this.loading = false)); + }); + }) + .catch(error => { + const { status, data } = error.response; + displayError({ + title: this.$gettext("Backend Error"), + message: `${status}: ${data.message || data}` + }); + }); + }, + deleteSection(section) { + this.$store.commit("application/popup", { + icon: "trash", + title: this.$gettext("Delete Section"), + content: + this.$gettext("Do you really want to delete this section:") + + `<br> + <b>${section.properties.name}, ${ + section.properties.source_organization + } (${section.properties.countries})</b>`, + confirm: { + label: this.$gettext("Delete"), + icon: "trash", + callback: () => { + displayInfo({ + title: this.$gettext("Not implemented"), + message: this.$gettext("Deleting ") + section.id + }); + } + }, + cancel: { + label: this.$gettext("Cancel"), + icon: "times" + } + }); + }, + moveMapToSection(section) { + this.$store.commit("imports/selectedSectionId", section.id); + this.$store.commit("fairwayavailability/type", "sections"); + this.$store.commit("application/showFairwayDepth", true); + this.openLayersMap() + .getLayer("SECTIONS") + .setVisible(true); + this.$store.dispatch("map/moveToFeauture", { + feature: section, + zoom: 17, + preventZoomOut: true + }); + } + }, + mounted() { + this.loading = true; + this.$store + .dispatch("imports/loadSections") + .catch(error => { + const { status, data } = error.response; + displayError({ + title: this.$gettext("Backend Error"), + message: `${status}: ${data.message || data}` + }); + }) + .finally(() => (this.loading = false)); + this.loadStagingData(); + } +}; +</script>