From 9bffdf4923a20a443f28c74aa4b130a5bbf1bb34 Mon Sep 17 00:00:00 2001 From: Udo Walter Date: Wed, 25 Mar 2020 12:29:17 +0000 Subject: [webapp] show part of the path (full path on hover) in the select boxes for selecting groups and clients --- server/api/clients.js | 8 ++++-- server/api/groups.js | 5 +++- server/lib/grouphelper.js | 55 ++++++++++++++++++++++++++++++++++++- webapp/src/assets/styles.css | 2 +- webapp/src/components/DataTable.vue | 1 + webapp/src/components/LogModule.vue | 50 +++++++++++++++++++++------------ webapp/src/components/SelectBox.vue | 22 +++++++++++++++ webapp/src/store/groups.js | 4 +-- 8 files changed, 122 insertions(+), 25 deletions(-) diff --git a/server/api/clients.js b/server/api/clients.js index 15e3b8d..4222f49 100644 --- a/server/api/clients.js +++ b/server/api/clients.js @@ -8,13 +8,17 @@ const { decorateApp } = require('@awaitjs/express') var router = decorateApp(express.Router()) const HttpResponse = require(path.join(__appdir, 'lib', 'httpresponse')) const log = require(path.join(__appdir, 'lib', 'log')) +const groupHelper = require(path.join(__appdir, 'lib', 'grouphelper')) // ############################################################################ // ########################### GET requests ################################# router.getAsync('', async (req, res) => { - const clients = await db.client.findAll({ order: [['name', 'ASC']] }) - res.status(200).send(clients) + const includePaths = req.query.path !== undefined && req.query.path !== 'false' + const include = includePaths ? ['groups'] : [] + let clients = await db.client.findAll({ order: [['name', 'ASC']], include }) + if (includePaths) clients = await groupHelper.addPathsToClients(clients, false) + res.send(clients) }) router.getAsync('/:id', async (req, res) => { diff --git a/server/api/groups.js b/server/api/groups.js index 88e7da8..64351cf 100644 --- a/server/api/groups.js +++ b/server/api/groups.js @@ -14,7 +14,10 @@ const log = require(path.join(__appdir, 'lib', 'log')) // ########################### GET requests ################################# router.getAsync('', async (req, res) => { - const groups = await db.group.findAll({ order: [['name', 'ASC']] }) + const includePaths = req.query.path !== undefined && req.query.path !== 'false' + const include = includePaths ? ['parents'] : [] + let groups = await db.group.findAll({ order: [['name', 'ASC']], include }) + if (includePaths) groups = await groupHelper.addPathsToGroups(groups, false) res.send(groups) }) diff --git a/server/lib/grouphelper.js b/server/lib/grouphelper.js index 117dd79..fe94b50 100644 --- a/server/lib/grouphelper.js +++ b/server/lib/grouphelper.js @@ -36,4 +36,57 @@ async function getAllChildrenByIds (groupIds, knownGroupMap, knownClientMap) { return { subgroups, clients } } -module.exports = { getAllChildren } +async function addPathsToGroups (groups, queryParents = true) { + const allGroups = queryParents ? await db.group.findAll({ order: [['name', 'ASC']], include: ['parents'] }) : groups + const parentMap = {} + allGroups.forEach(group => { + parentMap[group.id] = group.parents + }) + const groupsWithPaths = [] + groups.forEach(group => { + let g = group.toJSON() + delete g.parents + g.paths = _buildPaths(parentMap, group) + groupsWithPaths.push(g) + }) + return groupsWithPaths +} + +async function addPathsToClients (clients) { + const allGroups = await db.group.findAll({ order: [['name', 'ASC']], include: ['parents'] }) + const parentMap = {} + allGroups.forEach(group => { + parentMap[group.id] = group.parents + }) + const clientsWithPaths = [] + clients.forEach(client => { + let c = client.toJSON() + delete c.groups + + c.paths = [] + client.groups.forEach(group => { + c.paths.push(..._buildPaths(parentMap, group)) + }) + + clientsWithPaths.push(c) + }) + return clientsWithPaths +} + +function _buildPaths (parentMap, group, knownIds = []) { + let parents = parentMap[group.id] + let paths = [] + if (parents && parents.length > 0) { + parents.forEach(parent => { + if (!knownIds.includes(parent.id)) { + paths.push(..._buildPaths(parentMap, parent, [...knownIds, group.id])) + } + }) + if (knownIds.length) paths.forEach(path => path.push(group.name)) + } else { + if (knownIds.length) paths.push([group.name]) + } + return paths +} + +module.exports = { getAllChildren, addPathsToGroups, addPathsToClients } diff --git a/webapp/src/assets/styles.css b/webapp/src/assets/styles.css index a5b1e28..e30a465 100644 --- a/webapp/src/assets/styles.css +++ b/webapp/src/assets/styles.css @@ -205,4 +205,4 @@ html { .theme--dark .v-tooltip__content { background: white; color: black; -} \ No newline at end of file +} diff --git a/webapp/src/components/DataTable.vue b/webapp/src/components/DataTable.vue index 4643d54..4364f7c 100644 --- a/webapp/src/components/DataTable.vue +++ b/webapp/src/components/DataTable.vue @@ -582,6 +582,7 @@ export default { align-items: center; font-size: 12px; min-height: 48px; + width: 0; } .table-controls > * { diff --git a/webapp/src/components/LogModule.vue b/webapp/src/components/LogModule.vue index 386b46b..4d08464 100644 --- a/webapp/src/components/LogModule.vue +++ b/webapp/src/components/LogModule.vue @@ -15,7 +15,8 @@ "groups": "Groups", "clients": "Clients", "users": "Users", - "includeSubgroups": "Include Subgroups" + "includeSubgroups": "Include Subgroups", + "refresh" :"Refresh" }, "de": { "systemLog": "System Protokoll", @@ -32,7 +33,8 @@ "groups": "Gruppen", "clients": "Clients", "users": "Benutzer", - "includeSubgroups": "Inklusive Untergruppen" + "includeSubgroups": "Inklusive Untergruppen", + "refresh": "Aktualisieren" } } @@ -146,7 +148,7 @@ - + - + - + - - filter_list{{ $t('filter') }} + + + {{ filterModified ? 'filter_list' : 'refresh' }}{{ $t(filterModified ? 'filter' : 'refresh') }} + @@ -317,7 +321,8 @@ export default { toDateMenu: false, toTimeMenu: false, groupRecursive: false, - userList: [] + userList: [], + filterModified: false } }, computed: { @@ -341,6 +346,14 @@ export default { return this.$vuetify.breakpoint.xsOnly ? 250 : undefined } }, + watch: { + filter: { + deep: true, + handler () { + this.filterModified = true + } + } + }, methods: { setFilter (filter, value) { if (filter === 'toDate' && !this.filter.toTime) this.$store.commit('log/setFilter', { filter: 'toTime', value: this.formatDate(new Date(), { date: false, seconds: false }) }) @@ -402,6 +415,7 @@ export default { } this.log = response.data this.loading = false + this.filterModified = false } }, created () { diff --git a/webapp/src/components/SelectBox.vue b/webapp/src/components/SelectBox.vue index 5deafa3..ff3a2f9 100644 --- a/webapp/src/components/SelectBox.vue +++ b/webapp/src/components/SelectBox.vue @@ -53,6 +53,21 @@ :row-count="6" :single-select="singleSelect" > + @@ -166,6 +181,13 @@ export default { const newValue = this.value.slice(0) newValue.splice(index, 1) this.$emit('input', newValue) + }, + formatPath (path) { + return path.join(' > ') + }, + pathPreview (paths) { + if (paths.length > 0) return paths[0].slice(Math.max(paths[0].length - 2, 0)).join(' > ') + return '' } } } diff --git a/webapp/src/store/groups.js b/webapp/src/store/groups.js index 3d5aefe..bd44bb7 100644 --- a/webapp/src/store/groups.js +++ b/webapp/src/store/groups.js @@ -65,12 +65,12 @@ export default { }) }, loadGroupList (context) { - axios.get('/api/groups').then(response => { + axios.get('/api/groups?path').then(response => { context.commit('setGroupList', Object.freeze(response.data)) }) }, loadClientList (context) { - axios.get('/api/clients').then(response => { + axios.get('/api/clients?path').then(response => { context.commit('setClientList', Object.freeze(response.data)) }) }, -- cgit v1.2.3-55-g7522