Mercurial > gemma
view client/src/components/importschedule/Importscheduledetail.vue @ 1965:f845236e76bd
Translated using Weblate (Bulgarian)
Currently translated at 2.7% (6 of 221 strings)
Translation: Gemma/client
Translate-URL: https://hosted.weblate.org/projects/gemma/client/bg/
author | Fadi Abbud <fadi.abbud@intevation.de> |
---|---|
date | Wed, 23 Jan 2019 09:38:17 +0000 |
parents | 3ccdd635d4fd |
children | 29f02d0043a9 |
line wrap: on
line source
<template> <div class="importscheduledetails fadeIn animated" v-if="importScheduleDetailVisible" > <div class="card shadow-xs importscheduledetailscard pb-5"> <h6 class="mb-0 py-2 px-3 border-bottom d-flex text-info align-items-center" > {{ dialogLabel }} <span @click="closeDetailview" class="closebutton"> <font-awesome-icon icon="times"></font-awesome-icon> </span> </h6> <div class="card-body"> <form @submit.prevent="save" class="ml-2 mr-2"> <div class="d-flex flex-row"> <div class="flex-column w-50 mr-3"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Imports</translate> </small> </div> <select v-model="import_" class="custom-select" id="importtype"> <option :value="$options.IMPORTTYPES.BOTTLENECK" ><translate>Bottlenecks</translate></option > <option :value="$options.IMPORTTYPES.WATERWAYAXIS" ><translate>Waterway axis</translate></option > <option :value="$options.IMPORTTYPES.GAUGEMEASUREMENT" ><translate>Gauge measurement</translate></option > <option :value="$options.IMPORTTYPES.FAIRWAYAVAILABILITY" ><translate>Available Fairway Depths</translate></option > <option :value="$options.IMPORTTYPES.WATERWAYAREA" ><translate>Waterwayarea</translate></option > <option :value="$options.IMPORTTYPES.FAIRWAYDIMENSION" ><translate>Fairwaydimension</translate></option > <option :value="$options.IMPORTTYPES.WATERWAYGAUGES" ><translate>Waterway gauges</translate></option > <option :value="$options.IMPORTTYPES.DISTANCEMARKSVIRTUAL" ><translate>Distance Marks Virtual</translate></option > </select> </div> <div class="flex-column ml-4"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Email Notification</translate> </small> </div> <div class="flex-flex-row text-left"> <toggle-button v-model="eMailNotification" class="mt-2" :speed="100" :labels="{ checked: this.$options.on, unchecked: this.$options.off }" :width="60" :height="30" /> </div> </div> </div> <div v-if="isURLRequired"> <div class="d-flex flex-row"> <div class="flex-column mt-3 mr-3 w-100"> <div class="flex-row text-left"> <small class="text-muted"> <translate>URL</translate> </small> </div> <div class="w-100"> <input v-model="url" class="form-control" type="url" /> </div> </div> <div v-if="false" class="flex-column mt-3 text-left"> <div class="d-flex flex-row"> <small class="text-muted mr-2" ><translate>Insecure</translate> </small> </div> <div class="d-flex flex-row"> <toggle-button v-model="insecure" class="mt-2" :speed="100" :color="{ checked: '#FF0000', unchecked: '#E9ECEF', disabled: '#CCCCCC' }" :labels="{ checked: this.$options.on, unchecked: this.$options.off }" :width="60" :height="30" /> </div> </div> </div> <div v-if="!url" class="d-flex flex-row"> <small ><translate class="text-danger" >Please enter a URL</translate ></small > </div> </div> <div v-if="isCredentialsRequired"> <div class="d-flex flex-row"> <div class="flex-column mt-3 mr-3 w-50"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Username</translate> </small> </div> <div class="w-100"> <input v-model="username" class="form-control" type="text" /> </div> <div v-if="!username" class="d-flex flex-row"> <small ><translate class="text-danger" >Please enter a Username</translate ></small > </div> </div> <div class="flex-column mt-3 w-50"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Password</translate> </small> </div> <div class="w-100 d-flex flex-row"> <input v-model="password" class="form-control" :type="showPassword" /> <span class="input-group-text ml-2" @click="passwordVisible = !passwordVisible" > <font-awesome-icon :icon="passwordVisible ? 'eye-slash' : 'eye'" ></font-awesome-icon> </span> </div> <div v-if="!password" class="d-flex flex-row"> <small ><translate class="text-danger" >Please enter a Password</translate ></small > </div> </div> </div> </div> <div v-if="isFeatureTypeRequired"> <div class="d-flex flex-row"> <div class="flex-column mt-3 mr-3 w-50"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Featuretype</translate> </small> </div> <div class="w-100"> <input v-model="featureType" class="form-control" type="text" /> </div> <div v-if="!featureType" class="d-flex flex-row"> <small ><translate class="text-danger" >Please enter a Featuretype</translate ></small > </div> </div> <div class="flex-column mt-3 w-50"> <div class="flex-row text-left"> <small class="text-muted"> <translate>SortBy</translate> </small> </div> <div class="w-100"> <input v-model="sortBy" class="form-control" type="text" /> </div> <div v-if="!sortBy" class="d-flex flex-row"> <small ><translate class="text-danger" >Please enter SortBy</translate ></small > </div> </div> </div> </div> <div v-if="import_ == $options.IMPORTTYPES.FAIRWAYDIMENSION"> <div class="d-flex flex-row"> <div class="flex-column mt-3 mr-3 w-50"> <div class="flex-row text-left"> <small class="text-muted"> <translate>LOS</translate> </small> </div> <div class="w-100"> <select v-model="LOS" class="form-control"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> </div> <div v-if="!LOS" class="d-flex flex-row"> <small ><translate class="text-danger" >Please enter a level of service</translate ></small > </div> </div> <div class="flex-column mt-3 w-50"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Depth</translate> </small> </div> <div class="d-flex flex-row"> <input v-model="depth" class="form-control" type="number" /> <div class="ml-2 my-auto">cm</div> </div> <div v-if="!depth" class="d-flex flex-row"> <small ><translate class="text-danger" >Please enter a depth</translate ></small > </div> </div> </div> <div class="d-flex flex-row"> <div class="flex-column mt-3 mr-3 w-50"> <div class="flex-row text-left"> <small class="text-muted"> <translate>MinWidth</translate> </small> </div> <div class="d-flex flex-row"> <input v-model="minWidth" class="form-control" type="number" /> <div class="ml-2 my-auto"> m</div> </div> <div v-if="!minWidth" class="d-flex flex-row"> <small ><translate class="text-danger" >Please enter a minimum width</translate ></small > </div> </div> <div class="flex-column mt-3 w-50"> <div class="flex-row text-left"> <small class="text-muted"> <translate>MaxWidth</translate> </small> </div> <div class="d-flex flex-row"> <input v-model="maxWidth" class="form-control" type="number" /> <div class="ml-2 my-auto"> m</div> </div> <div v-if="!maxWidth" class="d-flex flex-row"> <small ><translate class="text-danger" >Please enter a maximum width</translate ></small > </div> </div> </div> <div class="d-flex flex-row"> <div class="flex-column mt-3 mr-3 w-50"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Source orgranization</translate> </small> </div> <div class="w-100"> <input v-model="sourceOrganization" class="form-control" type="text" /> </div> <div v-if="!sourceOrganization" class="d-flex flex-row"> <small ><translate class="text-danger" >Please enter a source orgranization</translate ></small > </div> </div> </div> </div> <div class="d-flex flex-row"> <div class="flex-column mt-3 mr-4"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Scheduled</translate>? </small> </div> <div class="flex-flex-row text-left"> <toggle-button v-model="scheduled" class="mt-2" :speed="100" :labels="{ checked: this.$options.on, unchecked: this.$options.off }" :width="60" :height="30" /> </div> </div> <div class="flex-column mt-3 mr-2"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Simple Schedule</translate> </small> </div> <div class="flex-flex-row text-left"> <toggle-button :disabled="!scheduled" v-model="easyCron" class="mt-2" :speed="100" :labels="{ checked: this.$options.on, unchecked: this.$options.off }" :width="60" :height="30" /> </div> </div> </div> <div class="flex-column w-100 mr-2"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Schedule</translate> </small> </div> <div v-if="easyCron" class="text-left w-50"> <select :disabled="!scheduled" v-model="simple" class="form-control" ><option value="weekly"><translate>Weekly</translate></option> <option value="monthly"><translate>Monthly</translate></option> </select> </div> <div v-if="!easyCron" class="text-left w-100"> <div class="d-flex flex-row"> <h4 class="mt-auto mb-auto mr-2">{{ $options.EVERY }}</h4> <select :disabled="!scheduled" style="width: 130px;" v-model="cronMode" class="form-control" @change="clearInputs" > <option v-for="(option, key) in $options.CRONMODE" :value="key" :key="key" >{{ option }}</option > </select> <div v-if="cronMode == 'hour'" class="ml-1 d-flex flex-row"> <h4 class="mt-auto mb-auto">{{ $options.ON }}</h4> <input :disabled="!scheduled" v-model="minutes" class="cronfield ml-1 mr-1 form-control" type="number" /> <h4 class="mt-auto mb-auto">{{ $options.MINUTESPAST }}</h4> </div> <div v-if="cronMode == 'day'" class="ml-1 d-flex flex-row"> <h4 class="mt-auto mb-auto">{{ $options.AT }}</h4> <input :disabled="!scheduled" v-model="hour" class="cronfield ml-1 mr-1 form-control" type="number" /> <input :disabled="!scheduled" v-model="minutes" class="cronfield ml-1 mr-1 form-control" type="number" /> <h4 class="mt-auto mb-auto">{{ $options.OCLOCK }}</h4> </div> <div v-if="cronMode == 'week'" class="ml-1 d-flex flex-row"> <h4 class="ml-1 mr-1 mt-auto mb-auto">{{ $options.ON }}</h4> <select :disabled="!scheduled" v-model="day" class="form-control" > <option v-for="(option, key) in $options.DAYSOFWEEK" :key="key" :value="key" >{{ option }}</option > </select> <h4 class="ml-1 mt-auto mb-auto">{{ $options.AT }}</h4> <input :disabled="!scheduled" v-model="hour" class="cronfield ml-1 mr-1 form-control" type="number" /> <input :disabled="!scheduled" v-model="minutes" class="cronfield ml-1 mr-1 form-control" type="number" /> </div> <div v-if="cronMode == 'month'" class="ml-1 d-flex flex-row"> <h4 class="ml-1 mt-auto mb-auto">{{ $options.ON }}</h4> <input :disabled="!scheduled" v-model="dayOfMonth" class="cronfield ml-1 mr-1 form-control" type="number" /> <h4 class="mt-auto mb-auto">{{ $options.AT }}</h4> <input :disabled="!scheduled" v-model="hour" class="cronfield ml-1 mr-2 form-control" type="number" /> <input :disabled="!scheduled" v-model="minutes" class="cronfield ml-1 mr-2 form-control" type="number" /> <h4 class="mt-auto mb-auto">{{ $options.OCLOCK }}</h4> </div> <div v-if="cronMode == 'year'" class="ml-1 d-flex flex-row"> <h4 class="ml-1 mt-auto mb-auto">{{ $options.ON }}</h4> <input :disabled="!scheduled" v-model="dayOfMonth" class="cronfield ml-1 mr-1 form-control" type="number" /> <h4 class="mt-auto mb-auto">{{ $options.OF }}</h4> <select :disabled="!scheduled" v-model="month" class="ml-1 mr-1 form-control" > <option v-for="(option, key) in $options.MONTHS" :value="key" :key="key" >{{ option }}</option > </select> <h4 class="mt-auto mb-auto">{{ $options.ON }}</h4> <input :disabled="!scheduled" v-model="hour" class="cronfield ml-1 mr-1 form-control" type="number" /> <input :disabled="!scheduled" v-model="minutes" class="cronfield ml-1 mr-1 form-control" type="number" /> </div> </div> <div class="mt-3 w-50 d-flex flex-row"> <h5 class="mt-auto mb-auto mr-2"> <translate>Cronstring</translate> </h5> <input :disabled="!scheduled" class="form-control" v-model="cronString" type="text" /> </div> </div> </div> <button type="submit" class="shadow-sm btn btn-info submit-button"> <translate>Submit</translate> </button> <button @click="triggerManualImport" type="button" class="shadow-sm btn btn-outline-info trigger" :disabled="!triggerActive" > <font-awesome-icon class="fa-fw mr-2" fixed-width icon="play" ></font-awesome-icon ><translate>Trigger import</translate> </button> </form> </div> </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> */ import { IMPORTTYPES, IMPORTTYPEKIND, initializeCurrentSchedule } from "@/store/imports.js"; import { mapState } from "vuex"; import { displayInfo, displayError } from "@/lib/errors.js"; import app from "@/main.js"; export default { name: "importscheduledetail", data() { return { passwordVisible: false, ...initializeCurrentSchedule() }; }, IMPORTTYPES: IMPORTTYPES, EVERY: app.$gettext("Every"), MINUTESPAST: app.$gettext("minutes past"), ON: app.$gettext("on"), OF: app.$gettext("of"), AT: app.$gettext("at"), OCLOCK: app.$gettext("o' clock"), CRONMODE: { "15minutes": app.$gettext("15 minutes"), hour: app.$gettext("hour"), day: app.$gettext("day"), week: app.$gettext("week"), month: app.$gettext("month"), year: app.$gettext("year") }, DAYSOFWEEK: { 1: app.$gettext("Monday"), 2: app.$gettext("Tuesday"), 3: app.$gettext("Wednesday"), 4: app.$gettext("Thursday"), 5: app.$gettext("Friday"), 6: app.$gettext("Saturday"), 0: app.$gettext("Sunday") }, MONTHS: { 1: app.$gettext("January"), 2: app.$gettext("February"), 3: app.$gettext("March"), 4: app.$gettext("April"), 5: app.$gettext("May"), 6: app.$gettext("June"), 7: app.$gettext("July"), 8: app.$gettext("August"), 9: app.$gettext("September"), 10: app.$gettext("October"), 11: app.$gettext("November"), 12: app.$gettext("December") }, mounted() { this.initialize(); }, watch: { cronMode() { this.cronString = this.calcCronString(); }, minutes() { this.cronString = this.calcCronString(); }, hour() { this.cronString = this.calcCronString(); }, month() { this.cronString = this.calcCronString(); }, day() { this.cronString = this.calcCronString(); }, dayOfMonth() { this.cronString = this.calcCronString(); }, importScheduleDetailVisible() { this.initialize(); }, cronString() { if (this.isWeekly(this.cronString)) { this.simple = "weekly"; } if (this.isMonthly(this.cronString)) { this.simple = "monthly"; } } }, computed: { ...mapState("imports", ["importScheduleDetailVisible", "currentSchedule"]), showPassword() { if (this.passwordVisible) return "text"; return "password"; }, dialogLabel() { if (this.id) return this.$gettext("Import") + " " + this.id; return this.$gettext("New Import"); }, isCredentialsRequired() { switch (this.import_) { case this.$options.IMPORTTYPES.WATERWAYGAUGES: case this.$options.IMPORTTYPES.DISTANCEMARKSVIRTUAL: return true; default: return false; } }, isURLRequired() { switch (this.import_) { case this.$options.IMPORTTYPES.BOTTLENECK: case this.$options.IMPORTTYPES.WATERWAYAXIS: case this.$options.IMPORTTYPES.GAUGEMEASUREMENT: case this.$options.IMPORTTYPES.FAIRWAYAVAILABILITY: case this.$options.IMPORTTYPES.WATERWAYAREA: case this.$options.IMPORTTYPES.FAIRWAYDIMENSION: case this.$options.IMPORTTYPES.WATERWAYGAUGES: case this.$options.IMPORTTYPES.DISTANCEMARKSVIRTUAL: return true; default: return false; } }, isFeatureTypeRequired() { switch (this.import_) { case this.$options.IMPORTTYPES.WATERWAYAXIS: case this.$options.IMPORTTYPES.WATERWAYAREA: case this.$options.IMPORTTYPES.FAIRWAYDIMENSION: return true; default: return false; } }, isSortbyRequired() { switch (this.import_) { case this.$options.IMPORTTYPES.WATERWAYAXIS: case this.$options.IMPORTTYPES.WATERWAYAREA: case this.$options.IMPORTTYPES.FAIRWAYDIMENSION: return true; default: return false; } }, fixedSource() { if (this.import_ === this.$options.IMPORTTYPES.BOTTLENECK) return true; return false; } }, methods: { calcCronString() { let getValue = value => { return this[value] ? this[value] : "*"; }; if (this.cronMode === "15minutes") return "0 */15 * * * *"; const min = getValue("minutes"); const h = getValue("hour"); const dm = getValue("dayOfMonth"); const m = getValue("month"); const wd = getValue("day"); return `0 ${min} ${h} ${dm} ${m} ${wd}`; }, validateBottleneckfields() { return !!this.url; }, initialize() { this.id = this.currentSchedule.id; this.importType = this.currentSchedule.importType; this.schedule = this.currentSchedule.schedule; this.scheduled = this.currentSchedule.scheduled; this.import_ = this.currentSchedule.import_; this.importSource = this.currentSchedule.importSource; this.eMailNotification = this.currentSchedule.eMailNotification; this.easyCron = this.currentSchedule.easyCron; this.cronMode = this.currentSchedule.cronMode; this.minutes = this.currentSchedule.minutes; this.month = this.currentSchedule.month; this.hour = this.currentSchedule.hour; this.day = this.currentSchedule.day; this.dayOfMonth = this.currentSchedule.dayOfMonth; this.simple = this.currentSchedule.simple; this.url = this.currentSchedule.url; this.insecure = this.currentSchedule.insecure; this.cronString = this.currentSchedule.cronString; this.featureType = this.currentSchedule.featureType; this.sortBy = this.currentSchedule.sortBy; this.username = this.currentSchedule.username; this.password = this.currentSchedule.password; this.LOS = this.currentSchedule.LOS; this.minWidth = this.currentSchedule.minWidth; this.maxWidth = this.currentSchedule.maxWidth; this.depth = this.currentSchedule.depth; this.sourceOrganization = this.currentSchedule.sourceOrganization; }, isWeekly(cron) { return /0 \d{1,2} \d{1,2} \* \* \d{1}/.test(cron); }, isMonthly(cron) { return /0 \d{1,2} \d{1,2} \d{1,2} \* \*/.test(cron); }, clearInputs() { this.minutes = null; this.month = null; this.hour = null; this.day = null; this.dayOfMonth = null; }, triggerManualImport() { if (!this.triggerActive) return; if (!this.import_) return; let data = {}; if (this.isURLRequired) { if (!this.url) return; data["url"] = this.url; data["insecure"] = this.insecure; } if (this.isFeatureTypeRequired) { if (!this.featureType) return; data["feature-type"] = this.featureType; } if (this.isSortbyRequired) { if (!this.sortBy) return; data["sort-by"] = this.sortBy; } if (this.isCredentialsRequired) { if (!this.username || !this.password) return; data["username"] = this.username; data["password"] = this.password; } if (this.import_ == this.$options.IMPORTTYPES.FAIRWAYDIMENSION) { if ( !this.LOS || !this.minWidth || !this.maxWidth || !this.depth || !this.sourceOrganization ) return; data["feature-type"] = this.featureType; data["sort-by"] = this.sortBy; data["los"] = this.LOS * 1; data["min-width"] = this.minWidth * 1; data["max-width"] = this.maxWidth * 1; data["depth"] = this.depth * 1; data["source-organization"] = this.sourceOrganization; } this.triggerActive = false; this.$store .dispatch("imports/triggerImport", { type: this.import_, data }) .then(response => { const { id } = response.data; displayInfo({ title: this.$gettext("Import"), message: this.$gettext("Manually triggered import: #") + id }); }) .catch(error => { const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }) .finally(() => { this.triggerActive = true; }); }, save() { const addAttribute = (data, attribute) => { if (!data["attributes"]) data.attributes = {}; data["attributes"] = { ...data["attributes"], ...attribute }; }; if (!this.import_) return; let cron = this.cronString; if (this.easyCron) { if (this.simple === "weekly") cron = "0 0 0 * * 0"; if (this.simple === "monthly") cron = "0 0 0 1 * *"; } let data = {}; if (this.isURLRequired) { if (!this.url) return; data["url"] = this.url; addAttribute(data, { insecure: this.insecure + "" }); } if (this.isSortbyRequired) { if (!this.sortBy) return; addAttribute(data, { "sort-by": this.sortBy }); } if (this.isFeatureTypeRequired) { if (!this.featureType) return; addAttribute(data, { "feature-type": this.featureType }); } if (this.isCredentialsRequired) { if (!this.username || !this.password) return; addAttribute(data, { username: this.username, password: this.password }); } if (this.import_ == this.$options.IMPORTTYPES.FAIRWAYDIMENSION) { if ( !this.LOS || !this.minWidth || !this.maxWidth || !this.depth || !this.sourceOrganization ) return; const values = { los: this.LOS, depth: this.depth }; values["min-width"] = this.minWidth; values["max-width"] = this.maxWidth; values["source-organization"] = this.sourceOrganization; addAttribute(data, values); } if (this.scheduled) data["cron"] = cron; data["kind"] = IMPORTTYPEKIND[this.import_]; data["send-email"] = this.eMailNotification; if (!this.id) { this.$store .dispatch("imports/saveCurrentSchedule", data) .then(response => { const { id } = response.data; displayInfo({ title: this.$gettext("Import"), message: this.$gettext("Saved import: #") + id }); this.closeDetailview(); this.$store.dispatch("imports/loadSchedules").catch(error => { const { status, data } = error.response; displayError({ title: this.gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); }) .catch(error => { const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); } else { this.$store .dispatch("imports/updateCurrentSchedule", { data: data, id: this.id }) .then(response => { const { id } = response.data; displayInfo({ title: this.$gettext("Import"), message: this.$gettext("update import: #") + id }); this.closeDetailview(); this.$store.dispatch("imports/loadSchedules").catch(error => { const { status, data } = error.response; displayError({ title: this.gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); }) .catch(error => { const { status, data } = error.response; displayError({ title: this.$gettext("Backend Error"), message: `${status}: ${data.message || data}` }); }); } }, closeDetailview() { this.$store.commit("imports/clearCurrentSchedule"); this.$store.commit("imports/setImportScheduleDetailInvisible"); } }, imports: [], on: "on", off: "off", periods: { DAILY: "daily", MONTHLY: "monthly" } }; </script> <style lang="scss" scoped> .cronfield { width: 55px; } .importscheduledetailscard { min-height: 550px; } .importscheduledetails { width: 100%; margin-top: $offset; margin-right: $offset; } .trigger { position: absolute; left: $large-offset; bottom: $offset; } .submit-button { position: absolute; right: $large-offset; bottom: $offset; } </style>