diff --git a/package-lock.json b/package-lock.json index 3b3a49c6b7d..ca83e79cce4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19473,6 +19473,11 @@ } } }, + "sortablejs": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz", + "integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A==" + }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -21011,6 +21016,14 @@ "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "dev": true }, + "vuedraggable": { + "version": "2.24.3", + "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz", + "integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==", + "requires": { + "sortablejs": "1.10.2" + } + }, "vuetify": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.4.3.tgz", diff --git a/package.json b/package.json index ffac305eb98..d5a4cbf44b5 100644 --- a/package.json +++ b/package.json @@ -128,6 +128,7 @@ "vue": "^2.6.12", "vue-prism-editor": "^1.2.2", "vue-router": "^3.5.1", + "vuedraggable": "^2.24.3", "vuetify": "^2.4.3", "vuex": "^3.6.2", "winston": "^3.3.3", diff --git a/src/components/nodes-table/index.vue b/src/components/nodes-table/index.vue index 890f036c44d..f3e947e2aff 100644 --- a/src/components/nodes-table/index.vue +++ b/src/components/nodes-table/index.vue @@ -24,7 +24,11 @@ - + - + + + + + Reset + diff --git a/src/components/nodes-table/nodes-table.js b/src/components/nodes-table/nodes-table.js index 06f1b103ee8..4bbed6d082b 100644 --- a/src/components/nodes-table/nodes-table.js +++ b/src/components/nodes-table/nodes-table.js @@ -1,3 +1,4 @@ +import draggable from 'vuedraggable' import { ManagedItems } from '@/modules/ManagedItems' import { Settings } from '@/modules/Settings' import ColumnFilter from '@/components/nodes-table/ColumnFilter.vue' @@ -10,6 +11,7 @@ export default { socket: Object }, components: { + draggable, ColumnFilter, ExpandedNode }, diff --git a/src/modules/ManagedItems.js b/src/modules/ManagedItems.js index 225741ee5e9..43d29a354a3 100644 --- a/src/modules/ManagedItems.js +++ b/src/modules/ManagedItems.js @@ -30,9 +30,9 @@ export class ManagedItems { ? this.loadSetting('tableOptions', this.initialTableOptions) : this.tableOptions this._columns = - this.columns === undefined - ? this.loadSetting('columns', this.initialColumns) - : this.columns + this.tableColumns === undefined + ? this.loadSetting('tableColumns', this.initialTableColumns) + : this.tableColumns this._filters = this.filters === undefined ? this.loadSetting('filters', this.initialFilters) @@ -45,7 +45,7 @@ export class ManagedItems { */ reset () { this.tableOptions = this.initialTableOptions - this.columns = this.initialColumns + this.tableColumns = this.initialTableColumns this.filters = this.initialFilters this.selected = this.initialSelected } @@ -129,51 +129,68 @@ export class ManagedItems { // Table columns handling + /** + * Internal function to get a table header definition for a specific column name + */ + _getTableHeaderForColumn (colName) { + const propDef = this.propDefs[colName] + return { + value: colName, + text: propDef.label === undefined ? colName : propDef.label, + type: propDef.type === undefined ? 'string' : propDef.type, + groupable: propDef.groupable === undefined ? true : !!propDef.groupable + } + } + /** * Get all table column headers */ get allTableHeaders () { - const headers = [] - Object.keys(this.propDefs).forEach(key => { - const propDef = this.propDefs[key] - headers.push({ - value: key, - text: propDef.label === undefined ? key : propDef.label, - type: propDef.type === undefined ? 'string' : propDef.type, - groupable: propDef.groupable === undefined ? true : !!propDef.groupable - }) - }) - return headers + return Object.keys(this.propDefs).reduce((headers, colName) => { + headers.push(this._getTableHeaderForColumn(colName)) + return headers + }, []) } /** * Get visible table column headers */ get tableHeaders () { - return this.allTableHeaders.filter(col => this.columns.includes(col.value)) + return this.tableColumns.reduce((tableHeaders, column) => { + if (column.visible) { + tableHeaders.push(this._getTableHeaderForColumn(column.name)) + } + return tableHeaders + }, []) } /** * Get initial table column list */ - get initialColumns () { - return Object.keys(this.propDefs) + get initialTableColumns () { + return Object.keys(this.propDefs).reduce((tableColumns, propName) => { + tableColumns.push({ + name: propName, + visible: true + }) + return tableColumns + }, []) } /** * Get the active table colum list */ - get columns () { + get tableColumns () { return this._columns } /** - * Set the list of active table columns - * @param {Array} columns List of columns to be set + * Set the list of table columns with visibility status + * @param {Array} tableColumns List of table columns to be set */ - set columns (columns) { - this._columns = columns - this.storeSetting('columns', columns) + set tableColumns (tableColumns) { + this._columns = tableColumns + this.storeSetting('tableColumns', tableColumns) } // Filters handling diff --git a/src/modules/ManagedItems.test.js b/src/modules/ManagedItems.test.js index eacb6e9069e..ed6429d0ee7 100644 --- a/src/modules/ManagedItems.test.js +++ b/src/modules/ManagedItems.test.js @@ -71,7 +71,7 @@ describe('ManagedItems', () => { }) it('resets the table columns', () => { const managedItems = getNewManagedTestItems() - managedItems.columns = ['id', 'value'] + managedItems.tableColumns = ['id', 'value'] managedItems.reset() chai.expect(managedItems.tableHeaders).to.eql(testItemHeaders) }) @@ -169,7 +169,11 @@ describe('ManagedItems', () => { describe('#tableHeaders', () => { it('returns the active table headers', () => { const managedItems = getNewManagedTestItems() - managedItems.columns = ['id', 'value'] + managedItems.tableColumns = [ + { name: 'id', visible: true }, + { name: 'value', visible: true }, + { name: 'info', visible: false } + ] chai.expect(managedItems.tableHeaders).to.eql([ { value: 'id', text: 'ID', type: 'number', groupable: false }, { value: 'value', text: 'Value', type: 'string', groupable: true }