summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUdo Walter2018-07-30 01:31:37 +0200
committerUdo Walter2018-07-30 01:31:37 +0200
commit8e70df54f1b3ca4be94d5d3633351aa7f4a38fa1 (patch)
tree6eb0d1cd91f5bc571b2fe8fd7841f92f47f1d99f
parent[server/router] changed api routing from query keyword to url parameter for g... (diff)
parent[webapp/backends] Reworked Dynamic fields to work with the new recursive stru... (diff)
downloadbas-8e70df54f1b3ca4be94d5d3633351aa7f4a38fa1.tar.gz
bas-8e70df54f1b3ca4be94d5d3633351aa7f4a38fa1.tar.xz
bas-8e70df54f1b3ca4be94d5d3633351aa7f4a38fa1.zip
merge
-rw-r--r--server/api/backends.js40
-rw-r--r--server/api/ipxe-loader.js18
-rw-r--r--server/lib/external-backends/backends/another-backend.js4
-rw-r--r--server/lib/external-backends/backends/dummy-backend.js4
-rw-r--r--server/lib/external-backends/backends/idoit-backend.js27
-rw-r--r--server/lib/external-backends/backends/template-backend.js14
-rw-r--r--server/lib/external-backends/external-backends.js8
-rw-r--r--server/router.js3
-rw-r--r--webapp/src/assets/styles.css4
-rw-r--r--webapp/src/components/BackendModuleEdit.vue254
-rw-r--r--webapp/src/components/BackendModuleEditDynamicFields.vue73
-rw-r--r--webapp/src/components/BackendModuleTable.vue6
-rw-r--r--webapp/src/components/SettingsModule.vue66
-rw-r--r--webapp/src/store/global.js4
14 files changed, 423 insertions, 102 deletions
diff --git a/server/api/backends.js b/server/api/backends.js
index b744bd2..a5d1233 100644
--- a/server/api/backends.js
+++ b/server/api/backends.js
@@ -47,19 +47,21 @@ module.exports = {
})
},
- checkConnection: function (req, res) {
- var x = Math.floor(Math.random() * Math.floor(2))
- var y = ''
- if (x === 0) {
- y = 'success'
- } else {
- y = 'error'
- }
- var w = 'Oh noes! An error occurred.'
- var z = Math.floor(Math.random() * Math.floor(5000))
-
-
- setTimeout(function() { res.status(200).send({ status: y, msg: w }) }, 0)
+ checkConnectionById: function (req, res) {
+ const backendId = req.query.id
+ db.backend.findOne({ where: { id: backendId } }).then(backend => {
+ const bCredentials = {
+ backendId: backendId,
+ backendName: backend.name,
+ backendType: backend.type,
+ backendCredentials: backend.credentials
+ }
+ const b = new ExternalBackends()
+ const instance = b.getInstance(bCredentials.backendType)
+ instance.checkConnection().then(connection => {
+ res.status(200).send({ success: connection.success, msg: connection.msg })
+ })
+ })
},
// POST REQUESTS
@@ -86,5 +88,17 @@ module.exports = {
db.backend.destroy({ where: { id: backendIds } }).then(function () {
res.status(200).send('success')
})
+ },
+
+ checkConnection: function (req, res) {
+ const type = req.body.backendType
+ // const credentials = req.body.backendCredentials
+
+ const b = new ExternalBackends()
+ const instance = b.getInstance(type)
+ instance.checkConnection().then(connection => {
+ res.status(200).send({ success: connection.success, msg: connection.msg })
+ })
+ // TODO: Set credentials
}
}
diff --git a/server/api/ipxe-loader.js b/server/api/ipxe-loader.js
index e75ce72..c484578 100644
--- a/server/api/ipxe-loader.js
+++ b/server/api/ipxe-loader.js
@@ -22,18 +22,18 @@ exit 1
:pxelnx
# set 210:string https://bas.stfu-kthx.net:8888/
# chain \${210:string}pxelinux.0 || goto start
-#chain https://bas.stfu-kthx.net:8888/pxelinux.0
+# chain https://bas.stfu-kthx.net:8888/pxelinux.0
# set next-server bas-stfu-kthx.net:8888
# set 209:string https://bas.stfu-kthx.net:8888/pxelinux.cfg
-#imgload pxelinux.0
-#boot pxelinux.0
+# imgload pxelinux.0
+set net0/next-server 192.52.3.91 ||
+set netX/next-server 192.52.3.91 ||
+set next-server 192.52.3.91 ||
-set 209:string pxelinux.cfg/default
-set 210:string bas.stfu-kthx.net
-# chain tftp://bas.stfu-kthx.net/pxelinux.0 || goto start
-kernel tftp://bas.stfu-kthx.net/ldlinux.c32
-imgload tftp://bas.stfu-kthx.net/pxelinux.0
-boot
+# set 209:string pxelinux.cfg/default
+# set 210:string bas.stfu-kthx.net
+shell ||
+boot tftp://bas.stfu-kthx.net/pxelinux.0 || goto start
:sh
shell
diff --git a/server/lib/external-backends/backends/another-backend.js b/server/lib/external-backends/backends/another-backend.js
index eb329ae..90b8f8b 100644
--- a/server/lib/external-backends/backends/another-backend.js
+++ b/server/lib/external-backends/backends/another-backend.js
@@ -4,6 +4,10 @@ class AnotherBackend extends ExternalBackends {
getCredentials () {
return [{ type: 'text', id: 1, name: 'text 1' }, { type: 'text', id: 2, name: 'text 2' }, { type: 'password', id: 3, name: 'password 1', show: false }, { type: 'password', id: 4, name: 'password 2', show: true }, { type: 'password', id: 5, name: 'password 3', show: false }]
}
+
+ async checkConnection () {
+ return { success: true }
+ }
}
module.exports = AnotherBackend
diff --git a/server/lib/external-backends/backends/dummy-backend.js b/server/lib/external-backends/backends/dummy-backend.js
index 6052953..99d27c1 100644
--- a/server/lib/external-backends/backends/dummy-backend.js
+++ b/server/lib/external-backends/backends/dummy-backend.js
@@ -4,6 +4,10 @@ class DummyBackend extends ExternalBackends {
getCredentials () {
return [{ type: 'switch', id: 1, name: 'switch 1', value: false }, { type: 'switch', id: 2, name: 'switch 2', value: false }, { type: 'switch', id: 3, name: 'switch 3', value: true }, { type: 'select', id: 4, name: 'selection 1', items: ['wasd', 'asdf', 'qwertz'] }, { type: 'select', id: 5, name: 'selection 2', items: ['1', '2', '3'] }]
}
+
+ async checkConnection () {
+ return { success: false, msg: 'This is a test where success was intentionally set to false!' }
+ }
}
module.exports = DummyBackend
diff --git a/server/lib/external-backends/backends/idoit-backend.js b/server/lib/external-backends/backends/idoit-backend.js
new file mode 100644
index 0000000..2520b07
--- /dev/null
+++ b/server/lib/external-backends/backends/idoit-backend.js
@@ -0,0 +1,27 @@
+var ExternalBackends = require('../external-backends.js')
+
+class IdoitBackend extends ExternalBackends {
+ getCredentials () {
+ // I do it only needs the API-key.
+ return [
+ { type: 'text', id: 1, name: 'API url', icon: 'link' },
+ { type: 'password', id: 2, name: 'API token', icon: 'vpn_key', show: false },
+ { type: 'switch',
+ id: 3,
+ name: 'Login',
+ icon: 'lock_open',
+ elements: [
+ { type: 'text', id: 4, name: 'username', icon: 'person_outline' },
+ { type: 'password', id: 5, name: 'password', icon: 'lock', show: false }
+ ]
+ }
+ ]
+ }
+
+ async checkConnection () {
+ // Make a simple login and check if the connection works.
+ return { success: false, msg: 'TODO: IMPLEMENT' }
+ }
+}
+
+module.exports = IdoitBackend
diff --git a/server/lib/external-backends/backends/template-backend.js b/server/lib/external-backends/backends/template-backend.js
index 19f1d76..ceab46a 100644
--- a/server/lib/external-backends/backends/template-backend.js
+++ b/server/lib/external-backends/backends/template-backend.js
@@ -4,6 +4,20 @@ class TemplateBackend extends ExternalBackends {
getCredentials () {
return [{ type: 'text', id: 1, name: 'text test', icon: 'bug_report' }, { type: 'password', id: 2, name: 'password test', show: true }, { type: 'password', id: 3, name: 'password test nr2', show: false }, { type: 'switch', id: 4, name: 'bool test', value: false }, { type: 'select', id: 5, name: 'selection test', items: ['wasd', 'asdf', 'qwertz'] }]
}
+
+ async checkConnection () {
+ var result = await x()
+ console.log(result)
+ return result
+ }
+}
+
+function x () {
+ return new Promise(resolve => {
+ setTimeout(() => {
+ resolve({ success: true })
+ }, 5000)
+ })
}
module.exports = TemplateBackend
diff --git a/server/lib/external-backends/external-backends.js b/server/lib/external-backends/external-backends.js
index 0bf891e..a1264a0 100644
--- a/server/lib/external-backends/external-backends.js
+++ b/server/lib/external-backends/external-backends.js
@@ -9,7 +9,8 @@ class ExternalBackends {
}
getCredentials () {
- return 'If this method gets called the backend class has NOT IMPLEMENTED the getCredentials method!'
+ console.log('If this method gets called the backend class has NOT IMPLEMENTED the getCredentials method!')
+ return null
}
getInstance (type) {
@@ -25,6 +26,11 @@ class ExternalBackends {
const backend = new (require(path.join(__appdir, 'lib', 'external-backends', 'backends', bType)))()
return backend
}
+
+ async checkConnection () {
+ console.log('If this method gets called the backend class has NOT IMPLEMENTED the checkConnection method!')
+ return null
+ }
}
module.exports = ExternalBackends
diff --git a/server/router.js b/server/router.js
index 6c0e4cd..9e29f93 100644
--- a/server/router.js
+++ b/server/router.js
@@ -53,9 +53,10 @@ router.get('/backends/getCredentialsByType', auth.verifyToken, backends.getCrede
router.get('/backends/getBackendInfoById', auth.verifyToken, backends.getBackendInfoById)
router.get('/backends/getBackendList', auth.verifyToken, backends.getBackendList)
router.get('/backends/getBackendTypes', backends.getBackendTypes)
-router.get('/backends/checkConnection', auth.verifyToken, backends.checkConnection)
+router.get('/backends/checkConnection', auth.verifyToken, backends.checkConnectionById)
router.post('/backends/saveBackend', auth.verifyToken, backends.saveBackend)
router.post('/backends/deleteBackends', auth.verifyToken, backends.deleteBackends)
+router.post('/backends/checkConnection', auth.verifyToken, backends.checkConnection)
// Load ipxe scipts API
var ipxeloader = require(path.join(__dirname, 'api', 'ipxe-loader'))
diff --git a/webapp/src/assets/styles.css b/webapp/src/assets/styles.css
index 9bb1355..c18db49 100644
--- a/webapp/src/assets/styles.css
+++ b/webapp/src/assets/styles.css
@@ -35,4 +35,8 @@ html {
padding: 0 5px;
margin: 0 -5px;
flex: 1
+}
+
+.element-container {
+ padding: 26px;
} \ No newline at end of file
diff --git a/webapp/src/components/BackendModuleEdit.vue b/webapp/src/components/BackendModuleEdit.vue
index 90045f4..87d97a2 100644
--- a/webapp/src/components/BackendModuleEdit.vue
+++ b/webapp/src/components/BackendModuleEdit.vue
@@ -1,26 +1,31 @@
<i18n>
{
"en": {
- "select_backend_type": "Select a backend type.",
- "input_credentials": "Fill in the backend details.",
+ "input_credentials": "Login credentials",
"backend_name": "Backend name",
"backend_empty_error": "This field can not be empty.",
"backend_type": "Backend type",
"backendtype_empty_error": "Please choose a backend type.",
- "stepper_optional": "optional"
+ "stepper_optional": "optional",
+ "pending": "pending",
+ "progress": "in progress ...",
+ "success": "success",
+ "error": "error"
},
"de": {
- "select_backend_type": "Wähle einen Backend typ aus.",
- "input_credentials": "Gib die benötigten Backend Daten ein.",
+ "input_credentials": "Anmeldedaten",
"backend_name": "Backend Name",
"backend_empty_error": "Dieses Feld darf nicht leer sein.",
"backend_type": "Backend Typ",
"backendtype_empty_error": "Bitte wähle einen Backendtyp aus.",
- "stepper_optional": "Optional"
+ "stepper_optional": "Optional",
+ "pending": "Nicht getestet",
+ "progress": "Test läuft ...",
+ "success": "Erfolgreich",
+ "error": "Fehler"
}
}
</i18n>
-
<template>
<v-form class="edit-backend-form" ref="form" v-model="valid" @submit.prevent="submit" lazy-validation>
<v-stepper v-model="step" horizontal>
@@ -28,23 +33,20 @@
<v-stepper-step
:complete="stepCompleted >= 1"
step="1"
- :editable="stepCompleted >= 1"
- edit-icon="check"
+ :editable="stepCompleted >= 1 && !loadData"
:rules="[() => true]"
- >{{ $t('select_backend_type') }}</v-stepper-step>
+ >{{ $t('backend_type') }}</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step
:complete="stepCompleted >= 2"
step="2"
:editable="stepCompleted >= 2"
- edit-icon="check"
>{{ $t('input_credentials') }}</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step
:complete="stepCompleted >= 3"
step="3"
:editable="stepCompleted >= 3"
- edit-icon="check"
>{{ $t('test_connection') }}
<small>{{ $t('stepper_optional') }}</small>
</v-stepper-step>
@@ -58,6 +60,7 @@
:label="$t('backend_type')"
:rules="[() => !!backendType || $t('backendtype_empty_error')]"
@change="loadInputFields"
+ prepend-icon="view_list"
></v-select>
</v-stepper-content>
<v-stepper-content step="2" class="stepper-content">
@@ -66,43 +69,27 @@
:label="$t('backend_name')"
:rules="[() => !!backendName || $t('backend_empty_error')]"
ref="backendName"
+ prepend-icon="assignment_ind"
></v-text-field>
- <template v-for="element in elements">
- <v-text-field
- v-if="element.type == 'text'"
- label="TODO:"
- :key="element.name"
- v-model="element.value"
- :prepend-icon="element.icon"
- ></v-text-field>
- <v-text-field
- v-if="element.type == 'password'"
- label="TODOOO yoo"
- :key="element.name"
- :append-icon="element.show ? 'visibility_off' : 'visibility'"
- :type="element.show ? 'text' : 'password'"
- @click:append="element.show = !element.show"
- v-model="element.value"
- ></v-text-field>
- <v-switch
- v-if="element.type == 'switch'"
- v-model="element.value"
- :label="element.name"
- :key="element.name"
- color="primary"
- ></v-switch>
- <v-select
- offset-y
- v-if="element.type == 'select'"
- :items="element.items"
- label="Standard"
- :key="element.name"
- v-model="element.value"
- ></v-select>
- </template>
+ <backend-module-edit-dynamic-fields :elements="elements"/>
</v-stepper-content>
<v-stepper-content step="3" class="stepper-content">
- <v-btn color="primary">{{ $t('work_in_progress') }}</v-btn>
+ <v-container>
+ <v-layout align-center justify-center column>
+ <v-btn
+ fab
+ dark
+ icon
+ :loading="loading"
+ :disabled="loading"
+ @click.stop="checkConnection"
+ large
+ >
+ <v-icon x-large color="primary">cached</v-icon>
+ </v-btn>
+ <div class="display-1">{{ $t('status') }}: <strong :class="statusColor">{{ statusLabel }}</strong></div>
+ </v-layout>
+ </v-container>
</v-stepper-content>
</v-stepper-items>
@@ -118,38 +105,123 @@
</v-stepper>
</v-form>
</template>
+<!--
+<template>
+<v-form class="edit-backend-form" ref="form" v-model="valid" @submit.prevent="submit" lazy-validation>
+ <v-card>
+ <v-stepper v-model="step" horizontal>
+ <v-stepper-header>
+ <v-stepper-step
+ :complete="stepCompleted >= 1"
+ step="1"
+ :editable="stepCompleted >= 1 && !loadData"
+ :rules="[() => true]"
+ >{{ $t('backend_type') }}</v-stepper-step>
+ <v-divider></v-divider>
+ <v-stepper-step
+ :complete="stepCompleted >= 2"
+ step="2"
+ :editable="stepCompleted >= 2"
+ >{{ $t('input_credentials') }}</v-stepper-step>
+ <v-divider></v-divider>
+ <v-stepper-step
+ :complete="stepCompleted >= 3"
+ step="3"
+ :editable="stepCompleted >= 3"
+ >{{ $t('test_connection') }}
+ <small>{{ $t('stepper_optional') }}</small>
+ </v-stepper-step>
+ </v-stepper-header>
+ <v-card-text style="height: 500px;">
+<v-stepper-items>
+ <v-stepper-content step="1" class="stepper-content">
+ <v-select
+ offset-y
+ v-model="backendType"
+ :items="backendChoices"
+ :label="$t('backend_type')"
+ :rules="[() => !!backendType || $t('backendtype_empty_error')]"
+ @change="loadInputFields"
+ prepend-icon="view_list"
+ ></v-select>
+ </v-stepper-content>
+ <v-stepper-content step="2" class="stepper-content">
+ <v-text-field
+ v-model="backendName"
+ :label="$t('backend_name')"
+ :rules="[() => !!backendName || $t('backend_empty_error')]"
+ ref="backendName"
+ prepend-icon="assignment_ind"
+ ></v-text-field>
+ <backend-module-edit-dynamic-fields :elements="elements"/>
+ </v-stepper-content>
+ <v-stepper-content step="3" class="stepper-content">
+ <v-container>
+ <v-layout align-center justify-center column>
+ <v-btn
+ fab
+ dark
+ icon
+ :loading="loading"
+ :disabled="loading"
+ @click.stop="checkConnection"
+ large
+ >
+ <v-icon x-large color="primary">cached</v-icon>
+ </v-btn>
+ <div class="display-1">{{ $t('status') }}: <strong :class="statusColor">{{ statusLabel }}</strong></div>
+ </v-layout>
+ </v-container>
+ </v-stepper-content>
+ </v-stepper-items>
+ </v-card-text>
+ <v-divider></v-divider>
+ <v-card-actions>
+ <v-flex xl10 offset-xl1 lg12 text-xs-right>
+ <v-btn flat @click.native="$store.commit('backends/setDialog', { show: false })">{{ $t('cancel') }}</v-btn>
+ <v-btn color="primary" v-show="step == 1" @click.native="completeStepOne()">{{ $t('continue') }}</v-btn>
+ <v-btn color="primary" v-show="step == 2" @click.native="completeStepTwo()">{{ $t('continue') }}</v-btn>
+ <v-btn type="submit" v-show="step == 3" class="primary" raised>{{ $t('submit') }}</v-btn>
+ </v-flex>
+ </v-card-actions>
+ </v-stepper>
+ </v-card>
+</v-form>
+</template>
+-->
<script>
+import BackendModuleEditDynamicFields from '@/components/BackendModuleEditDynamicFields'
export default {
name: 'BackendModuleEdit',
props: ['backendId'],
+ components: {
+ BackendModuleEditDynamicFields
+ },
data () {
return {
valid: true,
step: 1,
stepCompleted: 0,
backendChoices: [],
- elements: [],
backendType: '',
backendName: '',
- loadData: false
+ elements: [],
+ loadData: false,
+ loading: false,
+ statusColor: 'primary--text',
+ statusLabel: this.$t('pending')
}
},
methods: {
submit (event) {
if (this.$refs.form.validate()) {
- var credentials = []
- this.elements.forEach(function (element) {
- const e = { id: element.id, value: element.value }
- credentials.push(e)
- })
-
this.$http.post('/api/backends/saveBackend', {
backendId: this.backendId,
backendName: this.backendName,
backendType: this.backendType,
- backendCredentials: credentials
+ backendCredentials: this.credentials
}).then(response => {
// TODO: Add backend saved successfull msg.
console.log('TODO: Implement snackbar and print backend added successfully msg.')
@@ -185,7 +257,8 @@ export default {
var credentials = res.data
// Make an array merge to combine the credentials with the values.
- var mergedCredentials = credentials.map(x => Object.assign(x, credentialValues.find(y => y.id === x.id)))
+ // var mergedCredentials = credentials.map(x => Object.assign(x, credentialValues.find(y => y.id === x.id)))
+ var mergedCredentials = mergeObjects(credentials, credentialValues)
this.elements = mergedCredentials
})
})
@@ -207,9 +280,39 @@ export default {
} else {
this.$refs.form.validate()
}
+ },
+ checkConnection () {
+ // Start the loading animation and reset the label colors.
+ this.loading = true
+ this.statusColor = 'primary--text'
+ this.statusLabel = this.$t('progress')
+
+ // Test the credential connection.
+ this.$http.post('/api/backends/checkConnection', {
+ backendName: this.backendName,
+ backendType: this.backendType,
+ backendCredentials: this.credentials,
+ headers: {
+ 'Cache-Control': 'no-cache'
+ }
+ }).then(response => {
+ if (response.data.success) {
+ this.statusColor = 'success--text'
+ this.statusLabel = this.$t('success')
+ } else {
+ this.statusColor = 'error--text'
+ this.statusLabel = this.$t('error')
+ this.$store.commit('newSnackbar', response.data.msg)
+ }
+ // Set item.loading = false to end the loading animation.
+ this.loading = false
+ })
}
},
computed: {
+ credentials: function () {
+ return filterData(this.elements)
+ }
},
beforeMount () {
this.loadBackendTypes()
@@ -222,12 +325,47 @@ export default {
watch: {
}
}
+
+function filterData (obj) {
+ var result = []
+ obj.forEach(function (element) {
+ const e = { id: element.id, value: element.value }
+ if (element.elements) {
+ e.elements = filterData(element.elements)
+ }
+ result.push(e)
+ })
+ return result
+}
+
+function mergeObjects (obj1, obj2) {
+ var tmp = []
+ var merged = obj1.map(x => Object.assign(x, obj2.find(y => {
+ if (y.id === x.id) {
+ if (x.elements && y.elements) {
+ var tmp2 = { id: x.id, elements: mergeObjects(x.elements, y.elements) }
+ tmp.push(tmp2)
+ }
+ }
+ return y.id === x.id
+ })))
+
+ // Is there a cleaner way?
+ tmp.forEach(function (e) {
+ merged.forEach(function (r) {
+ if (e.id === r.id) {
+ r.elements = e.elements
+ }
+ })
+ })
+ return merged
+}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.stepper-content {
- height: 600px;
- overflow: auto;
+ /*height: 600px;*/
+ /*overflow: auto;*/
}
</style>
diff --git a/webapp/src/components/BackendModuleEditDynamicFields.vue b/webapp/src/components/BackendModuleEditDynamicFields.vue
new file mode 100644
index 0000000..eae6357
--- /dev/null
+++ b/webapp/src/components/BackendModuleEditDynamicFields.vue
@@ -0,0 +1,73 @@
+<i18n>
+{
+ "en": {
+ },
+ "de": {
+ }
+}
+</i18n>
+<template>
+ <div>
+ <template v-for="element in elements">
+ <v-text-field
+ v-if="element.type == 'text'"
+ :label="element.name"
+ :key="element.name"
+ v-model="element.value"
+ :prepend-icon="element.icon"
+ ></v-text-field>
+ <v-text-field
+ v-else-if="element.type == 'password'"
+ :label="element.name"
+ :key="element.name"
+ :append-icon="element.show ? 'visibility_off' : 'visibility'"
+ :type="element.show ? 'text' : 'password'"
+ @click:append="element.show = !element.show"
+ v-model="element.value"
+ :prepend-icon="element.icon"
+ ></v-text-field>
+ <div v-else-if="element.type == 'switch'" :key="element.name">
+ <v-switch
+ v-model="element.value"
+ :label="element.name"
+ :key="element.name"
+ color="primary"
+ :prepend-icon="element.icon"
+ ></v-switch>
+ <backend-module-edit-dynamic-fields :elements="element.elements" v-if="element.value"/>
+ </div>
+ <v-select
+ offset-y
+ v-else-if="element.type == 'select'"
+ :items="element.items"
+ :label="element.name"
+ :key="element.name"
+ v-model="element.value"
+ ></v-select>
+ </template>
+ </div>
+</template>
+
+<script>
+import BackendModuleEditDynamicFields from '@/components/BackendModuleEditDynamicFields'
+
+export default {
+ props: ['elements'],
+ data () {
+ return {
+ }
+ },
+ methods: {
+ },
+ computed: {
+ },
+ created () {
+ this.$options.components['BackendModuleEditDynamicFields'] = BackendModuleEditDynamicFields
+ }
+}
+
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+</style>
diff --git a/webapp/src/components/BackendModuleTable.vue b/webapp/src/components/BackendModuleTable.vue
index 2ca15b3..a0e59e4 100644
--- a/webapp/src/components/BackendModuleTable.vue
+++ b/webapp/src/components/BackendModuleTable.vue
@@ -104,15 +104,15 @@ export default {
// Set to start the loading animation.
item.loading = true
// Test the credential connection.
- this.$http('/api/backends/checkConnection?id=' + this.backendId, {
+ this.$http('/api/backends/checkConnection?id=' + item.id, {
headers: {
'Cache-Control': 'no-cache'
}
}).then(response => {
- if (response.data.status === 'success') {
+ if (response.data.success) {
// Set the button color to green if success.
item.connection = 'success'
- } else if (response.data.status === 'error') {
+ } else {
// Set the button color to red if error.
item.connection = 'error'
this.$store.commit('newSnackbar', response.data.msg)
diff --git a/webapp/src/components/SettingsModule.vue b/webapp/src/components/SettingsModule.vue
index 2d3b781..ed23cc9 100644
--- a/webapp/src/components/SettingsModule.vue
+++ b/webapp/src/components/SettingsModule.vue
@@ -4,40 +4,81 @@
"darkTheme": "Dark Theme",
"coloredTabs": "Colored tabpanels",
"clipped": "Show menu under the top bar",
- "mini": "Show icons in collapsed menu"
+ "mini": "Show icons in collapsed menu",
+ "language": "Language",
+ "general": "General",
+ "generalSettings": "General settings",
+ "appearance": "Appearance"
},
"de": {
"darkTheme": "Dunkles Design",
"coloredTabs": "Tab-Panels einfärben",
"clipped": "Menü an die Hauptleiste andocken",
- "mini": "Symbole im eingeklappten Menü anzeigen"
+ "mini": "Symbole im eingeklappten Menü anzeigen",
+ "language": "Sprache",
+ "general": "Allgemein",
+ "generalSettings": "Allgemeine Einstellungen",
+ "appearance": "Aussehen"
}
}
</i18n>
<template>
- <v-container>
+ <v-container fill-height>
<v-layout>
- <v-flex md4 offset-md4 sm10 offset-sm1>
- <v-select :value="store.locale" @input="save('locale', $event)" class="lang-select" :items="langChoices" solo offset-y></v-select>
- <v-switch :input-value="store.dark" @change="save('dark', $event)" :label="$t('darkTheme')" color="primary"></v-switch>
- <v-switch :input-value="store.coloredTabs" @change="save('coloredTabs', $event)" :label="$t('coloredTabs')" color="primary"></v-switch>
- <v-switch :input-value="store.clipped" @change="save('clipped', $event)" :label="$t('clipped')" color="primary" class="hidden-md-and-down"></v-switch>
- <v-switch :input-value="store.mini" @change="save('mini', $event)" :label="$t('mini')" color="primary" class="hidden-md-and-down"></v-switch>
+ <v-flex class="tabs-wrapper" xl10 offset-xl1 lg12>
+ <v-card>
+ <v-tabs :dark="tabsDark" :color="tabsColor" :slider-color="tabsSliderColor"
+ v-model="tab"
+ centered
+ >
+ <v-tab>
+ <v-icon>settings_applications</v-icon>{{ $t('general') }}
+ </v-tab>
+ <v-tab>
+ <v-icon>color_lens</v-icon>{{ $t('appearance') }}
+ </v-tab>
+ </v-tabs>
+ </v-card>
+ <v-tabs-items v-model="tab">
+ <v-tab-item>
+ <v-subheader>{{ $t('generalSettings') }}</v-subheader>
+ <v-card>
+ <div class="element-container">
+ <v-select :value="store.locale" @input="save('locale', $event)" :items="langChoices" :label="$t('language')" prepend-icon="language"></v-select>
+ </div>
+ </v-card>
+ </v-tab-item>
+ <v-tab-item>
+ <v-subheader>{{ $t('generalSettings') }}</v-subheader>
+ <v-card>
+ <div class="element-container">
+ <v-switch :input-value="store.dark" @change="save('dark', $event)" :label="$t('darkTheme')" color="primary" prepend-icon="style"></v-switch>
+ <v-switch :input-value="store.coloredTabs" @change="save('coloredTabs', $event)" :label="$t('coloredTabs')" color="primary" prepend-icon="tab"></v-switch>
+ <v-switch :input-value="store.clipped" @change="save('clipped', $event)" :label="$t('clipped')" color="primary" class="hidden-md-and-down" prepend-icon="view_quilt"></v-switch>
+ <v-switch :input-value="store.mini" @change="save('mini', $event)" :label="$t('mini')" color="primary" class="hidden-md-and-down" prepend-icon="view_list"></v-switch>
+ </div>
+ </v-card>
+ </v-tab-item>
+ </v-tabs-items>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
+import { mapGetters } from 'vuex'
+
export default {
name: 'SettingsPage',
data () {
return {
- langChoices: [ { text: 'Deutsch', value: 'de' }, { text: 'English', value: 'en' } ]
+ langChoices: [ { text: 'Deutsch', value: 'de' }, { text: 'English', value: 'en' } ],
+ tab: ''
}
},
computed: {
+ ...mapGetters(['tabsDark', 'tabsColor', 'tabsSliderColor']),
store () { return this.$store.state.settings }
},
methods: {
@@ -49,9 +90,4 @@ export default {
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
-.lang-select {
- margin-top: 40px;
- margin-bottom: 40px;
-}
-
</style>
diff --git a/webapp/src/store/global.js b/webapp/src/store/global.js
index a636cd6..d461ad9 100644
--- a/webapp/src/store/global.js
+++ b/webapp/src/store/global.js
@@ -1,4 +1,4 @@
-function loadSetting(name, defaultValue) {
+function loadSetting (name, defaultValue) {
const value = localStorage.getItem('settings.' + name)
switch (typeof defaultValue) {
case 'boolean':
@@ -17,7 +17,7 @@ export default {
dark: loadSetting('dark', true),
coloredTabs: loadSetting('coloredTabs', false),
clipped: loadSetting('clipped', true),
- mini: loadSetting('mini', true),
+ mini: loadSetting('mini', true)
},
snackbars: []
},