summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/api/clients.js20
-rw-r--r--server/api/groups.js10
-rw-r--r--webapp/src/components/GroupModule.vue2
-rw-r--r--webapp/src/components/GroupModuleClientView.vue121
-rw-r--r--webapp/src/components/GroupModuleGroupView.vue144
-rw-r--r--webapp/src/store/groups.js21
6 files changed, 231 insertions, 87 deletions
diff --git a/server/api/clients.js b/server/api/clients.js
index 8daab55..5bb2a1b 100644
--- a/server/api/clients.js
+++ b/server/api/clients.js
@@ -5,7 +5,7 @@ var db = require(path.join(__appdir, 'lib', 'sequelize'))
// GET Requests
module.exports.get = {
getList: function (req, res) {
- db.client.findAll({ attributes: ['id', 'name'] }).then(list => {
+ db.client.findAll({ attributes: ['id', 'name'], order: [['name', 'ASC']] }).then(list => {
res.send(list)
})
},
@@ -24,3 +24,21 @@ module.exports.get = {
})
}
}
+
+// POST Requests
+module.exports.post = {
+ // create client or update information of a client (returns id)
+ saveInfo: function (req, res) {
+ const id = req.body.id > 0 ? req.body.id : null
+ if (id) {
+ db.client.findOne({ where: { id: id } }).then(client => {
+ var promises = []
+ if (req.body.info) promises.push([client.update(req.body.info)])
+ if (req.body.groupIds) promises.push(client.setGroups(req.body.groupIds))
+ Promise.all(promises).then(() => { res.send({id}) })
+ })
+ } else {
+ res.end()
+ }
+ }
+}
diff --git a/server/api/groups.js b/server/api/groups.js
index 5916585..6debc4d 100644
--- a/server/api/groups.js
+++ b/server/api/groups.js
@@ -6,7 +6,7 @@ var db = require(path.join(__appdir, 'lib', 'sequelize'))
module.exports.get = {
// get a list containing id and name of all groups
getList: function (req, res) {
- db.group.findAll({ attributes: ['id', 'name'] }).then(list => {
+ db.group.findAll({ attributes: ['id', 'name'], order: [['name', 'ASC']] }).then(list => {
res.send(list)
})
},
@@ -33,10 +33,10 @@ module.exports.post = {
const id = req.body.id > 0 ? req.body.id : null
if (id) {
db.group.findOne({ where: { id: id } }).then(group => {
- Promise.all([
- group.update({ name: req.body.name, description: req.body.description }),
- group.setParents(req.body.parentIds)
- ]).then(() => { res.send({id}) })
+ var promises = []
+ if (req.body.info) promises.push([group.update(req.body.info)])
+ if (req.body.parentIds) promises.push(group.setParents(req.body.parentIds))
+ Promise.all(promises).then(() => { res.send({id}) })
})
} else {
res.end()
diff --git a/webapp/src/components/GroupModule.vue b/webapp/src/components/GroupModule.vue
index a1a445c..e2541e2 100644
--- a/webapp/src/components/GroupModule.vue
+++ b/webapp/src/components/GroupModule.vue
@@ -27,7 +27,7 @@
<v-tab-item v-for="(item, index) in tabChain" :key="index">
<group-module-home-view v-if="item.tabType === 'home'" :home="item" />
<group-module-group-view v-if="item.tabType === 'group'" :group="item" :tabIndex="index" />
- <group-module-client-view v-if="item.tabType === 'client'" :client="item" />
+ <group-module-client-view v-if="item.tabType === 'client'" :client="item" :tabIndex="index" />
</v-tab-item>
</v-tabs-items>
</v-flex>
diff --git a/webapp/src/components/GroupModuleClientView.vue b/webapp/src/components/GroupModuleClientView.vue
index 7518d67..9534274 100644
--- a/webapp/src/components/GroupModuleClientView.vue
+++ b/webapp/src/components/GroupModuleClientView.vue
@@ -11,7 +11,92 @@
<div>
<v-subheader>Info</v-subheader>
<v-card>
-
+ <v-card-text>
+ <v-layout wrap>
+ <v-flex sm6 xs12 order-xs2 order-sm1>
+ <v-text-field v-if="editMode" hide-details class="info-input" label="Name" color="primary" v-model="info.name"></v-text-field>
+ <div v-else class="info-input">
+ <div class="body-2">Name</div>
+ {{ client.name || '-' }}
+ </div>
+ </v-flex>
+ <v-flex sm6 xs12 order-xs1 order-sm2 class="text-xs-right">
+ <div class="info-input">
+ <v-btn v-if="!editMode" color="primary" flat @click="editInfo">
+ <v-icon left>create</v-icon>Edit
+ </v-btn>
+ <div v-else>
+ <v-btn color="primary" flat @click="editMode = false">Cancel</v-btn>
+ <v-btn color="primary" @click="saveInfo">
+ <v-icon left>save</v-icon>Save
+ </v-btn>
+ </div>
+ </div>
+ </v-flex>
+ </v-layout>
+ <v-layout wrap>
+ <v-flex sm6 xs12>
+ <v-textarea v-if="editMode" rows="1" auto-grow hide-details class="info-input" label="Description" color="primary" v-model="info.description"></v-textarea>
+ <div v-else class="info-input">
+ <div class="body-2">Description</div>
+ <pre>{{ client.description || '-' }}</pre>
+ </div>
+ </v-flex>
+ <v-flex sm6 xs12>
+ <v-autocomplete
+ v-if="editMode"
+ class="info-input"
+ :items="$store.state.groups.groupList"
+ v-model="groupIds"
+ hide-details
+ offset-y
+ label="Parents"
+ color="primary"
+ multiple
+ >
+ <template slot="selection" slot-scope="data">
+ <v-chip small :selected="data.selected" @input="removeGroup(data.item.value)" close>
+ {{ data.item.text }}
+ </v-chip>
+ </template>
+ </v-autocomplete>
+ <div v-else class="info-input">
+ <div class="body-2">Groups</div>
+ <template v-if="client.groups.length > 0">
+ <v-chip v-for="group in client.groups" :key="group.id" small>
+ {{ group.name || group.id }}
+ </v-chip>
+ </template>
+ <span v-else>-</span>
+ </div>
+ </v-flex>
+ </v-layout>
+ <v-layout wrap>
+ <v-flex sm6 xs12>
+ <v-text-field v-if="editMode" hide-details class="info-input" label="IP Address" color="primary" v-model="info.ip"></v-text-field>
+ <div v-else class="info-input">
+ <div class="body-2">IP Address</div>
+ {{ client.ip || '-' }}
+ </div>
+ </v-flex>
+ <v-flex sm6 xs12>
+ <v-text-field v-if="editMode" hide-details class="info-input" label="MAC Address" color="primary" v-model="info.mac"></v-text-field>
+ <div v-else class="info-input">
+ <div class="body-2">MAC Address</div>
+ {{ client.mac || '-' }}
+ </div>
+ </v-flex>
+ </v-layout>
+ <v-layout wrap>
+ <v-flex sm6 xs12>
+ <v-text-field v-if="editMode" hide-details class="info-input" label="UUID" color="primary" v-model="info.uuid"></v-text-field>
+ <div v-else class="info-input">
+ <div class="body-2">UUID</div>
+ {{ client.uuid || '-' }}
+ </div>
+ </v-flex>
+ </v-layout>
+ </v-card-text>
</v-card>
</div>
</template>
@@ -19,9 +104,38 @@
<script>
export default {
name: 'GroupModuleClientView',
- props: ['tabIndex'],
+ props: ['tabIndex', 'client'],
data () {
return {
+ editMode: false,
+ info: {
+ name: '',
+ description: '',
+ ip: '',
+ mac: '',
+ uuid: '',
+ groupIds: []
+ }
+ }
+ },
+ methods: {
+ removeGroup (id) {
+ this.groupIds.splice(this.groupIds.indexOf(id), 1)
+ },
+ editInfo () {
+ this.editMode = true
+ this.info.name = this.client.name
+ this.info.description = this.client.description
+ this.groupIds = this.client.groups.map(x => x.id)
+ },
+ saveInfo () {
+ this.$store.dispatch('groups/saveClient', {
+ id: this.client.id,
+ info: this.info,
+ groupIds: this.groupIds,
+ tabIndex: this.tabIndex
+ })
+ this.editMode = false
}
}
}
@@ -29,4 +143,7 @@ export default {
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
+.info-input {
+ margin: 10px;
+}
</style>
diff --git a/webapp/src/components/GroupModuleGroupView.vue b/webapp/src/components/GroupModuleGroupView.vue
index 740266e..1706ba4 100644
--- a/webapp/src/components/GroupModuleGroupView.vue
+++ b/webapp/src/components/GroupModuleGroupView.vue
@@ -9,72 +9,70 @@
<template>
<div>
- <template v-if="tabIndex > 0">
- <v-subheader>Info</v-subheader>
- <v-card>
- <v-card-text>
- <v-layout wrap>
- <v-flex sm6 xs12 order-xs2 order-sm1>
- <v-text-field v-if="editMode" hide-details class="info-input" label="Name" color="primary" v-model="info.name"></v-text-field>
- <div v-else class="info-input">
- <div class="body-2">Name</div>
- {{ group.name || '-' }}
- </div>
- </v-flex>
- <v-flex sm6 xs12 order-xs1 order-sm2 class="text-xs-right">
- <div class="info-input">
- <v-btn v-if="!editMode" color="primary" flat @click="editInfo">
- <v-icon left>create</v-icon>Edit
+ <v-subheader>Info</v-subheader>
+ <v-card>
+ <v-card-text>
+ <v-layout wrap>
+ <v-flex sm6 xs12 order-xs2 order-sm1>
+ <v-text-field v-if="editMode" hide-details class="info-input" label="Name" color="primary" v-model="info.name"></v-text-field>
+ <div v-else class="info-input">
+ <div class="body-2">Name</div>
+ {{ group.name || '-' }}
+ </div>
+ </v-flex>
+ <v-flex sm6 xs12 order-xs1 order-sm2 class="text-xs-right">
+ <div class="info-input">
+ <v-btn v-if="!editMode" color="primary" flat @click="editInfo">
+ <v-icon left>create</v-icon>Edit
+ </v-btn>
+ <div v-else>
+ <v-btn color="primary" flat @click="editMode = false">Cancel</v-btn>
+ <v-btn color="primary" @click="saveInfo">
+ <v-icon left>save</v-icon>Save
</v-btn>
- <div v-else>
- <v-btn color="primary" flat @click="editMode = false">Cancel</v-btn>
- <v-btn color="primary" @click="saveInfo">
- <v-icon left>save</v-icon>Save
- </v-btn>
- </div>
- </div>
- </v-flex>
- </v-layout>
- <v-layout wrap>
- <v-flex sm6 xs12>
- <v-textarea v-if="editMode" rows="1" auto-grow hide-details class="info-input" label="Description" color="primary" v-model="info.description"></v-textarea>
- <div v-else class="info-input">
- <div class="body-2">Description</div>
- <pre>{{ group.description || '-' }}</pre>
- </div>
- </v-flex>
- <v-flex sm6 xs12>
- <v-autocomplete
- v-if="editMode"
- class="info-input"
- :items="$store.state.groups.groupList"
- v-model="info.parentIds"
- hide-details
- offset-y
- label="Parents"
- color="primary"
- multiple
- >
- <template slot="selection" slot-scope="data">
- <v-chip small :selected="data.selected" @input="removeParent(data.item.id)" close>
- {{ data.item.text }}
- </v-chip>
- </template>
- </v-autocomplete>
- <div v-else class="info-input">
- <div class="body-2">Parents</div>
- <template v-if="group.parents.length > 0">
- <v-chip v-for="parent in group.parents" :key="parent.id" small>
- {{ parent.name || parent.id }}
- </v-chip>
- </template>
- <span v-else>-</span>
</div>
- </v-flex>
- </v-layout>
- </v-card-text>
- </v-card>
- </template>
+ </div>
+ </v-flex>
+ </v-layout>
+ <v-layout wrap>
+ <v-flex sm6 xs12>
+ <v-textarea v-if="editMode" rows="1" auto-grow hide-details class="info-input" label="Description" color="primary" v-model="info.description"></v-textarea>
+ <div v-else class="info-input">
+ <div class="body-2">Description</div>
+ <pre>{{ group.description || '-' }}</pre>
+ </div>
+ </v-flex>
+ <v-flex sm6 xs12>
+ <v-autocomplete
+ v-if="editMode"
+ class="info-input"
+ :items="$store.state.groups.groupList"
+ v-model="parentIds"
+ hide-details
+ offset-y
+ label="Parents"
+ color="primary"
+ multiple
+ >
+ <template slot="selection" slot-scope="data">
+ <v-chip small :selected="data.selected" @input="removeParent(data.item.value)" close>
+ {{ data.item.text }}
+ </v-chip>
+ </template>
+ </v-autocomplete>
+ <div v-else class="info-input">
+ <div class="body-2">Parents</div>
+ <template v-if="group.parents.length > 0">
+ <v-chip v-for="parent in group.parents" :key="parent.id" small>
+ {{ parent.name || parent.id }}
+ </v-chip>
+ </template>
+ <span v-else>-</span>
+ </div>
+ </v-flex>
+ </v-layout>
+ </v-card-text>
+ </v-card>
<v-subheader>{{ tabIndex === 0 ? 'Groups' : 'Subgoups' }}</v-subheader>
<group-module-group-list :tabIndex="tabIndex" :groups="group.subgroups" />
<v-subheader>Clients</v-subheader>
@@ -98,23 +96,29 @@ export default {
editMode: false,
info: {
name: '',
- description: '',
- parentIds: []
- }
+ description: ''
+ },
+ parentIds: []
}
},
methods: {
removeParent (id) {
- this.info.parentIds.splice(this.info.parentIds.indexOf(id), 1)
+ console.log(this.parentIds.indexOf(id))
+ this.parentIds.splice(this.parentIds.indexOf(id), 1)
},
editInfo () {
this.editMode = true
this.info.name = this.group.name
this.info.description = this.group.description
- this.info.parentIds = this.group.parents.map(x => x.id)
+ this.parentIds = this.group.parents.map(x => x.id)
},
saveInfo () {
- this.$store.dispatch('groups/saveGroupInfo', { id: this.group.id, info: this.info, tabIndex: this.tabIndex })
+ this.$store.dispatch('groups/saveGroup', {
+ id: this.group.id,
+ info: this.info,
+ parentIds: this.parentIds,
+ tabIndex: this.tabIndex
+ })
this.editMode = false
}
}
diff --git a/webapp/src/store/groups.js b/webapp/src/store/groups.js
index 45fa59b..5df5609 100644
--- a/webapp/src/store/groups.js
+++ b/webapp/src/store/groups.js
@@ -60,20 +60,25 @@ export default {
})
},
reload (context) {
+ context.dispatch('loadLists')
context.state.tabChain.forEach((item, index) => {
if (item.tabType === 'home') context.dispatch('loadHome')
else if (item.tabType === 'group') context.dispatch('loadGroup', { id: item.id, tabIndex: index })
else if (item.tabType === 'client') context.dispatch('loadClient', { id: item.id, tabIndex: index })
})
},
- saveGroupInfo (context, { id, info, tabIndex }) {
- axios.post('/api/groups/saveInfo', {
- id,
- name: info.name,
- description: info.description,
- parentIds: info.parentIds
- }).then(res => {
- if (tabIndex > 1 && !(context.state.tabChain[tabIndex - 1].id in info.parentIds)) {
+ saveGroup (context, { id, info, parentIds, tabIndex }) {
+ axios.post('/api/groups/saveInfo', { id, info, parentIds }).then(res => {
+ if (parentIds && tabIndex > 1 && !parentIds.includes(context.state.tabChain[tabIndex - 1].id)) {
+ context.commit('deleteFromTabChain', { index: 1, count: tabIndex - 1 })
+ context.commit('setActiveTab', 1)
+ }
+ context.dispatch('reload')
+ })
+ },
+ saveClient (context, { id, info, groupIds, tabIndex }) {
+ axios.post('/api/clients/saveInfo', { id, info, groupIds }).then(res => {
+ if (groupIds && tabIndex > 1 && !groupIds.includes(context.state.tabChain[tabIndex - 1].id)) {
context.commit('deleteFromTabChain', { index: 1, count: tabIndex - 1 })
context.commit('setActiveTab', 1)
}