Mercurial > gemma
changeset 1612:b5061deb9ab9
refac: move staging area to separate folder
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Tue, 18 Dec 2018 12:29:48 +0100 |
parents | 1835d1c9eb9b |
children | f2d24dceecc7 |
files | client/src/components/Contextbox.vue client/src/components/Staging.vue client/src/components/staging/Staging.vue |
diffstat | 3 files changed, 237 insertions(+), 237 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/components/Contextbox.vue Tue Dec 18 11:53:53 2018 +0100 +++ b/client/src/components/Contextbox.vue Tue Dec 18 12:29:48 2018 +0100 @@ -28,7 +28,7 @@ name: "contextbox", components: { Bottlenecks: () => import("./Bottlenecks"), - Staging: () => import("./Staging.vue") + Staging: () => import("./staging/Staging.vue") }, computed: { ...mapState("application", [
--- a/client/src/components/Staging.vue Tue Dec 18 11:53:53 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -<template> - <div class="w-90 stagingcard"> - <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center"> - <font-awesome-icon - class="mr-2" - icon="clipboard-check" - ></font-awesome-icon> - <translate>Staging Area</translate> - </h6> - <table class="table"> - <thead> - <tr> - <th><translate>Name</translate></th> - <th><translate>Type</translate></th> - <th><translate>Date</translate></th> - <th><translate>Imported</translate></th> - <th><translate>Username</translate></th> - <th> </th> - <th> </th> - </tr> - </thead> - <tbody v-if="filteredData.length"> - <tr :key="data.id" v-for="data in filteredData"> - <td> - <a @click="zoomTo(data.id)" href="#">{{ - data.summary.bottleneck - }}</a> - </td> - <td>{{ data.kind.toUpperCase() }}</td> - <td>{{ formatSurveyDate(data.summary.date) }}</td> - <td>{{ formatSurveyDate(data.enqueued.split("T")[0]) }}</td> - <td>{{ data.user }}</td> - <td> - <button - :class="{ - btn: true, - 'btn-sm': true, - 'btn-outline-success': needsApproval(data) || isRejected(data), - 'btn-success': isApproved(data) - }" - @click="toggleApproval(data.id, $options.STATES.APPROVED)" - > - <font-awesome-icon icon="check"></font-awesome-icon> - </button> - </td> - <td> - <button - :class="{ - btn: true, - 'btn-sm': true, - 'btn-outline-danger': needsApproval(data) || isApproved(data), - 'btn-danger': isRejected(data) - }" - @click="toggleApproval(data.id, $options.STATES.REJECTED)" - > - <font-awesome-icon icon="times"></font-awesome-icon> - </button> - </td> - </tr> - </tbody> - <tbody v-else> - <tr> - <td class="text-center" colspan="6"> - <translate>No results.</translate> - </td> - </tr> - </tbody> - </table> - <div class="p-3" v-if="filteredData.length"> - <button @click="confirmReview" class="confirm-button btn btn-info"> - <translate>Confirm</translate> - </button> - </div> - <div class="p-3"> - <button @click="loadData" class="refresh btn btn-dark">Refresh</button> - </div> - </div> -</template> - -<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 by via donau - * – Österreichische Wasserstraßen-Gesellschaft mbH - * Software engineering by Intevation GmbH - * - * Author(s): - * Thomas Junk <thomas.junk@intevation.de> - * Markus Kottländer <markus@intevation.de> - */ -import { mapState } from "vuex"; -import { HTTP } from "../lib/http.js"; -import { STATES } from "../store/imports.js"; -import { displayError, displayInfo } from "../lib/errors.js"; -import { formatSurveyDate } from "../lib/date.js"; - -export default { - data() { - return {}; - }, - mounted() { - this.loadData(); - }, - computed: { - ...mapState("application", ["searchQuery"]), - ...mapState("imports", ["staging"]), - filteredData() { - return this.staging.filter(data => { - const result = [data.id + "", data.enqueued, data.kind, data.user].some( - x => x.toLowerCase().includes(this.searchQuery.toLowerCase()) - ); - return result; - }); - } - }, - STATES: STATES, - methods: { - formatSurveyDate(date) { - return formatSurveyDate(date); - }, - loadData() { - this.$store.dispatch("imports/getStaging").catch(error => { - const { status, data } = error.response; - displayError({ - title: "Backend Error", - message: `${status}: ${data.message || data}` - }); - }); - }, - confirmReview() { - const reviewResults = this.staging - .filter(x => x.status !== STATES.NEEDSAPPROVAL) - .map(r => { - return { - id: r.id, - state: r.status - }; - }); - if (!reviewResults.length) return; - HTTP.patch("/imports", reviewResults, { - headers: { - "X-Gemma-Auth": localStorage.getItem("token"), - "Content-type": "application/json" - } - }) - .then(response => { - const messages = response.data - .map(x => { - if (x.message) return x.message; - if (x.error) return x.error; - }) - .join("\n\n"); - displayInfo({ - title: "Staging Area", - message: messages, - options: { - timeout: 0, - buttons: [{ text: "Ok", action: null, bold: true }] - } - }); - this.loadData(); - }) - .catch(error => { - const { status, data } = error.response; - displayError({ - title: "Backend Error", - message: `${status}: ${data.message || data}` - }); - }); - }, - needsApproval(item) { - return item.status === STATES.NEEDSAPPROVAL; - }, - isRejected(item) { - return item.status === STATES.REJECTED; - }, - isApproved(item) { - return item.status === STATES.APPROVED; - }, - zoomTo(id) { - if (!id) return; - const soundingResult = this.filteredData.filter(x => x.id == id)[0]; - const { lat, lon, bottleneck, date } = soundingResult.summary; - const coordinates = [lat, lon]; - - this.$store.commit("map/moveMap", { - coordinates: coordinates, - zoom: 17, - preventZoomOut: true - }); - this.$store - .dispatch("bottlenecks/setSelectedBottleneck", bottleneck) - .then(() => { - this.$store.commit("bottlenecks/setSelectedSurveyByDate", date); - }); - }, - toggleApproval(id, newStatus) { - this.$store.commit("imports/toggleApproval", { - id: id, - newStatus: newStatus - }); - } - } -}; -</script> - -<style lang="scss" scoped> -.refresh { - position: absolute; - left: $offset; - bottom: $offset; -} -.table th, -td { - font-size: 0.9rem; - border-top: 0px !important; - border-bottom-width: 1px; - text-align: left; - padding: 0.5rem !important; -} - -.stagingcard { - position: relative; - min-height: 150px; -} - -.confirm-button { - position: absolute; - right: $offset; - bottom: $offset; -} -</style>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/components/staging/Staging.vue Tue Dec 18 12:29:48 2018 +0100 @@ -0,0 +1,236 @@ +<template> + <div class="w-90 stagingcard"> + <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center"> + <font-awesome-icon + class="mr-2" + icon="clipboard-check" + ></font-awesome-icon> + <translate>Staging Area</translate> + </h6> + <table class="table"> + <thead> + <tr> + <th><translate>Name</translate></th> + <th><translate>Type</translate></th> + <th><translate>Date</translate></th> + <th><translate>Imported</translate></th> + <th><translate>Username</translate></th> + <th> </th> + <th> </th> + </tr> + </thead> + <tbody v-if="filteredData.length"> + <tr :key="data.id" v-for="data in filteredData"> + <td> + <a @click="zoomTo(data.id)" href="#">{{ + data.summary.bottleneck + }}</a> + </td> + <td>{{ data.kind.toUpperCase() }}</td> + <td>{{ formatSurveyDate(data.summary.date) }}</td> + <td>{{ formatSurveyDate(data.enqueued.split("T")[0]) }}</td> + <td>{{ data.user }}</td> + <td> + <button + :class="{ + btn: true, + 'btn-sm': true, + 'btn-outline-success': needsApproval(data) || isRejected(data), + 'btn-success': isApproved(data) + }" + @click="toggleApproval(data.id, $options.STATES.APPROVED)" + > + <font-awesome-icon icon="check"></font-awesome-icon> + </button> + </td> + <td> + <button + :class="{ + btn: true, + 'btn-sm': true, + 'btn-outline-danger': needsApproval(data) || isApproved(data), + 'btn-danger': isRejected(data) + }" + @click="toggleApproval(data.id, $options.STATES.REJECTED)" + > + <font-awesome-icon icon="times"></font-awesome-icon> + </button> + </td> + </tr> + </tbody> + <tbody v-else> + <tr> + <td class="text-center" colspan="6"> + <translate>No results.</translate> + </td> + </tr> + </tbody> + </table> + <div class="p-3" v-if="filteredData.length"> + <button @click="confirmReview" class="confirm-button btn btn-info"> + <translate>Confirm</translate> + </button> + </div> + <div class="p-3"> + <button @click="loadData" class="refresh btn btn-dark">Refresh</button> + </div> + </div> +</template> + +<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 by via donau + * – Österreichische Wasserstraßen-Gesellschaft mbH + * Software engineering by Intevation GmbH + * + * Author(s): + * Thomas Junk <thomas.junk@intevation.de> + * Markus Kottländer <markus@intevation.de> + */ +import { mapState } from "vuex"; +import { HTTP } from "@/lib/http.js"; +import { STATES } from "@/store/imports.js"; +import { displayError, displayInfo } from "@/lib/errors.js"; +import { formatSurveyDate } from "@/lib/date.js"; + +export default { + data() { + return {}; + }, + mounted() { + this.loadData(); + }, + computed: { + ...mapState("application", ["searchQuery"]), + ...mapState("imports", ["staging"]), + filteredData() { + return this.staging.filter(data => { + const result = [data.id + "", data.enqueued, data.kind, data.user].some( + x => x.toLowerCase().includes(this.searchQuery.toLowerCase()) + ); + return result; + }); + } + }, + STATES: STATES, + methods: { + formatSurveyDate(date) { + return formatSurveyDate(date); + }, + loadData() { + this.$store.dispatch("imports/getStaging").catch(error => { + const { status, data } = error.response; + displayError({ + title: "Backend Error", + message: `${status}: ${data.message || data}` + }); + }); + }, + confirmReview() { + const reviewResults = this.staging + .filter(x => x.status !== STATES.NEEDSAPPROVAL) + .map(r => { + return { + id: r.id, + state: r.status + }; + }); + if (!reviewResults.length) return; + HTTP.patch("/imports", reviewResults, { + headers: { + "X-Gemma-Auth": localStorage.getItem("token"), + "Content-type": "application/json" + } + }) + .then(response => { + const messages = response.data + .map(x => { + if (x.message) return x.message; + if (x.error) return x.error; + }) + .join("\n\n"); + displayInfo({ + title: "Staging Area", + message: messages, + options: { + timeout: 0, + buttons: [{ text: "Ok", action: null, bold: true }] + } + }); + this.loadData(); + }) + .catch(error => { + const { status, data } = error.response; + displayError({ + title: "Backend Error", + message: `${status}: ${data.message || data}` + }); + }); + }, + needsApproval(item) { + return item.status === STATES.NEEDSAPPROVAL; + }, + isRejected(item) { + return item.status === STATES.REJECTED; + }, + isApproved(item) { + return item.status === STATES.APPROVED; + }, + zoomTo(id) { + if (!id) return; + const soundingResult = this.filteredData.filter(x => x.id == id)[0]; + const { lat, lon, bottleneck, date } = soundingResult.summary; + const coordinates = [lat, lon]; + + this.$store.commit("map/moveMap", { + coordinates: coordinates, + zoom: 17, + preventZoomOut: true + }); + this.$store + .dispatch("bottlenecks/setSelectedBottleneck", bottleneck) + .then(() => { + this.$store.commit("bottlenecks/setSelectedSurveyByDate", date); + }); + }, + toggleApproval(id, newStatus) { + this.$store.commit("imports/toggleApproval", { + id: id, + newStatus: newStatus + }); + } + } +}; +</script> + +<style lang="scss" scoped> +.refresh { + position: absolute; + left: $offset; + bottom: $offset; +} +.table th, +td { + font-size: 0.9rem; + border-top: 0px !important; + border-bottom-width: 1px; + text-align: left; + padding: 0.5rem !important; +} + +.stagingcard { + position: relative; + min-height: 150px; +} + +.confirm-button { + position: absolute; + right: $offset; + bottom: $offset; +} +</style>