Mercurial > gemma
view client/src/components/importschedule/Importscheduledetail.vue @ 2503:51dbcbf11c5f critical-bottlenecks
client: addendum for e13daf439068
Of course, as you'd expect, this only solves the problem if you don't care about
significant changes in the tables sorting behavior. To point out the difference
this commit shows the other way to solve the problem without changing the tables
behavior.
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Mon, 04 Mar 2019 16:28:49 +0100 |
parents | f185503ef35a |
children | dc4fae4bdb8f |
line wrap: on
line source
<template> <div class="importscheduledetails fadeIn animated" v-if="importScheduleDetailVisible" > <div class="card shadow-xs importscheduledetailscard pb-5"> <UIBoxHeader :title="dialogLabel" :closeCallback="closeDetailview" /> <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>Waterway area</translate></option > <option :value="$options.IMPORTTYPES.FAIRWAYDIMENSION" ><translate>Fairway dimension</translate></option > <option :value="$options.IMPORTTYPES.WATERWAYGAUGES" ><translate>Waterway gauges</translate></option > <option :value="$options.IMPORTTYPES.DISTANCEMARKSVIRTUAL" ><translate>Distance marks virtual</translate></option > <option :value="$options.IMPORTTYPES.DISTANCEMARKSASHORE" ><translate>Distance marks ashore</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="directImportAvailable" class="flex-column"> <div class="flex-row text-left"> <small class="text-muted"> <translate>Import via</translate> </small> </div> <div class="flex-flex-row text-left"> <toggle-button v-model="directImport" class="mt-2" :speed="100" :labels="{ checked: this.$options.FILE, unchecked: this.$options.URL }" :width="60" :height="30" /> </div> </div> <Availablefairwaydepth v-if=" import_ == $options.IMPORTTYPES.FAIRWAYAVAILABILITY && !directImport " @urlChanged="setUrl" :url="url" ></Availablefairwaydepth> <Bottleneck v-if="import_ == $options.IMPORTTYPES.BOTTLENECK && !directImport" @urlChanged="setUrl" :url="url" ></Bottleneck> <Distancemarksvirtual v-if="import_ == $options.IMPORTTYPES.DISTANCEMARKSVIRTUAL" @urlChanged="setUrl" @usernameChanged="setUsername" @passwordChanged="setPassword" :url="url" :username="username" :password="password" ></Distancemarksvirtual> <Distancemarksashore v-if="import_ == $options.IMPORTTYPES.DISTANCEMARKSASHORE" @urlChanged="setUrl" @featureTypeChanged="setFeatureType" @sortByChanged="setSortBy" :url="url" :featureType="featureType" :sortBy="sortBy" ></Distancemarksashore> <Faiwaydimensions v-if="import_ == $options.IMPORTTYPES.FAIRWAYDIMENSION" @urlChanged="setUrl" @featureTypeChanged="setFeatureType" @sortByChanged="setSortBy" @LOSChanged="setLOS" @depthChanged="setDepth" @minWidthChanged="setMinWidth" @maxWidthChanged="setMaxWidth" @sourceOrganizationChanged="setSourceOrganization" :url="url" :featureType="featureType" :sortBy="sortBy" :LOS="LOS" :minWidth="minWidth" :maxWidth="maxWidth" :sourceOrganization="sourceOrganization" :depth="depth" ></Faiwaydimensions> <Gaugemeasurement v-if=" import_ == $options.IMPORTTYPES.GAUGEMEASUREMENT && !directImport " @urlChanged="setUrl" :url="url" ></Gaugemeasurement> <Waterwayarea v-if="import_ == $options.IMPORTTYPES.WATERWAYAREA" @urlChanged="setUrl" @featureTypeChanged="setFeatureType" @sortByChanged="setSortBy" :url="url" :featureType="featureType" :sortBy="sortBy" ></Waterwayarea> <Waterwaygauges v-if="import_ == $options.IMPORTTYPES.WATERWAYGAUGES" @urlChanged="setUrl" @usernameChanged="setUsername" @passwordChanged="setPassword" :url="url" :username="username" :password="password" ></Waterwaygauges> <Waterwayaxis v-if="import_ == $options.IMPORTTYPES.WATERWAYAXIS" @urlChanged="setUrl" @featureTypeChanged="setFeatureType" @sortByChanged="setSortBy" :url="url" :featureType="featureType" :sortBy="sortBy" ></Waterwayaxis> <div v-if="!directImport" 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 v-if="!directImport" 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 :value="null"></option> <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> <div v-if="directImport" class="d-flex flex-row text-left"> <div class="mt-3 mb-3 flex-column w-100"> <div class="custom-file"> <input accept=".xml" type="file" @change="fileSelected" class="custom-file-input" id="uploadFile" /> <label class="pointer custom-file-label" for="uploadFile"> {{ uploadLabel }} </label> </div> </div> </div> <button v-if="!directImport" :disabled="!isValid" type="submit" class="shadow-sm btn btn-info submit-button" > <translate>Save</translate> </button> <button @click="triggerManualImport" type="button" class="shadow-sm btn btn-outline-info trigger" :disabled="!triggerActive || !isValid" > <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/importschedule"; import { mapState } from "vuex"; import { displayInfo, displayError } from "@/lib/errors.js"; import app from "@/main.js"; import { HTTP } from "@/lib/http"; export default { name: "importscheduledetail", components: { Availablefairwaydepth: () => import("@/components/importschedule/importtypes/Availablefairwaydepth"), Bottleneck: () => import("@/components/importschedule/importtypes/Bottleneck"), Distancemarksvirtual: () => import("@/components/importschedule/importtypes/Distancemarksvirtual"), Distancemarksashore: () => import("@/components/importschedule/importtypes/Distancemarksashore"), Faiwaydimensions: () => import("@/components/importschedule/importtypes/Fairwaydimensions"), Gaugemeasurement: () => import("@/components/importschedule/importtypes/Gaugemeasurement"), Waterwayarea: () => import("@/components/importschedule/importtypes/Waterwayarea"), Waterwaygauges: () => import("@/components/importschedule/importtypes/Waterwaygauges"), Waterwayaxis: () => import("@/components/importschedule/importtypes/Waterwayaxis") }, data() { return { directImport: false, passwordVisible: false, uploadLabel: this.$gettext("choose file to upload"), uploadFile: null, ...initializeCurrentSchedule() }; }, 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("importschedule", [ "importScheduleDetailVisible", "currentSchedule" ]), dialogLabel() { if (this.id) return this.$gettext("Import") + " " + this.id; return this.$gettext("New Import"); }, directImportAvailable() { switch (this.import_) { case this.$options.IMPORTTYPES.BOTTLENECK: case this.$options.IMPORTTYPES.FAIRWAYAVAILABILITY: case this.$options.IMPORTTYPES.GAUGEMEASUREMENT: return true; default: return false; } }, 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: case this.$options.IMPORTTYPES.DISTANCEMARKSASHORE: return true; default: return false; } }, isFeatureTypeRequired() { switch (this.import_) { case this.$options.IMPORTTYPES.WATERWAYAXIS: case this.$options.IMPORTTYPES.WATERWAYAREA: case this.$options.IMPORTTYPES.FAIRWAYDIMENSION: case this.$options.IMPORTTYPES.DISTANCEMARKSASHORE: return true; default: return false; } }, isSortbyRequired() { switch (this.import_) { case this.$options.IMPORTTYPES.WATERWAYAXIS: case this.$options.IMPORTTYPES.WATERWAYAREA: case this.$options.IMPORTTYPES.FAIRWAYDIMENSION: case this.$options.IMPORTTYPES.DISTANCEMARKSASHORE: return true; default: return false; } }, isValid() { if (!this.import_) return false; if (this.directImport && !this.uploadFile) return false; else if (!this.directImport) { if (this.isURLRequired && !this.url) return false; if (this.isSortbyRequired && !this.sortBy) return false; if (this.isFeatureTypeRequired && !this.featureType) return false; if (this.isCredentialsRequired && (!this.username || !this.password)) return false; if (this.import_ == this.$options.IMPORTTYPES.FAIRWAYDIMENSION) { if ( !this.LOS || !this.minWidth || !this.maxWidth || !this.depth || !this.sourceOrganization ) return false; } } return true; } }, methods: { fileSelected(e) { const files = e.target.files || e.dataTransfer.files; if (!files) return; this.uploadLabel = files[0].name; this.uploadFile = files[0]; }, setUrl(value) { this.url = value; }, setFeatureType(value) { this.featureType = value; }, setSortBy(value) { this.sortBy = value; }, setUsername(value) { this.username = value; }, setPassword(value) { this.password = value; }, setLOS(value) { this.LOS = value; }, setMinWidth(value) { this.minWidth = value; }, setMaxWidth(value) { this.maxWidth = value; }, setDepth(value) { this.depth = value; }, setSourceOrganization(value) { this.sourceOrganization = value; }, calcCronString() { let getValue = value => { return this[value] !== null ? this[value] : "*"; }; const min = getValue("minutes"); const h = getValue("hour"); const dm = getValue("dayOfMonth"); const m = getValue("month"); const wd = getValue("day"); if (this.cronMode === "15minutes") return "0 */15 * * * *"; if (this.cronMode === "hour") return `0 ${min} * * * *`; if (this.cronMode === "day") return `0 ${min} ${h} * * *`; if (this.cronMode === "week") return `0 ${min} ${h} * * ${wd}`; if (this.cronMode === "month") return `0 ${min} ${h} ${dm} * *`; if (this.cronMode === "year") return `0 ${min} ${h} ${dm} ${m} *`; return this.cronString; }, 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; this.directImport = false; }, 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 = this.currentSchedule.minutes; this.month = this.currentSchedule.month; this.hour = this.currentSchedule.hour; this.day = this.currentSchedule.day; this.dayOfMonth = this.currentSchedule.dayOfMonth; }, triggerFileUpload() { if (!this.uploadFile) return; let formData = new FormData(); let routeParam = ""; switch (this.import_) { case this.$options.IMPORTTYPES.BOTTLENECK: routeParam = "ubn"; break; case this.$options.IMPORTTYPES.FAIRWAYAVAILABILITY: routeParam = "ufa"; break; case this.$options.IMPORTTYPES.GAUGEMEASUREMENT: routeParam = "ugm"; break; default: throw new Error("invalid importroute"); } formData.append(routeParam, this.uploadFile); HTTP.post("/imports/" + routeParam, formData, { headers: { "X-Gemma-Auth": localStorage.getItem("token"), "Content-Type": "multipart/form-data" } }) .then(response => { const { id } = response.data; displayInfo({ title: this.$gettext("File Import"), message: this.$gettext("Import import: #") + id }); this.closeDetailview(); this.$store.dispatch("importschedule/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}` }); }); }, triggerManualImport() { if (!this.triggerActive) return; if (!this.import_) return; if (this.directImport) { if (!this.uploadFile) return; this.triggerFileUpload(); 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["user"] = 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; } data["send-email"] = this.eMailNotification; this.triggerActive = false; this.$store .dispatch("importschedule/triggerImport", { type: IMPORTTYPEKIND[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() { 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 = {}; let config = {}; data["kind"] = IMPORTTYPEKIND[this.import_]; if (this.isURLRequired) { if (!this.url) return; config["url"] = this.url; config["insecure"] = this.insecure; } if (this.isSortbyRequired) { if (!this.sortBy) return; config["sort-by"] = this.sortBy; } if (this.isFeatureTypeRequired) { if (!this.featureType) return; config["feature-type"] = this.featureType; } if (this.isCredentialsRequired) { if (!this.username || !this.password) return; config = { ...config, user: this.username, password: this.password }; } if (this.import_ == this.$options.IMPORTTYPES.FAIRWAYDIMENSION) { if ( !this.LOS || !this.minWidth || !this.maxWidth || !this.depth || !this.sourceOrganization ) return; config = { ...config, los: this.LOS, depth: this.depth }; config["min-width"] = this.minWidth; config["max-width"] = this.maxWidth; config["source-organization"] = this.sourceOrganization; } if (this.scheduled) config["cron"] = cron; config["send-email"] = this.eMailNotification; if (!this.id) { data["config"] = config; this.$store .dispatch("importschedule/saveCurrentSchedule", data) .then(response => { const { id } = response.data; displayInfo({ title: this.$gettext("Import"), message: this.$gettext("Saved import: #") + id }); this.closeDetailview(); this.$store .dispatch("importschedule/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("importschedule/updateCurrentSchedule", { data: config, 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("importschedule/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("importschedule/clearCurrentSchedule"); this.$store.commit("importschedule/setImportScheduleDetailInvisible"); } }, IMPORTTYPES: IMPORTTYPES, on: "on", off: "off", FILE: app.$gettext("File"), URL: app.$gettext("URL"), 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") } }; </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>