From b9e973ab9b1c16d4e24c7ce52557259cd2f669bc Mon Sep 17 00:00:00 2001 From: davidjumani Date: Mon, 21 Feb 2022 20:58:55 +0530 Subject: [PATCH] ui: Adding option to select columns to display (#6001) --- ui/public/locales/en.json | 1 + ui/src/store/getters.js | 3 +- ui/src/store/modules/app.js | 10 ++++- ui/src/store/modules/user.js | 11 +++++- ui/src/store/mutation-types.js | 1 + ui/src/views/AutogenView.vue | 67 ++++++++++++++++++++++++++++++++-- 6 files changed, 86 insertions(+), 7 deletions(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 80487bc8ca2..9253ae3f3b3 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -598,6 +598,7 @@ "label.clustertype": "Cluster Type", "label.clvm": "CLVM", "label.code": "Code", +"label.columns": "Columns", "label.comma.separated.list.description": "Enter comma-separated list of commands", "label.comments": "Comments", "label.community": "Community", diff --git a/ui/src/store/getters.js b/ui/src/store/getters.js index f6489ee6e35..711e761e577 100644 --- a/ui/src/store/getters.js +++ b/ui/src/store/getters.js @@ -42,7 +42,8 @@ const getters = { darkMode: state => state.user.darkMode, themeSetting: state => state.user.themeSetting, defaultListViewPageSize: state => state.user.defaultListViewPageSize, - countNotify: state => state.user.countNotify + countNotify: state => state.user.countNotify, + customColumns: state => state.user.customColumns } export default getters diff --git a/ui/src/store/modules/app.js b/ui/src/store/modules/app.js index 90be53bd97a..670e2dc7810 100644 --- a/ui/src/store/modules/app.js +++ b/ui/src/store/modules/app.js @@ -28,7 +28,8 @@ import { DEFAULT_CONTENT_WIDTH_TYPE, DEFAULT_MULTI_TAB, USE_BROWSER_TIMEZONE, - SERVER_MANAGER + SERVER_MANAGER, + CUSTOM_COLUMNS } from '@/store/mutation-types' const app = { @@ -110,6 +111,10 @@ const app = { SET_SERVER: (state, server) => { Vue.ls.set(SERVER_MANAGER, server) state.server = server + }, + SET_CUSTOM_COLUMNS: (state, customColumns) => { + Vue.ls.set(CUSTOM_COLUMNS, customColumns) + state.customColumns = customColumns } }, actions: { @@ -163,6 +168,9 @@ const app = { }, SetServer ({ commit }, server) { commit('SET_SERVER', server) + }, + SetCustomColumns ({ commit }, bool) { + commit('SET_CUSTOM_COLUMNS', bool) } } } diff --git a/ui/src/store/modules/user.js b/ui/src/store/modules/user.js index 1ecf61f462f..77de4776037 100644 --- a/ui/src/store/modules/user.js +++ b/ui/src/store/modules/user.js @@ -34,7 +34,8 @@ import { HEADER_NOTICES, DOMAIN_STORE, DARK_MODE, - THEME_SETTING + THEME_SETTING, + CUSTOM_COLUMNS } from '@/store/mutation-types' const user = { @@ -125,6 +126,10 @@ const user = { }, SET_COUNT_NOTIFY (state, number) { state.countNotify = number + }, + SET_CUSTOM_COLUMNS: (state, customColumns) => { + Vue.ls.set(CUSTOM_COLUMNS, customColumns) + state.customColumns = customColumns } }, @@ -154,6 +159,8 @@ const user = { commit('SET_DARK_MODE', darkMode) const themeSetting = Vue.ls.get(THEME_SETTING, {}) commit('SET_THEME_SETTING', themeSetting) + const cachedCustomColumns = Vue.ls.get(CUSTOM_COLUMNS, {}) + commit('SET_CUSTOM_COLUMNS', cachedCustomColumns) commit('SET_APIS', {}) commit('SET_NAME', '') @@ -181,6 +188,7 @@ const user = { const cachedZones = Vue.ls.get(ZONES, []) const cachedTimezoneOffset = Vue.ls.get(TIMEZONE_OFFSET, 0.0) const cachedUseBrowserTimezone = Vue.ls.get(USE_BROWSER_TIMEZONE, false) + const cachedCustomColumns = Vue.ls.get(CUSTOM_COLUMNS, {}) const domainStore = Vue.ls.get(DOMAIN_STORE, {}) const darkMode = Vue.ls.get(DARK_MODE, false) const themeSetting = Vue.ls.get(THEME_SETTING, {}) @@ -195,6 +203,7 @@ const user = { commit('SET_APIS', cachedApis) commit('SET_TIMEZONE_OFFSET', cachedTimezoneOffset) commit('SET_USE_BROWSER_TIMEZONE', cachedUseBrowserTimezone) + commit('SET_CUSTOM_COLUMNS', cachedCustomColumns) // Ensuring we get the user info so that store.getters.user is never empty when the page is freshly loaded api('listUsers', { username: Cookies.get('username'), listall: true }).then(response => { diff --git a/ui/src/store/mutation-types.js b/ui/src/store/mutation-types.js index 8a2637a3aee..89079455417 100644 --- a/ui/src/store/mutation-types.js +++ b/ui/src/store/mutation-types.js @@ -36,6 +36,7 @@ export const SERVER_MANAGER = 'SERVER_MANAGER' export const DOMAIN_STORE = 'DOMAIN_STORE' export const DARK_MODE = 'DARK_MODE' export const THEME_SETTING = 'THEME_SETTING' +export const CUSTOM_COLUMNS = 'CUSTOM_COLUMNS' export const CONTENT_WIDTH_TYPE = { Fluid: 'Fluid', diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index 9587ed15d56..a084c78c149 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -73,6 +73,19 @@ + + + {{ $t('label.columns') }} + + + + + {{ $t('label.' + getColumnKey(column)) }} + + + @@ -441,7 +454,7 @@ @@ -499,9 +512,13 @@ export default { apiName: '', loading: false, actionLoading: false, + columnKeys: [], + allColumns: [], columns: [], + bulkColumns: [], selectedColumns: [], chosenColumns: [], + customColumnsDropdownVisible: false, showGroupActionModal: false, selectedItems: [], items: [], @@ -716,6 +733,7 @@ export default { this.actions = [] this.columns = [] this.columnKeys = [] + this.selectedColumns = [] const refreshed = ('irefresh' in params) params.listall = true @@ -825,7 +843,20 @@ export default { scopedSlots: { customRender: key }, sorter: function (a, b) { return genericCompare(a[this.dataIndex] || '', b[this.dataIndex] || '') } }) + this.selectedColumns.push(key) } + this.allColumns = this.columns + + if (!store.getters.metrics) { + if (!this.$store.getters.customColumns[this.$store.getters.userInfo.id]) { + this.$store.getters.customColumns[this.$store.getters.userInfo.id] = {} + this.$store.getters.customColumns[this.$store.getters.userInfo.id][this.$route.path] = this.selectedColumns + } else { + this.selectedColumns = this.$store.getters.customColumns[this.$store.getters.userInfo.id][this.$route.path] || this.selectedColumns + this.updateSelectedColumns() + } + } + this.chosenColumns = this.columns.filter(column => { return ![this.$t('label.state'), this.$t('label.hostname'), this.$t('label.hostid'), this.$t('label.zonename'), this.$t('label.zone'), this.$t('label.zoneid'), this.$t('label.ip'), this.$t('label.ipaddress'), this.$t('label.privateip'), @@ -1218,7 +1249,7 @@ export default { eventBus.$emit('update-bulk-job-status', this.selectedItems, false) this.showGroupActionModal = false this.selectedItems = [] - this.selectedColumns = [] + this.bulkColumns = [] this.selectedRowKeys = [] this.message = {} }, @@ -1227,9 +1258,9 @@ export default { this.promises = [] if (!this.dataView && this.currentAction.groupAction && this.selectedRowKeys.length > 0) { if (this.selectedRowKeys.length > 0) { - this.selectedColumns = this.chosenColumns + this.bulkColumns = this.chosenColumns this.selectedItems = this.selectedItems.map(v => ({ ...v, status: 'InProgress' })) - this.selectedColumns.splice(0, 0, { + this.bulkColumns.splice(0, 0, { dataIndex: 'status', title: this.$t('label.operation.status'), scopedSlots: { customRender: 'status' }, @@ -1441,6 +1472,30 @@ export default { shouldNavigateBack (action) { return ((action.icon === 'delete' || ['archiveEvents', 'archiveAlerts', 'unmanageVirtualMachine'].includes(action.api)) && this.dataView) }, + getColumnKey (name) { + if (typeof name === 'object') { + name = Object.keys(name)[0] + } + return name + }, + updateSelectedColumns (name) { + if (name) { + name = this.getColumnKey(name) + if (this.selectedColumns.includes(name)) { + this.selectedColumns = this.selectedColumns.filter(x => x !== name) + } else { + this.selectedColumns.push(name) + } + } + + this.columns = this.allColumns.filter(x => this.selectedColumns.includes(x.dataIndex)) + + if (!this.$store.getters.customColumns[this.$store.getters.userInfo.id]) { + this.$store.getters.customColumns[this.$store.getters.userInfo.id] = {} + } + this.$store.getters.customColumns[this.$store.getters.userInfo.id][this.$route.path] = this.selectedColumns + this.$store.dispatch('SetCustomColumns', this.$store.getters.customColumns) + }, changeFilter (filter) { const query = Object.assign({}, this.$route.query) delete query.templatefilter @@ -1609,4 +1664,8 @@ export default { display: flex; align-items: center; } + +.hide { + display: none !important; +}