summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUdo Walter2020-03-25 13:29:17 +0100
committerUdo Walter2020-03-25 13:29:17 +0100
commit9bffdf4923a20a443f28c74aa4b130a5bbf1bb34 (patch)
tree904f39a8a13782e9cf51d8d5e9ee059d1149bce1
parentmerge (diff)
downloadbas-9bffdf4923a20a443f28c74aa4b130a5bbf1bb34.tar.gz
bas-9bffdf4923a20a443f28c74aa4b130a5bbf1bb34.tar.xz
bas-9bffdf4923a20a443f28c74aa4b130a5bbf1bb34.zip
[webapp] show part of the path (full path on hover) in the select boxes for selecting groups and clients
-rw-r--r--server/api/clients.js8
-rw-r--r--server/api/groups.js5
-rw-r--r--server/lib/grouphelper.js55
-rw-r--r--webapp/src/assets/styles.css2
-rw-r--r--webapp/src/components/DataTable.vue1
-rw-r--r--webapp/src/components/LogModule.vue50
-rw-r--r--webapp/src/components/SelectBox.vue22
-rw-r--r--webapp/src/store/groups.js4
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"
}
}
</i18n>
@@ -146,7 +148,7 @@
</div>
</v-flex>
- <v-flex xs12 md3 order-xs3>
+ <v-flex xs12 md6 order-xs3>
<select-box
class="select-box"
:value="filter.clientFilter"
@@ -158,32 +160,34 @@
hide-details
></select-box>
</v-flex>
- <v-flex xs12 md3 order-xs4>
+ <v-flex xs12 md6 order-xs4>
<select-box
class="select-box"
- :value="filter.groupFilter"
- @input="setFilter('groupFilter', $event)"
- :items="groupList"
+ :value="filter.userFilter"
+ @input="setFilter('userFilter', $event)"
+ :items="userList"
:max-columns="selectBoxColumnCount"
- prepend-icon="category"
- :label="$t('groups')"
+ prepend-icon="person"
+ :label="$t('users')"
hide-details
></select-box>
</v-flex>
- <v-flex xs12 md3 order-xs4>
+ <v-flex xs12 md6 order-xs4>
<select-box
class="select-box"
- :value="filter.userFilter"
- @input="setFilter('userFilter', $event)"
- :items="userList"
+ :value="filter.groupFilter"
+ @input="setFilter('groupFilter', $event)"
+ :items="groupList"
:max-columns="selectBoxColumnCount"
- prepend-icon="person"
- :label="$t('users')"
+ prepend-icon="category"
+ :label="$t('groups')"
hide-details
></select-box>
</v-flex>
- <v-flex xs12 md3 order-xs5 style="display: flex; align-items: flex-end; justify-content: flex-end">
- <v-btn color="primary" :loading="loading" @click="loadLog"><v-icon left>filter_list</v-icon>{{ $t('filter') }}</v-btn>
+ <v-flex xs12 md6 order-xs5 style="display: flex; align-items: flex-end; justify-content: flex-end">
+ <v-btn color="primary" :loading="loading" @click="loadLog">
+ <v-icon left>{{ filterModified ? 'filter_list' : 'refresh' }}</v-icon>{{ $t(filterModified ? 'filter' : 'refresh') }}
+ </v-btn>
</v-flex>
</v-layout>
</v-card-text>
@@ -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"
>
+ <template #[textKey]="row">
+ <v-tooltip top>
+ <template v-slot:activator="{ on }">
+ <span style="font-size: 10px; opacity: 0.6" v-on="on">
+ {{ pathPreview(row.item.paths) }}
+ </span>
+ </template>
+ <div style="font-size: 11px" v-for="(path, index) in row.item.paths" :key="index">
+ {{ formatPath(path) }}
+ </div>
+ </v-tooltip>
+ <div>
+ {{ row.item.name }}
+ </div>
+ </template>
</data-table>
</v-card>
</v-menu>
@@ -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))
})
},