summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUdo Walter2018-07-31 04:20:37 +0200
committerUdo Walter2018-07-31 04:20:37 +0200
commitcb7711cc9f76fe4211538bad74de68c57cd07e83 (patch)
tree633568bcbc8737e97eb0e99eaefbf846422e6147
parent[webapp/external-backends] Dialog polishing. Thx Udo for fixing the scroll co... (diff)
downloadbas-cb7711cc9f76fe4211538bad74de68c57cd07e83.tar.gz
bas-cb7711cc9f76fe4211538bad74de68c57cd07e83.tar.xz
bas-cb7711cc9f76fe4211538bad74de68c57cd07e83.zip
[groups] add edit form for groups; add description to groups and clients
-rw-r--r--server/api/clients.js22
-rw-r--r--server/api/groups.js63
-rw-r--r--server/migrations/20180717132233-create-group.js3
-rw-r--r--server/migrations/20180717132333-create-client.js3
-rw-r--r--server/models/client.js1
-rw-r--r--server/models/group.js3
-rw-r--r--webapp/src/components/GroupModule.vue48
-rw-r--r--webapp/src/components/GroupModuleClientList.vue80
-rw-r--r--webapp/src/components/GroupModuleClientView.vue32
-rw-r--r--webapp/src/components/GroupModuleEditDialog.vue83
-rw-r--r--webapp/src/components/GroupModuleGroupList.vue75
-rw-r--r--webapp/src/components/GroupModuleGroupView.vue114
-rw-r--r--webapp/src/store/groups.js114
13 files changed, 397 insertions, 244 deletions
diff --git a/server/api/clients.js b/server/api/clients.js
index 37e207b..d494fd0 100644
--- a/server/api/clients.js
+++ b/server/api/clients.js
@@ -2,17 +2,19 @@
var path = require('path')
var db = require(path.join(__appdir, 'lib', 'sequelize'))
-module.exports = {
- get: {
-
- getInfo: function (req, res) {
- db.client.findOne({ where: { id: req.query.id } }).then(client => {
- res.send(client)
- })
- }
-
+// GET Requests
+module.exports.get = {
+ getList: function (req, res) {
+ db.client.findAll({ attributes: ['id', 'name'] }).then(list => {
+ res.send(list)
+ })
},
- post: {
+ getGroups: function (req, res) {
+ db.client.findOne({ where: { id: req.query.id } }).then(client => {
+ client.getGroups().then(groups => {
+ res.send(groups)
+ })
+ })
}
}
diff --git a/server/api/groups.js b/server/api/groups.js
index ff29799..fa2c1ca 100644
--- a/server/api/groups.js
+++ b/server/api/groups.js
@@ -2,41 +2,44 @@
var path = require('path')
var db = require(path.join(__appdir, 'lib', 'sequelize'))
-module.exports = {
- get: {
-
- getParents: function (req, res) {
- const id = req.query.id > 0 ? req.query.id : null
- db.group.findOne({ where: { id: id }, include: ['parents'] }).then(group => {
- group.getParents().then(parents => {
- res.send(parents.map(x => ({ id: x.id, name: x.name })))
- })
- })
- },
-
- getSubGroups: function (req, res) {
- const id = req.query.id > 0 ? req.query.id : null
- db.group.findAll({ where: { '$parents.id$': id }, include: ['parents'] }).then(result => {
- res.send(result)
- })
- },
+// GET Requests
+module.exports.get = {
+ getList: function (req, res) {
+ db.group.findAll({ attributes: ['id', 'name'] }).then(list => {
+ res.send(list)
+ })
+ },
- getClients: function (req, res) {
- const id = req.query.id > 0 ? req.query.id : null
- db.client.findAll({ where: { '$groups.id$': id }, include: ['groups'] }).then(result => {
- res.send(result)
+ getParents: function (req, res) {
+ const id = req.query.id > 0 ? req.query.id : null
+ db.group.findOne({ where: { id: id }, include: ['parents'] }).then(group => {
+ group.getParents().then(parents => {
+ res.send(parents)
})
- }
+ })
+ },
+ getSubGroups: function (req, res) {
+ const id = req.query.id > 0 ? req.query.id : null
+ db.group.findAll({ where: { '$parents.id$': id }, include: ['parents'] }).then(subgroups => {
+ res.send(subgroups)
+ })
},
- post: {
- update: function (req, res) {
- const id = req.body.id > 0 ? req.body.id : null
- if (!id) res.end()
- db.group.update({ name: req.body.name }, { where: { id: id } })
- res.end()
- }
+ getClients: function (req, res) {
+ const id = req.query.id > 0 ? req.query.id : null
+ db.client.findAll({ where: { '$groups.id$': id }, include: ['groups'] }).then(clients => {
+ res.send(clients)
+ })
+ }
+}
+// POST Requests
+module.exports.post = {
+ update: function (req, res) {
+ const id = req.body.id > 0 ? req.body.id : null
+ if (!id) res.end()
+ db.group.update({ name: req.body.name }, { where: { id: id } })
+ res.end()
}
}
diff --git a/server/migrations/20180717132233-create-group.js b/server/migrations/20180717132233-create-group.js
index 720a1e7..71258dd 100644
--- a/server/migrations/20180717132233-create-group.js
+++ b/server/migrations/20180717132233-create-group.js
@@ -10,6 +10,9 @@ module.exports = {
},
name: {
type: Sequelize.STRING
+ },
+ description: {
+ type: Sequelize.STRING
}
})
},
diff --git a/server/migrations/20180717132333-create-client.js b/server/migrations/20180717132333-create-client.js
index 79552c4..955f2f9 100644
--- a/server/migrations/20180717132333-create-client.js
+++ b/server/migrations/20180717132333-create-client.js
@@ -11,6 +11,9 @@ module.exports = {
name: {
type: Sequelize.STRING
},
+ description: {
+ type: Sequelize.STRING
+ },
ip: {
type: Sequelize.STRING
},
diff --git a/server/models/client.js b/server/models/client.js
index 1086023..483d1e6 100644
--- a/server/models/client.js
+++ b/server/models/client.js
@@ -8,6 +8,7 @@ module.exports = (sequelize, DataTypes) => {
type: DataTypes.INTEGER
},
name: DataTypes.STRING,
+ description: DataTypes.STRING,
ip: DataTypes.STRING,
mac: DataTypes.STRING,
uuid: DataTypes.STRING
diff --git a/server/models/group.js b/server/models/group.js
index 223df07..e988497 100644
--- a/server/models/group.js
+++ b/server/models/group.js
@@ -7,7 +7,8 @@ module.exports = (sequelize, DataTypes) => {
primaryKey: true,
type: DataTypes.INTEGER
},
- name: DataTypes.STRING
+ name: DataTypes.STRING,
+ description: DataTypes.STRING
}, {
timestamps: false
})
diff --git a/webapp/src/components/GroupModule.vue b/webapp/src/components/GroupModule.vue
index 123f847..b690628 100644
--- a/webapp/src/components/GroupModule.vue
+++ b/webapp/src/components/GroupModule.vue
@@ -12,60 +12,64 @@
<v-layout>
<v-flex class="tabs-wrapper" xl10 offset-xl1 lg12>
<v-card>
- <v-tabs :value="activeTab" @input="updateActiveTab" :dark="tabsDark" :color="tabsColor" :slider-color="tabsSliderColor">
- <template v-for="(group, index) in groupChain">
- <v-icon v-if="group.id > 0" :key="2*index">keyboard_arrow_right</v-icon>
+ <v-tabs :value="activeTab" @input="setActiveTab" :dark="tabsDark" :color="tabsColor" :slider-color="tabsSliderColor">
+ <template v-for="(item, index) in tabChain">
+ <v-icon v-if="item.id > 0" :key="2*index">keyboard_arrow_right</v-icon>
<v-tab :key="2*index+1" ripple>
- <v-icon v-if="group.id === 0">home</v-icon>
- <template v-else>{{ group.name ? group.name : group.id }}</template>
+ <v-icon v-if="item.id === 0">home</v-icon>
+ <template v-else>
+ <v-icon v-if="item.isClient" style="margin-right: 10px">computer</v-icon>
+ {{ item.name ? item.name : item.id }}
+ </template>
</v-tab>
</template>
</v-tabs>
</v-card>
- <v-tabs-items :value="activeTab" @input="updateActiveTab" touchless>
- <template v-for="(group, index) in groupChain">
+ <v-tabs-items :value="activeTab" @input="setActiveTab" touchless style="padding-bottom: 20px">
+ <template v-for="(item, index) in tabChain">
<v-tab-item :key="index">
- <group-module-group-view :tabIndex="index" />
+ <group-module-group-view :tabIndex="index" v-if="!item.isClient" />
+ <group-module-client-view v-else />
</v-tab-item>
</template>
</v-tabs-items>
</v-flex>
</v-layout>
- <group-module-edit-dialog />
</v-container>
</template>
<script>
import GroupModuleGroupView from '@/components/GroupModuleGroupView'
-import GroupModuleEditDialog from '@/components/GroupModuleEditDialog'
-import { mapState, mapGetters } from 'vuex'
+import GroupModuleClientView from '@/components/GroupModuleClientView'
+import { mapState, mapGetters, mapMutations } from 'vuex'
export default {
name: 'GroupModule',
components: {
GroupModuleGroupView,
- GroupModuleEditDialog
+ GroupModuleClientView
},
data () {
return {
- editDialog: false,
- editId: null,
- editClient: false
}
},
computed: {
...mapGetters(['tabsDark', 'tabsColor', 'tabsSliderColor']),
- ...mapState('groups', ['groupChain', 'activeTab'])
+ ...mapState('groups', ['groupChain', 'client', 'activeTab']),
+ tabChain () {
+ if (this.client) return this.groupChain.concat({ isClient: true, ...this.client })
+ else return this.groupChain
+ }
},
methods: {
- updateActiveTab (tabIndex) {
- this.$store.commit('groups/updateActiveTab', tabIndex)
- }
+ ...mapMutations('groups', ['setActiveTab'])
},
created () {
- if (this.$store.state.groups.groupChain == null || this.$store.state.groups.groupChain.length === 0) {
- this.$store.dispatch('groups/loadGroupInChain', { tabIndex: 0, id: 0 })
- }
+ this.$store.dispatch('groups/loadLists')
+ this.$store.dispatch('groups/loadRoot')
+ },
+ destroyed () {
+ this.$store.commit('groups/resetStore')
}
}
</script>
diff --git a/webapp/src/components/GroupModuleClientList.vue b/webapp/src/components/GroupModuleClientList.vue
index a1036aa..8f9c306 100644
--- a/webapp/src/components/GroupModuleClientList.vue
+++ b/webapp/src/components/GroupModuleClientList.vue
@@ -8,35 +8,47 @@
</i18n>
<template>
- <v-data-table stlye="width: 100px"
- :headers="headers"
- :items="clients"
- item-key="id"
- hide-actions
- select-all
- v-model="selected"
- >
- <template slot="items" slot-scope="props">
- <tr @click="props.selected = !props.selected">
- <td class="narrow-td">
- <v-checkbox
- color="primary"
- v-model="props.selected"
- hide-details
- @click.native.stop
- ></v-checkbox>
- </td>
- <td class="narrow-td">{{ props.item.id }}</td>
- <td>{{ props.item.name }}</td>
- <td>{{ props.item.ip }}</td>
- <td>{{ props.item.mac }}</td>
- <td>{{ props.item.uuid }}</td>
- <td class="narrow-td">
- <v-btn icon @click.stop><v-icon color="primary">edit</v-icon></v-btn>
- </td>
- </tr>
- </template>
- </v-data-table>
+ <div>
+ <v-card>
+ <v-data-table stlye="width: 100px"
+ :headers="headers"
+ :items="clients"
+ item-key="id"
+ hide-actions
+ select-all
+ v-model="selected"
+ >
+ <template slot="items" slot-scope="props">
+ <tr @click="loadClient(props.item.id)">
+ <td class="narrow-td">
+ <v-checkbox
+ color="primary"
+ v-model="props.selected"
+ hide-details
+ @click.native.stop
+ ></v-checkbox>
+ </td>
+ <td class="narrow-td">{{ props.item.id }}</td>
+ <td>{{ props.item.name }}</td>
+ <td>{{ props.item.ip }}</td>
+ <td>{{ props.item.mac }}</td>
+ <td>{{ props.item.uuid }}</td>
+ <td class="narrow-td">
+ <v-btn class="next-arrow" icon><v-icon>keyboard_arrow_right</v-icon></v-btn>
+ </td>
+ </tr>
+ </template>
+ </v-data-table>
+ </v-card>
+ <div v-if="tabIndex > 0" class="text-xs-right">
+ <v-btn flat color="error"><v-icon left>remove_circle_outline</v-icon>Remove selected clients</v-btn>
+ <v-btn flat color="success"><v-icon left>add_circle_outline</v-icon>Add clients</v-btn>
+ </div>
+ <div v-else class="text-xs-right">
+ <v-btn flat color="error"><v-icon left>delete</v-icon>Delete selected clients</v-btn>
+ <v-btn flat color="success"><v-icon left>create</v-icon>Create client</v-btn>
+ </div>
+ </div>
</template>
<script>
@@ -61,6 +73,11 @@ export default {
clients () {
return this.$store.state.groups.groupChain[this.tabIndex].clients
}
+ },
+ methods: {
+ loadClient (id) {
+ this.$store.dispatch('groups/loadClientIntoTab', id)
+ }
}
}
</script>
@@ -70,4 +87,9 @@ export default {
.narrow-td {
width: 10px;
}
+
+.next-arrow {
+ margin-left: 20px;
+ margin-right: -10px;
+}
</style>
diff --git a/webapp/src/components/GroupModuleClientView.vue b/webapp/src/components/GroupModuleClientView.vue
new file mode 100644
index 0000000..7518d67
--- /dev/null
+++ b/webapp/src/components/GroupModuleClientView.vue
@@ -0,0 +1,32 @@
+<i18n>
+{
+ "en": {
+ },
+ "de": {
+ }
+}
+</i18n>
+
+<template>
+ <div>
+ <v-subheader>Info</v-subheader>
+ <v-card>
+
+ </v-card>
+ </div>
+</template>
+
+<script>
+export default {
+ name: 'GroupModuleClientView',
+ props: ['tabIndex'],
+ data () {
+ return {
+ }
+ }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+</style>
diff --git a/webapp/src/components/GroupModuleEditDialog.vue b/webapp/src/components/GroupModuleEditDialog.vue
deleted file mode 100644
index 8eab1e1..0000000
--- a/webapp/src/components/GroupModuleEditDialog.vue
+++ /dev/null
@@ -1,83 +0,0 @@
-<i18n>
-{
- "en": {
- },
- "de": {
- }
-}
-</i18n>
-
-<template>
- <v-dialog :value="editDialog" @input="setEditDialog" max-width="600px">
- <v-card>
- <div class="input-fields">
- <v-text-field v-model="name" label="Name" box color="primary"></v-text-field>
- </div>
- <div class="action-buttons text-xs-right">
- <v-btn flat @click="$emit('close')">Cancel</v-btn>
- <v-btn color="primary" @click="saveData">Save</v-btn>
- </div>
- </v-card>
- </v-dialog>
-</template>
-
-<script>
-import { mapState, mapMutations } from 'vuex'
-
-export default {
- name: 'GroupModuleEditDialog',
- props: ['id', 'client'],
- data () {
- return {
- name: ''
- }
- },
- computed: {
- ...mapState('groups', ['editDialog'])
- },
- methods: {
- ...mapMutations('groups', ['setEditDialog']),
- loadData () {
- if (!this.id) return
- if (this.client) {
- // TODO
- } else {
- this.$http('/api/groups?action=getInfo&id=' + this.id).then(response => {
- this.name = response.data.name
- })
- }
- },
- saveData () {
- if (this.client) {
- // TODO
- } else {
- this.$http.post('/api/groups', {
- action: 'setInfo',
- id: this.id,
- name: this.name
- }).then(response => {
- console.log(response)
- })
- }
- this.$emit('close')
- this.$emit('reload')
- }
- },
- created () {
- this.loadData()
- }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-.input-fields {
- padding: 40px;
- padding-bottom: 0;
-}
-
-.action-buttons {
- padding: 10px;
-}
-
-</style>
diff --git a/webapp/src/components/GroupModuleGroupList.vue b/webapp/src/components/GroupModuleGroupList.vue
index a9976f9..0abd2fa 100644
--- a/webapp/src/components/GroupModuleGroupList.vue
+++ b/webapp/src/components/GroupModuleGroupList.vue
@@ -9,36 +9,44 @@
<template>
<div>
- <v-data-table
- class="group-table"
- :headers="headers"
- :items="groups"
- item-key="id"
- hide-actions
- select-all
- v-model="selected"
- >
- <template slot="items" slot-scope="props">
- <tr @click="loadGroup(props.item)">
- <td>
- <v-checkbox
- color="primary"
- v-model="props.selected"
- hide-details
- @click.native.stop
- ></v-checkbox>
- </td>
- <td>{{ props.item.id }}</td>
- <td>{{ props.item.name }}</td>
- <td>
- <v-layout>
- <v-btn icon @click.stop><v-icon color="primary">edit</v-icon></v-btn>
+ <v-card>
+ <v-data-table
+ class="group-table"
+ :headers="headers"
+ :items="groups"
+ item-key="id"
+ hide-actions
+ select-all
+ v-model="selected"
+ >
+ <template slot="items" slot-scope="props">
+ <tr @click="loadGroup(props.item.id)">
+ <td>
+ <v-checkbox
+ color="primary"
+ v-model="props.selected"
+ hide-details
+ @click.native.stop
+ ></v-checkbox>
+ </td>
+ <td>{{ props.item.id }}</td>
+ <td>{{ props.item.name }}</td>
+ <td>{{ props.item.description }}</td>
+ <td>
<v-btn class="next-arrow" icon><v-icon>keyboard_arrow_right</v-icon></v-btn>
- </v-layout>
- </td>
- </tr>
- </template>
- </v-data-table>
+ </td>
+ </tr>
+ </template>
+ </v-data-table>
+ </v-card>
+ <div v-if="tabIndex > 0" class="text-xs-right">
+ <v-btn flat color="error"><v-icon left>remove_circle_outline</v-icon>Remove selected subgroups</v-btn>
+ <v-btn flat color="success"><v-icon left>add_circle_outline</v-icon>Add subgroups</v-btn>
+ </div>
+ <div v-else class="text-xs-right">
+ <v-btn flat color="error"><v-icon left>delete</v-icon>Delete selected groups</v-btn>
+ <v-btn flat color="success"><v-icon left>create</v-icon>Create group</v-btn>
+ </div>
</div>
</template>
@@ -55,7 +63,8 @@ export default {
return {
headers: [
{ text: 'ID', value: 'id' },
- { text: 'Name', value: 'name', width: '10000px' },
+ { text: 'Name', value: 'name' },
+ { text: 'Description', value: 'description', width: '10000px' },
{ sortable: false }
],
selected: []
@@ -67,10 +76,8 @@ export default {
}
},
methods: {
- loadGroup (group) {
- this.$store.dispatch('groups/loadGroupInChain', {
- tabIndex: this.tabIndex + 1, id: group.id, name: group.name, switchTab: true
- })
+ loadGroup (id) {
+ this.$store.dispatch('groups/loadGroupIntoTab', { id, tabIndex: this.tabIndex + 1 })
}
}
}
diff --git a/webapp/src/components/GroupModuleGroupView.vue b/webapp/src/components/GroupModuleGroupView.vue
index 69a8832..4126b2c 100644
--- a/webapp/src/components/GroupModuleGroupView.vue
+++ b/webapp/src/components/GroupModuleGroupView.vue
@@ -9,14 +9,77 @@
<template>
<div>
- <v-subheader>Groups</v-subheader>
- <v-card>
- <group-module-group-list :tabIndex="tabIndex" />
- </v-card>
+ <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" box 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>
+ </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" box 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-select
+ v-if="editMode"
+ class="info-input"
+ :items="groupList"
+ v-model="info.parents"
+ hide-details
+ offset-y
+ label="Parents"
+ box color="primary"
+ multiple
+ autocomplete
+ >
+ <template slot="selection" slot-scope="data">
+ <v-chip small :color="chipColor" :text-color="chipTextColor" :selected="data.selected" @input="removeParent(data.item.value)" close>
+ {{ data.item.text }}
+ </v-chip>
+ </template>
+ </v-select>
+ <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>
+ <v-subheader>{{ tabIndex === 0 ? 'Groups' : 'Subgoups' }}</v-subheader>
+ <group-module-group-list :tabIndex="tabIndex" />
<v-subheader>Clients</v-subheader>
- <v-card>
- <group-module-client-list :tabIndex="tabIndex" />
- </v-card>
+ <group-module-client-list :tabIndex="tabIndex" />
</div>
</template>
@@ -33,6 +96,40 @@ export default {
},
data () {
return {
+ editMode: false,
+ info: {
+ name: '',
+ description: '',
+ parents: []
+ }
+ }
+ },
+ computed: {
+ groupList () {
+ return this.$store.state.groups.groupList
+ },
+ group () {
+ return this.$store.state.groups.groupChain[this.tabIndex]
+ },
+ chipColor () {
+ return this.$store.state.settings.dark ? 'grey darken-1' : 'white'
+ },
+ chipTextColor () {
+ return this.$store.state.settings.dark ? 'white' : 'black'
+ }
+ },
+ methods: {
+ removeParent (id) {
+ this.info.parents.splice(this.info.parents.indexOf(id), 1)
+ },
+ editInfo () {
+ this.editMode = true
+ this.info.name = this.group.name
+ this.info.description = this.group.description
+ this.info.parents = this.group.parents.map(x => x.id)
+ },
+ saveInfo () {
+
}
}
}
@@ -40,4 +137,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/store/groups.js b/webapp/src/store/groups.js
index 8ce7f6b..6c5a23c 100644
--- a/webapp/src/store/groups.js
+++ b/webapp/src/store/groups.js
@@ -1,50 +1,108 @@
+import Vue from 'vue'
import axios from 'axios'
export default {
namespaced: true,
state: {
+ groupList: [],
+ clientList: [],
+ groupCache: {},
+ clientCache: {},
groupChain: [],
- activeTab: 0,
- editGroupDialog: false,
- editGroup: null
+ client: null,
+ activeTab: 0
},
mutations: {
- updateActiveTab (state, tabIndex) {
- state.activeTab = tabIndex
- },
- setGroupInChain (state, { tabIndex, group }) {
- if (state.groupChain.length <= tabIndex || state.groupChain[tabIndex].id !== group.id) {
+ setGroupList: (state, list) => { state.groupList = list },
+ setClientList: (state, list) => { state.clientList = list },
+ setActiveTab: (state, tabIndex) => { state.activeTab = tabIndex },
+ setGroupChain: (state, chain) => { state.groupChain = chain },
+ setClient: (state, id) => { state.client = state.clientCache[id] },
+ setGroupInChain (state, { id, tabIndex }) {
+ if (state.groupChain.length <= tabIndex || state.groupChain[tabIndex].id !== id) {
+ state.client = null
state.groupChain = state.groupChain.slice(0, tabIndex)
- state.groupChain.push(group)
+ state.groupChain.push(state.groupCache[id])
+ }
+ },
+ cacheGroup (state, group) {
+ if ('id' in group) {
+ if (!(group.id in state.groupCache)) state.groupCache[group.id] = group
+ else Object.keys(group).forEach(key => { Vue.set(state.groupCache[group.id], key, group[key]) })
}
},
- openEditGroupDialog (state, group) {
- state.editGroupDialog = true
- state.editGroup = group
+ cacheClient (state, client) {
+ if ('id' in client) {
+ if (!(client.id in state.clientCache)) state.clientCache[client.id] = client
+ else Object.keys(client).forEach(key => { Vue.set(state.clientCache[client.id], key, client[key]) })
+ }
},
- closeEditGroupDialog (state) {
- state.editGroupDialog = false
- state.editGroup = null
+ resetStore (state) {
+ state.groupList = []
+ state.clientList = []
+ state.groupCache = {}
+ state.clientCache = {}
+ state.groupChain = []
+ state.client = null
+ state.activeTab = 0
}
},
actions: {
- loadGroupInChain (context, { id, name, tabIndex, switchTab }) {
- var getSubGroups = axios.get('/api/groups/getSubGroups?id=' + id)
- var getClients = axios.get('/api/groups/getClients?id=' + id)
- axios.all([getSubGroups, getClients]).then(axios.spread((groupRespsonse, clientResponse) => {
- var group = { id: id, name: name, subGroups: groupRespsonse.data, clients: clientResponse.data }
- context.commit('setGroupInChain', { group: group, tabIndex: tabIndex })
- if (switchTab) context.commit('updateActiveTab', tabIndex)
+ loadLists (context) {
+ var getGroupList = axios.get('/api/groups/getList')
+ var getClientList = axios.get('/api/clients/getList')
+ axios.all([getGroupList, getClientList]).then(axios.spread((groupResponse, clientResponse) => {
+ context.commit('setGroupList', groupResponse.data.map(x => ({ value: x.id, text: x.name || x.id })))
+ context.commit('setClientList', clientResponse.data.map(x => ({ value: x.id, text: x.name || x.id })))
}))
},
- editGroup (context, { id, name }) {
- axios.get('/api/groups/getParents?id=' + id).then(res => {
- context.commit('openEditGroupDialog', { id: id, name: name, parents: res.data })
+ loadRoot (context) {
+ var getGroups = axios.get('/api/groups/getSubGroups?id=' + 0)
+ var getClients = axios.get('/api/groups/getClients?id=' + 0)
+ axios.all([getGroups, getClients]).then(axios.spread((groupResponse, clientResponse) => {
+ groupResponse.data.forEach(group => { context.commit('cacheGroup', group) })
+ clientResponse.data.forEach(client => { context.commit('cacheClient', client) })
+ context.commit('setGroupChain', [{ id: 0, subGroups: groupResponse.data, clients: clientResponse.data }])
+ }))
+ },
+ loadGroupIntoTab (context, { id, tabIndex }) {
+ var cached = null
+ if (context.state.groupCache[id].fullyCached) {
+ cached = new Promise(resolve => resolve())
+ } else {
+ var getParents = axios.get('/api/groups/getParents?id=' + id)
+ var getSubGroups = axios.get('/api/groups/getSubGroups?id=' + id)
+ var getClients = axios.get('/api/groups/getClients?id=' + id)
+ cached = axios.all([getParents, getSubGroups, getClients]).then(axios.spread((parentResponse, groupResponse, clientResponse) => {
+ parentResponse.data.forEach(group => { context.commit('cacheGroup', group) })
+ groupResponse.data.forEach(group => { context.commit('cacheGroup', group) })
+ clientResponse.data.forEach(client => { context.commit('cacheClient', client) })
+ context.commit('cacheGroup', {
+ id,
+ fullyCached: true,
+ parents: parentResponse.data.map(x => context.state.groupCache[x.id]),
+ subGroups: groupResponse.data.map(x => context.state.groupCache[x.id]),
+ clients: clientResponse.data.map(x => context.state.clientCache[x.id])
+ })
+ }))
+ }
+ cached.then(() => {
+ context.commit('setGroupInChain', { id, tabIndex })
+ context.commit('setActiveTab', tabIndex)
})
},
- saveGroup (context) {
- axios.post('/api/groups/update?id=' + context.state.editGroup.id).then(res => {
- context.commit('closeEditGroupDialog')
+ loadClientIntoTab (context, id) {
+ var cached = null
+ if (context.state.clientCache[id].fullyCached) {
+ cached = new Promise(resolve => resolve())
+ } else {
+ cached = axios.get('/api/clients/getGroups?id=' + id).then(response => {
+ context.commit('cacheClient', { id, fullyCached: true, groups: response.data.map(x => context.state.groupCache[x.id]) })
+ })
+ }
+ cached.then(() => {
+ context.commit('setClient', id)
+ context.commit('setActiveTab', context.state.groupChain.length)
})
}
}