Store filter/column settings in localStorage

The filter and column settings in tables are stored per project and
context in the browsers localStorage. This makes the table keep the
settings even if the browser is refreshed or restarted.

The table emits a "componentStateChanged" event containing the tables
current state (filter/column settings) which then is saved by the top
level component.
This commit is contained in:
2019-03-28 10:29:13 +01:00
parent f6056f4f7e
commit 465f1eb87e
13 changed files with 562 additions and 152 deletions

View File

@@ -4,13 +4,12 @@ import { CellDefault } from '../cells/renderer/CellDefault'
* Column logic
*/
let nextColumnId = 0;
export class ColumnBase {
constructor(displayName, columnType) {
this._id = nextColumnId++;
this.displayName = displayName;
this.columnType = columnType;
this.isMandatory = false;
this.includedByDefault = true;
this.isSortable = true;
this.isHighLighted = 0;
}

View File

@@ -0,0 +1,130 @@
import '../../../menu/DropDown'
const TEMPLATE =`
<div class="pillar-table-column-filter">
<pillar-dropdown>
<i class="pi-cog"
slot="button"
title="Table Settings"/>
<ul class="settings-menu"
slot="menu"
>
Columns:
<li class="attract-column-select action"
v-for="c in columnStates"
:key="c.displayName"
@click="toggleColumn(c)"
>
<input type="checkbox"
v-model="c.isVisible"
/>
{{ c.displayName }}
</li>
</ul>
</pillar-dropdown>
</div>
`;
class ColumnState{
constructor() {
this.displayName;
this.isVisible;
this.isMandatory;
}
static createDefault(column) {
let state = new ColumnState;
state.displayName = column.displayName;
state.isVisible = !!column.includedByDefault;
state.isMandatory = !!column.isMandatory;
return state;
}
}
class ComponentState {
/**
* Serializable state of this component.
*
* @param {Array} selected The columns that should be visible
*/
constructor(selected) {
this.selected = selected;
}
}
/**
* Component to select what columns to render in the table.
*
* @emits visibleColumnsChanged(columns) When visible columns has changed
* @emits componentStateChanged(newState) When column filter state changed.
*/
let Filter = Vue.component('pillar-table-column-filter', {
template: TEMPLATE,
props: {
columns: Array, // Instances of ColumnBase
componentState: Object, // Instance of ComponentState
},
data() {
return {
columnStates: this.createInitialColumnStates(), // Instances of ColumnState
}
},
computed: {
visibleColumns() {
return this.columns.filter((candidate) => {
return candidate.isMandatory || this.isColumnStateVisible(candidate);
});
},
columnFilterState() {
return new ComponentState(this.visibleColumns.map(it => it.displayName));
}
},
watch: {
columns() {
this.columnStates = this.createInitialColumnStates();
},
visibleColumns(visibleColumns) {
this.$emit('visibleColumnsChanged', visibleColumns);
},
columnFilterState(newValue) {
this.$emit('componentStateChanged', newValue);
}
},
created() {
this.$emit('visibleColumnsChanged', this.visibleColumns);
},
methods: {
createInitialColumnStates() {
let columnStateCB = ColumnState.createDefault;
if (this.componentState && this.componentState.selected) {
let selected = this.componentState.selected;
columnStateCB = (column) => {
let state = ColumnState.createDefault(column);
state.isVisible = selected.includes(column.displayName);
return state;
}
}
return this.columns.reduce((states, c) => {
if(!c.isMandatory) {
states.push(columnStateCB(c));
}
return states;
}, []);
},
isColumnStateVisible(column) {
for (let state of this.columnStates) {
if (state.displayName === column.displayName) {
return state.isVisible;
}
}
return false;
},
toggleColumn(column) {
column.isVisible = !column.isVisible;
}
},
});
export { Filter }