From c3853fa8b26e183fbc750e958021ee8e9709c8b4 Mon Sep 17 00:00:00 2001 From: Udo Walter Date: Mon, 15 Apr 2019 01:24:01 +0000 Subject: [webapp/datatable] add sort by number and ipv4 --- webapp/src/components/DashboardPage.vue | 2 -- webapp/src/components/DataTable.vue | 41 ++++++++++++++++++++----- webapp/src/components/GroupModuleClientList.vue | 4 +-- webapp/src/components/GroupModuleGroupList.vue | 2 +- webapp/src/components/IprangeModule.vue | 6 ++-- 5 files changed, 39 insertions(+), 16 deletions(-) (limited to 'webapp') diff --git a/webapp/src/components/DashboardPage.vue b/webapp/src/components/DashboardPage.vue index 19d8f44..4f7dc03 100644 --- a/webapp/src/components/DashboardPage.vue +++ b/webapp/src/components/DashboardPage.vue @@ -20,7 +20,6 @@ @@ -300,9 +300,14 @@ export default { const rows = this.rows.slice(0) for (let key in this.headerSortState) { if (!this.headers.some(header => header.sortKey || header.key === key)) continue - const direction = this.headerSortState[key] - if (direction === 'asc') rows.sort((a, b) => String(a.data[key]).localeCompare(String(b.data[key]))) - if (direction === 'desc') rows.sort((b, a) => String(a.data[key]).localeCompare(String(b.data[key]))) + const direction = this.headerSortState[key].direction + const type = this.headerSortState[key].type + let compareFunction + if (type === 'number') compareFunction = (a, b) => (Number(a.data[key]) - Number(b.data[key])) + else if (type === 'ipv4') compareFunction = (a, b) => this.ipv4Compare(a.data[key], b.data[key]) + else compareFunction = (a, b) => String(a.data[key]).localeCompare(String(b.data[key])) + rows.sort(compareFunction) + if (direction === 'desc') rows.reverse() } return Object.freeze(rows) }, @@ -428,10 +433,10 @@ export default { const key = header.sortKey || header.key const state = this.headerSortState[key] const newSortState = {} - if (state === undefined || state === 'desc') { - newSortState[key] = 'asc' - } else if (state === 'asc') { - newSortState[key] = 'desc' + if (state === undefined || state.direction === 'desc') { + newSortState[key] = { direction: 'asc', type: header.sortType } + } else { + newSortState[key] = { direction: 'desc', type: header.sortType } } this.headerSortState = newSortState }, @@ -492,6 +497,26 @@ export default { document.execCommand('copy') copyHelper.style.display = 'none' this.$snackbar({ text: this.$t('copyDone'), color: 'primary', timeout: 1200 }) + }, + ipv4Compare (a, b) { + if (!this.isValidIpv4(a)) return 1 + if (!this.isValidIpv4(b)) return -1 + a = a.split('.').map(x => parseInt(x)) + b = b.split('.').map(x => parseInt(x)) + for (let i in a) { + if (a[i] < b[i]) return -1 + else if (a[i] > b[i]) return 1 + } + return 0 + }, + isValidIpv4 (ip) { + if (!ip) return false + ip = ip.split('.') + if (ip.length !== 4) return false + for (let i in ip) { + if (ip[i] < 0 || ip[i] > 255) return false + } + return true } } } diff --git a/webapp/src/components/GroupModuleClientList.vue b/webapp/src/components/GroupModuleClientList.vue index 11b31b7..e73a3fb 100644 --- a/webapp/src/components/GroupModuleClientList.vue +++ b/webapp/src/components/GroupModuleClientList.vue @@ -74,9 +74,9 @@ export default { computed: { headers () { return [ - { key: 'id', text: this.$t('id'), width: '50px' }, + { key: 'id', text: this.$t('id'), width: '50px', sortType: 'number' }, { key: 'name', text: this.$t('name') }, - { key: 'ip', text: this.$t('ip'), width: '120px' }, + { key: 'ip', text: this.$t('ip'), width: '120px', sortType: 'ipv4' }, { key: 'mac', text: this.$t('mac'), width: '160px' }, { key: 'uuid', text: this.$t('uuid'), width: '300px' }, { key: 'actions', width: '60px' } diff --git a/webapp/src/components/GroupModuleGroupList.vue b/webapp/src/components/GroupModuleGroupList.vue index cda7a93..6226891 100644 --- a/webapp/src/components/GroupModuleGroupList.vue +++ b/webapp/src/components/GroupModuleGroupList.vue @@ -63,7 +63,7 @@ export default { computed: { headers () { return [ - { key: 'id', text: this.$t('id'), width: '50px' }, + { key: 'id', text: this.$t('id'), width: '50px', sortType: 'number' }, { key: 'name', text: this.$t('name'), width: '200px' }, { key: 'description', text: this.$t('description') }, { key: 'actions', width: '60px' } diff --git a/webapp/src/components/IprangeModule.vue b/webapp/src/components/IprangeModule.vue index bc137e7..d782707 100644 --- a/webapp/src/components/IprangeModule.vue +++ b/webapp/src/components/IprangeModule.vue @@ -144,9 +144,9 @@ export default { ...mapState('groups', ['groupList']), headers () { return [ - { key: 'id', text: this.$t('id'), width: '50px' }, - { key: 'startIp', text: this.$t('startIp'), width: '120px' }, - { key: 'endIp', text: this.$t('endIp'), width: '140px' }, + { key: 'id', text: this.$t('id'), width: '50px', sortType: 'number' }, + { key: 'startIp', text: this.$t('startIp'), width: '120px', sortType: 'ipv4' }, + { key: 'endIp', text: this.$t('endIp'), width: '140px', sortType: 'ipv4' }, { key: 'group', text: this.$t('group'), copyKey: 'groupName', sortKey: 'groupName' }, { key: 'actions', width: '60px' } ] -- cgit v1.2.3-55-g7522