feat(hide-columns): support colspan & don't persist autohide

This commit is contained in:
Gregor Kleen 2019-12-06 15:58:09 +01:00
parent 615555eb59
commit 0798d6870e
2 changed files with 93 additions and 16 deletions

View File

@ -50,6 +50,26 @@ export class StorageManager {
} }
} }
remove(key, options) {
if (options && options.lifetime !== undefined && !Object.values(LIFETIME).includes(options.lifetime)) {
throw new Error('StorageManager.load called with unsupported lifetime option');
}
const lifetime = options && options.lifetime !== undefined ? options.lifetime : LIFETIME.INFINITE;
switch (lifetime) {
case LIFETIME.INFINITE: {
var val = this.getFromLocalStorage();
delete val[key];
return this.saveToLocalStorage(val);
}
default:
console.error('StorageManager.load cannot load item with unsupported lifetime');
}
}
getFromLocalStorage() { getFromLocalStorage() {
const state = JSON.parse(window.localStorage.getItem(this.namespace)); const state = JSON.parse(window.localStorage.getItem(this.namespace));
if (state === null) { if (state === null) {
@ -67,5 +87,4 @@ export class StorageManager {
clearLocalStorage() { clearLocalStorage() {
window.localStorage.removeItem(this.namespace); window.localStorage.removeItem(this.namespace);
} }
} }

View File

@ -15,6 +15,7 @@ const TABLE_HIDER_VISIBLE_CLASS = 'table-hider--visible';
const TABLE_PILL_CLASS = 'table-pill'; const TABLE_PILL_CLASS = 'table-pill';
const CELL_HIDDEN_CLASS = 'hide-columns--hidden-cell'; const CELL_HIDDEN_CLASS = 'hide-columns--hidden-cell';
const CELL_ORIGINAL_COLSPAN = 'uw-hide-column-original-colspan';
@Utility({ @Utility({
selector: `[${HIDE_COLUMNS_CONTAINER_IDENT}] table`, selector: `[${HIDE_COLUMNS_CONTAINER_IDENT}] table`,
@ -121,7 +122,7 @@ export class HideColumns {
// reposition hider on each window resize event // reposition hider on each window resize event
window.addEventListener('resize', () => this.repositionHider(hider)); window.addEventListener('resize', () => this.repositionHider(hider));
this.updateColumnDisplay(th.cellIndex, preHidden); this.updateColumnDisplay(this.colIndex(th), preHidden);
this.updateHider(hider, preHidden); this.updateHider(hider, preHidden);
if (preHidden) { if (preHidden) {
@ -135,22 +136,46 @@ export class HideColumns {
switchColumnDisplay(th, hider) { switchColumnDisplay(th, hider) {
const hidden = !this.isHiddenColumn(th); const hidden = !this.isHiddenColumn(th);
const originalColspan = Math.max(1, th.getAttribute(CELL_ORIGINAL_COLSPAN)) || 1;
const colspan = Math.max(1, th.colSpan) || 1;
const columnIndex = this.colIndex(th);
this.updateColumnDisplay(th.cellIndex, hidden); for (var i = 0; i < Math.max(colspan, originalColspan); i++) {
this.updateColumnDisplay(columnIndex + i, hidden);
}
this.updateHider(hider, hidden); this.updateHider(hider, hidden);
// persist new hidden setting for column // persist new hidden setting for column
this._storageManager.save(this.getStorageKey(th), hidden); if (hidden && this.isEmptyColumn(columnIndex)) {
this._storageManager.remove(this.getStorageKey(th));
} else {
this._storageManager.save(this.getStorageKey(th), hidden);
}
} }
updateColumnDisplay(columnIndex, hidden) { updateColumnDisplay(columnIndex, hidden) {
this._element.getElementsByTagName('tr').forEach(row => { this._element.getElementsByTagName('tr').forEach(row => {
const cell = row.cells[columnIndex]; const cell = this.getCol(row, columnIndex);
if (cell) { if (cell) {
const originalColspan = cell.getAttribute(CELL_ORIGINAL_COLSPAN);
const colspan = Math.max(1, cell.colSpan) || 1;
if (hidden) { if (hidden) {
cell.classList.add(CELL_HIDDEN_CLASS); if (colspan > 1) {
if (!originalColspan) {
cell.setAttribute(CELL_ORIGINAL_COLSPAN, colspan);
}
cell.colSpan--;
} else {
cell.classList.add(CELL_HIDDEN_CLASS);
}
} else { } else {
cell.classList.remove(CELL_HIDDEN_CLASS); if (cell.classList.contains(CELL_HIDDEN_CLASS)) {
cell.classList.remove(CELL_HIDDEN_CLASS);
} else if (originalColspan && colspan < originalColspan) {
cell.colSpan++;
}
} }
} }
}); });
@ -215,20 +240,16 @@ export class HideColumns {
// check for unique table header ident from backend (if not present, use cell index as fallback) // check for unique table header ident from backend (if not present, use cell index as fallback)
let thIdent = th.getAttribute(TABLE_HEADER_IDENT); let thIdent = th.getAttribute(TABLE_HEADER_IDENT);
if (!thIdent) { if (!thIdent) {
thIdent = th.cellIndex; thIdent = this.colIndex(th);
} }
return `${handlerIdent}__${tIdent}__${thIdent}`; return `${handlerIdent}__${tIdent}__${thIdent}`;
} }
isEmptyColumn(columnIndex) { isEmptyColumn(columnIndex) {
for (let row of this._element.getElementsByTagName('TR')) { for (let row of this._element.getElementsByTagName('tr')) {
if (row.children.length <= columnIndex) { const cell = this.getCol(row, columnIndex);
return; if (cell.matches('th'))
}
const cell = row.children[columnIndex];
if (cell.tagName === 'TH')
continue; continue;
if (cell.querySelector('.table__td-content')) { if (cell.querySelector('.table__td-content')) {
for (let child of cell.children) { for (let child of cell.children) {
@ -244,10 +265,47 @@ export class HideColumns {
isHiddenColumn(th) { isHiddenColumn(th) {
const hidden = this._storageManager.load(this.getStorageKey(th)), const hidden = this._storageManager.load(this.getStorageKey(th)),
emptyColumn = this.isEmptyColumn(th.cellIndex); emptyColumn = this.isEmptyColumn(this.colIndex(th));
return hidden === true || hidden === undefined && emptyColumn; return hidden === true || hidden === undefined && emptyColumn;
} }
colSpan(cell) {
if (!cell)
return 1;
const originalColspan = cell.getAttribute(CELL_ORIGINAL_COLSPAN);
const colspan = Math.max(1, cell.colSpan) || 1;
return originalColspan ? Math.max(colspan, originalColspan) : colspan;
}
colIndex(cell) {
if (!cell)
return 0;
const rowParent = cell.closest('tr');
if (!rowParent)
return 0;
var i = 0;
for (const sibling of Array.from(rowParent.cells).slice(0, cell.cellIndex)) {
i += this.colSpan(sibling);
}
return i;
}
getCol(row, columnIndex) {
var c = 0;
for (const cell of row.cells) {
c += cell ? this.colSpan(cell) : 1;
if (columnIndex < c)
return cell;
}
}
} }
function isEmptyElement(element) { function isEmptyElement(element) {